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

9 投票
2 回答
26468 浏览
提问于 2025-04-16 00:26

最近我在玩转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 个回答

2

我不太确定关于twisted的事情,但我想提醒你,如果你要做一个HTTPS代理,网页浏览器会期待服务器的SSL证书和网址中的域名是匹配的(也就是地址栏里的内容)。如果不匹配,浏览器就会发出安全警告。

当然,有一些方法可以解决这个问题,比如动态生成证书,但你需要在浏览器上让根证书被信任。

15

如果你想通过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'状态行,对客户端来说,就好像它直接与目标服务器建立了连接一样。

撰写回答