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

时间:2016-07-27 12:49:33

标签: python twisted http-proxy

我在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()

1 个答案:

答案 0 :(得分:0)

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

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

对于proxy1.py,您只需要覆盖类process的{​​{1}}函数。像这样:

ProxyRequest

对于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中的process函数,因为proxy2.py在代理转发(链)之后可能无效。

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