2016-07-27 84 views
1

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

回答

0

這其實並不難扭使用來實現。讓我給你一個簡單的例子。

假設第一個代理是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,以便您的第二個代理通常可以將其發送到正確的目的地。