簡體   English   中英

扭曲 - 將代理請求轉發到另一個代理(代理鏈)

[英]Twisted - forwarding proxy requests to another proxy (proxy chain)

我在python中設置HTTP代理來過濾Web內容。 我在StackOverflow上找到了一個很好的例子 ,它使用Twisted來完成這個。 但是,我需要另一個代理來訪問網絡。 因此,代理需要將請求轉發給另一個代理。 使用twisted.web.proxy執行此操作的最佳方法是什么?

我發現了一個相關的問題需要類似的東西,但是來自反向代理

我最好的猜測是,應該可以通過修改或子類化twisted.web.proxy.ProxyClient來連接到下一個代理而不是直接連接到Web來構建鏈式代理。 不幸的是,我沒有在文檔中找到有關如何執行此操作的任何線索。

我到目前為止的代碼( 引用 ):

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

使用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以便您的第二個代理可以正常地將其傳遞到正確的目的地。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM