我试图在python中创建一个http代理。到目前为止,除了https工作之外,我已经完成了所有工作,因此下一步是实现CONNECT方法。
我对进行https隧道传输时需要发生的事件链略微混淆。 根据我的理解,当连接到谷歌时我应该有这个:
Broswer - >代理
CONNECT www.google.co.uk:443 HTTP/1.1\r\n\r\n
然后代理应建立与google.co.uk的安全连接,并通过发送确认:
代理 - >浏览器
HTTP/1.1 200 Connection established\r\n\r\n
此时我希望浏览器现在可以继续执行它最初要做的任何事情,但是,我要么什么也得不到,或者得到一串字节我无法做到解码()。我一直在阅读任何与ssl隧道有关的事情,我想我应该将所有字节从浏览器转发到服务器,以及相反的方式。但是,在这样做的时候,我得到了一个:
HTTP/1.0 400 Bad Request\r\n...\r\n
一旦我发送了200个代码,接下来我该做什么?
我的连接方法的代码段:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if headers["Method"] == "CONNECT":
client = ssl.wrap_socket(client)
try:
client.connect(( headers["Host"], headers["Port"] ))
reply = "HTTP/1.0 200 Connection established\r\n"
reply += "Proxy-agent: Pyx\r\n"
reply += "\r\n"
browser.sendall( reply.encode() )
except socket.error as err:
print(err)
break
while True:
now not sure
非常感谢帮助!
答案 0 :(得分:3)
找到相关问题的答案后:HTTPS Proxy Implementation (SSLStream)
我意识到目标服务器端口443上的初始连接(在本例中为google.co.uk)不应加密。因此我删除了
client = ssl.wrap_socket(client)
继续使用纯文本隧道而不是ssl。一旦
HTTP/1.1 200 Connection established\r\n\r\n
发送消息后,浏览器和终端服务器将通过代理形成自己的ssl连接,因此代理不需要执行与实际https连接相关的任何操作。
修改后的代码(包括字节转发):
# If we receive a CONNECT request
if headers["Method"] == "CONNECT":
# Connect to port 443
try:
# If successful, send 200 code response
client.connect(( headers["Host"], headers["Port"] ))
reply = "HTTP/1.0 200 Connection established\r\n"
reply += "Proxy-agent: Pyx\r\n"
reply += "\r\n"
browser.sendall( reply.encode() )
except socket.error as err:
# If the connection could not be established, exit
# Should properly handle the exit with http error code here
print(err)
break
# Indiscriminately forward bytes
browser.setblocking(0)
client.setblocking(0)
while True:
try:
request = browser.recv(1024)
client.sendall( request )
except socket.error as err:
pass
try:
reply = client.recv(1024)
browser.sendall( reply )
except socket.error as err:
pass
参考文献:
HTTPS Proxy Implementation (SSLStream)