扭曲地将代理请求转发到另一个代理(代理链)

2024-06-16 11:27:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用python设置一个HTTP代理来过滤web内容。我在StackOverflow上找到了一个good example,它使用Twisted实现了这一点。但是,我需要另一个代理来访问网络。因此,代理需要将请求转发给另一个代理。使用twisted.web.proxy进行此操作的最佳方法是什么?在

我找到了a related question,它需要类似的东西,但是来自一个反向代理。在

我的最佳猜测是,应该可以通过修改或子类化twisted.web.proxy.ProxyClient来连接到下一个代理,而不是直接连接到web来构建链接代理。不幸的是,我没有在文档中找到任何关于如何做到这一点的线索。在

到目前为止我得到的代码(cite):

from twisted.python import log
from twisted.web import http, proxy

class ProxyClient(proxy.ProxyClient):
    def handleResponsePart(self, buffer):
        proxy.ProxyClient.handleResponsePart(self, buffer)

class ProxyClientFactory(proxy.ProxyClientFactory):
    protocol = ProxyClient

class ProxyRequest(proxy.ProxyRequest):
    protocols = dict(http=ProxyClientFactory)

class Proxy(proxy.Proxy):
    requestFactory = ProxyRequest

class ProxyFactory(http.HTTPFactory):
    protocol = Proxy

portstr = "tcp:8080:interface=localhost"  # serve on localhost:8080

if __name__ == '__main__':
    import sys
    from twisted.internet import endpoints, reactor

    log.startLogging(sys.stdout)
    endpoint = endpoints.serverFromString(reactor, portstr)
    d = endpoint.listen(ProxyFactory())
    reactor.run()

Tags: fromimportlogwebhttp代理twistedclass
1条回答
网友
1楼 · 发布于 2024-06-16 11:27:52

使用Twisted实际上并不难实现。我给你举个简单的例子。在

假设第一个代理是proxy1.py,就像粘贴在问题中的代码; 第二个代理是proxy2.py。在

对于proxy1.py,您只需要重写类ProxyRequestprocess函数。像这样:

class ProxyRequest(proxy.ProxyRequest):
    def process(self):
        parsed = urllib_parse.urlparse(self.uri)
        protocol = parsed[0]
        host = parsed[1].decode('ascii')
        port = self.ports[protocol]
        if ':' in host:
            host, port = host.split(':')
            port = int(port)
        rest = urllib_parse.urlunparse((b'', b'') + parsed[2:])
        if not rest:
            rest = rest + b'/'
        class_ = self.protocols[protocol]
        headers = self.getAllHeaders().copy()
        if b'host' not in headers:
            headers[b'host'] = host.encode('ascii')
        self.content.seek(0, 0)
        s = self.content.read()
        clientFactory = class_(self.method, rest, self.clientproto, headers, s, self)
        if (NeedGoToSecondProxy):
            self.reactor.connectTCP(your_second_proxy_server_ip, your_second_proxy_port, clientFactory)
        else:
            self.reactor.connectTCP(host, port, clientFactory)

对于proxy2.py,只需设置另一个简单的代理即可。但是需要注意的一个问题是,您可能需要再次重写proxy2.py中的process函数,因为在代理转发(链)之后,self.uri可能无效。在

例如,原始的self.uri应该是http://www.google.com/something?para1=xxx,并且在第二个代理中,您可能只发现它是/something?para1=xxx。因此,您需要从self.headers中提取主机信息,并补充self.uri以便您的第二个代理可以正常地将其传递到正确的目的地。在

相关问题 更多 >