我正在尝试构建一个可以同时处理HTTP和HTTPS请求的代理,并且对于GET和POST等HTTP请求都可以正常工作,但是对于CONNECT请求,我没有从网络服务器获得任何响应。
这是我的代理的一个简单版本,可以说明问题。
import socket
IP = "0.0.0.0"
PORT = 1234
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
server_socket.bind((IP, PORT))
server_socket.listen()
while True:
conn, _ = server_socket.accept()
header_bytes, _ = conn.recv(1024).split(b"\r\n\r\n")
header_bytes += b"\r\n\r\n"
print("header: ", header_bytes)
for header in header_bytes.split(b"\r\n"):
key, value = header.split(b":", 1)
if key == b"Host":
if b":" not in value:
value += b":80"
break
addr, port = value.split(b":")
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((addr.decode("utf-8").replace(" ", ""), int(port.decode("utf-8"))))
client_socket.send(header_bytes)
response = client_socket.recv(1024)
print("response: ", response)
conn.send(response)
conn.close()
我出去的是
header: b'CONNECT www.google.com:443 HTTP/1.1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0\r\n
Proxy-Connection: keep-alive\r\n
Connection: keep-alive\r\n
Host: www.google.com:443\r\n\r\n'
response: b''
在阅读了更多有关CONNECT请求的信息之后,我认为我可能误解了它应该如何工作,但是我仍然不明白如何实现它。它说我必须建立到Web服务器的隧道,但是如果我的CONNECT请求没有响应,该怎么办。我只是发送200 OK响应并假装我有隧道吗?
答案 0 :(得分:1)
一个简单的HTTP请求(GET,POST等)被代理转发到服务器(通常在将路径重写为不再是完整的URL之后),并且服务器的响应被发送回客户端。但是,使用CONNECT则有所不同。
仅将CONNECT请求从客户端发送到代理。它不转发到服务器。相反,代理将建立与服务器的TCP连接,并在成功建立连接后向客户端返回成功的响应,即HTTP/1.0 200 ...
。换句话说:CONNECT请求/响应仅在客户端和代理之间,而服务器则看不到它。
建立与服务器的TCP连接并将HTTP响应发送到客户端后,应将来自客户端的所有数据转发到服务器,并将来自服务器的所有数据转发到客户端。