Python - витая, прокси и модифицирующий контент - PullRequest
18 голосов
/ 27 февраля 2012

Итак, я рассмотрел несколько вещей, связанных с написанием HTTP-прокси с использованием Python и Twisted Framework.

По сути, как и некоторые другие вопросы, я хотел бы иметь возможность изменять данные, которыебудет отправлен обратно в браузер.То есть браузер запрашивает ресурс, а прокси его получает.Прежде чем ресурс будет возвращен в браузер, я хотел бы иметь возможность изменять ЛЮБОЙ (заголовки HTTP И контент) контент.

Это ( Нужна помощь в написании скрученного прокси ) было то, что я изначально нашел.Я попробовал это, но это не сработало для меня.Я также нашел это ( Python Twisted proxy - как перехватывать пакеты ), который, как я думал, будет работать, однако я могу видеть только HTTP-запросы из браузера.

Я ищу любой совет,У меня есть некоторые мысли по поводу использования классов ProxyClient и ProxyRequest и переопределения функций, но я прочитал, что сам класс Proxy представляет собой комбинацию обоих.

Для тех, кто может попросить увидеть некоторый код, он долженСледует отметить, что я работал только с двумя приведенными выше примерами.Любая помощь велика.

Спасибо.

Ответы [ 2 ]

18 голосов
/ 27 февраля 2012

Чтобы создать ProxyFactory, который может изменять заголовки ответов сервера, вы можете переопределить содержимое ProxyClient.handle*() методов :

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
4 голосов
/ 27 февраля 2012

Для двустороннего прокси с использованием twisted см. Статью:

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

...