在Twisted中将HTTP代理转换为HTTPS代理

时间:2010-06-25 14:01:27

标签: python http proxy https twisted

最近我一直在使用扭曲的HTTP代理。经过多次反复试验后,我想我终于有了一些工作。我想知道的是,如果有可能,我是否可以扩展此代理以便能够处理HTTPS页面?这是我到目前为止所得到的:

from twisted.internet import reactor
from twisted.web import http
from twisted.web.proxy import Proxy, ProxyRequest, ProxyClientFactory, ProxyClient



class HTTPProxyClient(ProxyClient):
    def handleHeader(self, key, value):
        print "%s : %s" % (key, value)
        ProxyClient.handleHeader(self, key, value)

    def handleResponsePart(self, buffer):
        print buffer
        ProxyClient.handleResponsePart(self, buffer)

class HTTPProxyFactory(ProxyClientFactory):
    protocol = HTTPProxyClient

class HTTPProxyRequest(ProxyRequest):
    protocols = {'http' : HTTPProxyFactory}

    def process(self):
        print self.method
        for k,v in self.requestHeaders.getAllRawHeaders():
            print "%s : %s" % (k,v)
        print "\n \n"

        ProxyRequest.process(self)

class HTTPProxy(Proxy):

    requestFactory = HTTPProxyRequest


factory = http.HTTPFactory()
factory.protocol = HTTPProxy

reactor.listenSSL(8001, factory)
reactor.run()

正如此代码所示,为了现在的例子,我只是打印出通过连接的任何内容。是否可以使用相同的类处理HTTPS?如果没有,我该如何实施这样的事情?

2 个答案:

答案 0 :(得分:13)

如果要通过HTTP代理连接到HTTPS网站,则需要使用CONNECT HTTP谓词(因为这是代理对HTTPS的工作方式)。在这种情况下,代理服务器只是连接到目标服务器,并将服务器发送的任何内容中继回客户端的套接字(反之亦然)。在这种情况下不涉及缓存(但您可能能够记录您要连接的主机)。

交易所看起来像这样(客户代理):

C->P: CONNECT target.host:443 HTTP/1.0
C->P:

P->C: 200 OK
P->C: 

此后,代理只是打开一个到目标服务器的普通套接字(还没有HTTP或SSL / TLS),并在初始客户端和目标服务器之间中继所有内容(包括客户端启动的TLS握手)。客户端将其拥有的现有套接字升级到代理以使用TLS / SSL(通过启动SSL / TLS握手)。一旦客户端读取了'200'状态行,就客户端而言,就好像它已直接连接到目标服务器。

答案 1 :(得分:1)

我不确定是否会扭曲,但我想提醒您,如果您实施HTTPS代理,则Web浏览器会希望服务器的SSL证书与URL(地址栏)中的域名相匹配。否则,Web浏览器将发出安全警告。

有很多方法可以解决此问题,例如动态生成证书,但您需要在浏览器上信任根证书。