我如何回应" CONNECT"在python中使用套接字的代理服务器中的方法请求?

时间:2015-02-13 09:07:57

标签: python sockets proxy httplib

我目前正在使用httplib编写代理服务器, 当我尝试连接到HTTPS网站(例如facebook和google)时,我的客户端向我发送了“CONNECT”请求,如下所示:

CONNECT www.google.co.il:443 HTTP/1.1\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0\r\n
Proxy-Connection: keep-alive\r\n
Connection: keep-alive\r\n
Host: www.google.co.il:443\r\n
\r\n

我从网上拿了一个工作代理并把它打开,然后在wireshark上嗅探网络,对这个请求的响应应该是这样的:

HTTP/1.1 200 Connection established\n
Proxy-agent: Python Proxy/0.1.0 Draft 1\n
\n

我注意到客户端将请求发送给代理本身,所以我决定使用socket,并以这种方式将响应发送给客户端:

if getmethod(clientreq) is "CONNECT":
    text="HTTP/1.1 200 Connection established\nProxy-Agent: THE BB Proxy\n\n"
    client.send(text)

我真的希望处理这些“CONNECT”请求是解决方案,我的服务器最终将处理HTTPS请求,但它没有,我发送给客户端的响应数据包甚至没有显示在Wireshark的。

所以我的问题是: 1.“CONNECT”方法到底有什么作用? 2.除了处理“CONNECT”方法请求以便与HTTPS服务器通信外,我还需要什么?

2 个答案:

答案 0 :(得分:3)

我很久以后就回复了,因为我最近使用过这个概念。它可以帮助别人。

要使用CONNECT http方法,需要使用服务器的https端口创建套接字连接(例如443)。建立连接后,您可以发送“HTTP / 1.1 200建立连接”作为响应。

此客户端和服务器之后通过代理进行相互通信。代理必须只将数据从客户端套接字传输到服务器套接字,反之亦然。客户端和服务器将交换证书信息以进行握手,一旦完成握手,它们将开始以加密格式共享数据,因此代理将无法理解任何内容。

以下代码可以帮助您。

def _read_write(self):
    socs = [self.client, self.target]
    count = 0
    while 1:
        count += 1
        (recv, _, error) = select.select(socs, [], socs, 3)
        if error:
            break
        if recv:
            for in_ in recv:
                data = in_.recv(BUFLEN)
                if in_ is self.client:
                    out = self.target
                else:
                    out = self.client
                if data:
                    out.send(data)
                    print(data)
                    count = 0
        if count == time_out_max:
            break

希望这个答案可以帮助任何有需要的人。 因为我必须经历很多事情才能找到答案。

答案 1 :(得分:0)

我遇到了基本上相同的问题,最终解决此问题的方法是在GitHub上查找示例代码。事实证明proxy2项目是很有帮助的。一些relevant code与rushikesh的答案非常相似:

    def connect_relay(self):
        address = self.path.split(':', 1)
        address[1] = int(address[1]) or 443
        try:
            s = socket.create_connection(address, timeout=self.timeout)
        except Exception as e:
            self.send_error(502)
            return
        self.send_response(200, 'Connection Established')
        self.end_headers()

        conns = [self.connection, s]
        self.close_connection = 0
        while not self.close_connection:
            rlist, wlist, xlist = select.select(conns, [], conns, self.timeout)
            if xlist or not rlist:
                break
            for r in rlist:
                other = conns[1] if r is conns[0] else conns[0]
                data = r.recv(8192)
                if not data:
                    self.close_connection = 1
                    break
                other.sendall(data)

您可以在存储库中找到更多信息。