Python - 扭曲,代理和修改内容

时间:2012-02-27 12:45:05

标签: python proxy twisted

所以我看了一些涉及使用python和Twisted框架编写HTTP代理的事情。

基本上,像其他一些问题一样,我希望能够修改将发送回浏览器的数据。也就是说,浏览器请求资源,代理将获取它。在资源返回浏览器之前,我希望能够修改任何(HTTP标头和内容)内容。

这(Need help writing a twisted proxy)是我最初找到的。我试了一下,但它对我不起作用。我也发现了这个(Python Twisted proxy - how to intercept packets),我认为它可以工作,但是我只能看到来自浏览器的HTTP请求。

我正在寻找任何建议。我有一些想法是使用ProxyClient和ProxyRequest类并覆盖函数,但我读到Proxy类本身是两者的组合。

对于那些可能要求查看某些代码的人,应该注意到我只使用了上述两个示例。任何帮助都很棒。

感谢。

2 个答案:

答案 0 :(得分:17)

要创建可以修改服务器响应标头的ProxyFactory,您可以覆盖的内容ProxyClient.handle*() methods

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

class ProxyClient(proxy.ProxyClient):
    """Mangle returned header, content here.

    Use `self.father` methods to modify request directly.
    """
    def handleHeader(self, key, value):
        # change response header here
        log.msg("Header: %s: %s" % (key, value))
        proxy.ProxyClient.handleHeader(self, key, value)

    def handleResponsePart(self, buffer):
        # change response part here
        log.msg("Content: %s" % (buffer[:50],))
        # make all content upper case
        proxy.ProxyClient.handleResponsePart(self, buffer.upper())

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

通过查看twisted.web.proxy的来源,我得到了这个解决方案。我不知道它是多么惯用。

要将其作为脚本运行或通过twistd运行,请在末尾添加:

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

if __name__ == '__main__': # $ python proxy_modify_request.py
    import sys
    from twisted.internet import endpoints, reactor

    def shutdown(reason, reactor, stopping=[]):
        """Stop the reactor."""
        if stopping: return
        stopping.append(True)
        if reason:
            log.msg(reason.value)
        reactor.callWhenRunning(reactor.stop)

    log.startLogging(sys.stdout)
    endpoint = endpoints.serverFromString(reactor, portstr)
    d = endpoint.listen(ProxyFactory())
    d.addErrback(shutdown, reactor)
    reactor.run()
else: # $ twistd -ny proxy_modify_request.py
    from twisted.application import service, strports

    application = service.Application("proxy_modify_request")
    strports.service(portstr, ProxyFactory()).setServiceParent(application)

用法

$ twistd -ny proxy_modify_request.py

在另一个终端:

$ curl -x localhost:8080 http://example.com

答案 1 :(得分:4)

对于使用twisted的双向代理,请参阅文章:

http://sujitpal.blogspot.com/2010/03/http-debug-proxy-with-twisted.html