【问题标题】:Twisted - forwarding proxy requests to another proxy (proxy chain)Twisted - 将代理请求转发到另一个代理(代理链)
【发布时间】:2016-07-27 12:49:32
【问题描述】:

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

我发现 a related question 需要类似的东西,但来自 反向代理

我最好的猜测是应该可以通过修改或子类化twisted.web.proxy.ProxyClient 来连接下一个代理而不是直接连接到网络来构建链式代理。不幸的是,我在文档中没有找到有关如何执行此操作的任何线索。

我目前拥有的代码 (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()

【问题讨论】:

    标签: python twisted http-proxy


    【解决方案1】:

    这实际上使用 Twisted 并不难实现。让我举个简单的例子。

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

    对于proxy1.py,只需要重写ProxyRequest类的process函数即可。像这样:

    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,以便您的第二个代理可以正常将其传送到正确的目的地。

    【讨论】:

      猜你喜欢
      • 2017-05-20
      • 1970-01-01
      • 2018-11-16
      • 1970-01-01
      • 2019-08-17
      • 1970-01-01
      • 2011-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多