Twisted Web Proxy - PullRequest
       4

Twisted Web Proxy

1 голос
/ 04 августа 2010

Я выполняю этот код (с: http://blog.somethingaboutcode.com/?p=155):

from twisted.internet import reactor
from twisted.web import http
from twisted.web.proxy import Proxy, ProxyRequest, ProxyClientFactory, ProxyClient
from ImageFile import Parser
from StringIO import StringIO

class InterceptingProxyClient(ProxyClient):
    def __init__(self, *args, **kwargs):
        ProxyClient.__init__(self, *args, **kwargs)
        self.image_parser = None

    def handleHeader(self, key, value):
        if key == "Content-Type" and value in ["image/jpeg", "image/gif", "image/png"]:
            self.image_parser = Parser()
        if key == "Content-Length" and self.image_parser:
            pass
        else:
            ProxyClient.handleHeader(self, key, value)

    def handleEndHeaders(self):
        if self.image_parser:
            pass #Need to calculate and send Content-Length first
        else:
            ProxyClient.handleEndHeaders(self)

    def handleResponsePart(self, buffer):
        print buffer
        if self.image_parser:
            self.image_parser.feed(buffer)
        else:
            ProxyClient.handleResponsePart(self, buffer)

    def handleResponseEnd(self):
        if self.image_parser:
            image = self.image_parser.close()
            try:
                format = image.format
                image = image.rotate(180)
                s = StringIO()
                image.save(s, format)
                buffer = s.getvalue()
            except:
                buffer = ""
            ProxyClient.handleHeader(self, "Content-Length", len(buffer))
            ProxyClient.handleEndHeaders(self)
            ProxyClient.handleResponsePart(self, buffer)
        ProxyClient.handleResponseEnd(self)

class InterceptingProxyClientFactory(ProxyClientFactory):
    protocol = InterceptingProxyClient

class InterceptingProxyRequest(ProxyRequest):
    protocols = {'http': InterceptingProxyClientFactory}
    ports = {"http" : 80}

class InterceptingProxy(Proxy):
    requestFactory = InterceptingProxyRequest

factory = http.HTTPFactory()
factory.protocol = InterceptingProxy

reactor.listenTCP(8000, factory)
reactor.run()

Всякий раз, когда я получаю это и иду к 127.0.0.1:8000, я получаю это:

Traceback (most recent call last):
  File "C:\Program Files\Python 2.6.2\lib\site-packages\twisted\python\log.py",
line 84, in callWithLogger
    return callWithContext({"system": lp}, func, *args, **kw)
  File "C:\Program Files\Python 2.6.2\lib\site-packages\twisted\python\log.py",
line 69, in callWithContext
    return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "C:\Program Files\Python 2.6.2\lib\site-packages\twisted\python\context.p
y", line 59, in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "C:\Program Files\Python 2.6.2\lib\site-packages\twisted\python\context.p
y", line 37, in callWithContext
    return func(*args,**kw)
--- <exception caught here> ---
  File "C:\Program Files\Python 2.6.2\lib\site-packages\twisted\internet\selectr
eactor.py", line 146, in _doReadOrWrite
    why = getattr(selectable, method)()
  File "C:\Program Files\Python 2.6.2\lib\site-packages\twisted\internet\tcp.py"
, line 460, in doRead
    return self.protocol.dataReceived(data)
  File "C:\Program Files\Python 2.6.2\lib\site-packages\twisted\protocols\basic.
py", line 251, in dataReceived
    why = self.lineReceived(line)
  File "C:\Program Files\Python 2.6.2\lib\site-packages\twisted\web\http.py", li
ne 1573, in lineReceived
    self.allContentReceived()
  File "C:\Program Files\Python 2.6.2\lib\site-packages\twisted\web\http.py", li
ne 1641, in allContentReceived
    req.requestReceived(command, path, version)
  File "C:\Program Files\Python 2.6.2\lib\site-packages\twisted\web\http.py", li
ne 807, in requestReceived
    self.process()
  File "C:\Program Files\Python 2.6.2\lib\site-packages\twisted\web\proxy.py", l
ine 147, in process
    port = self.ports[protocol]
exceptions.KeyError: ''

Всякий раз, когда я настраиваю Firefox, Chrome или Opera для использования прокси на локальном хосте: 8000 нет никаких соединений с прокси (и я больше не могу подключиться ни к одной странице, хотя это, вероятно, потому что это не соединение спрокси).


Хорошо, это все еще не удается, и при ведении журнала я получаю этот вывод, когда я устанавливаю firefox для использования прокси на localhost: 8000 и не посещаю прокси напрямую из веб-браузера (например,например, набрав localhost: 8000 в адресной строке firefox)

2010-08-04 12:31:18-0400 [-] Log opened.
2010-08-04 12:31:29-0400 [-] twisted.web.http.HTTPFactory starting on 8000
2010-08-04 12:31:29-0400 [-] Starting factory <twisted.web.http.HTTPFactory inst
ance at 0x010B3EE0>
2010-08-04 12:33:55-0400 [-] Received SIGINT, shutting down.
2010-08-04 12:33:55-0400 [twisted.web.http.HTTPFactory] (Port 8000 Closed)
2010-08-04 12:33:55-0400 [twisted.web.http.HTTPFactory] Stopping factory <twiste
d.web.http.HTTPFactory instance at 0x010B3EE0>
2010-08-04 12:33:55-0400 [-] Main loop terminated.

Однако, когда я посещаю прокси-сервер напрямую, я получаю ошибку ключа.

Также для прослушивания я не могу;Wireshark, кажется, не перехватывает трафик localhost, и если я использую fiddler 2, он устанавливает себя в качестве прокси-сервера (и поэтому я больше не использую свой прокси-сервер), а затем работает (потому что он использует прокси-сервер fiddler 2).

1 Ответ

1 голос
/ 04 августа 2010

Исключение KeyError, которое вы видите, когда вы подключаетесь напрямую, вызвано тем, что запросы к прокси должны включать абсолютный URL, а не относительный. Если ваш браузер не знает, что он разговаривает с прокси, он запросит URL-адрес, например /foo/bar. Если он знает, что разговаривает с прокси, он вместо этого запросит что-то вроде http://example.com/foo/bar. Часть http://example.com/ важна, потому что это единственный способ, которым прокси-сервер знает, что он должен отключить и получить.

Что касается того, почему ни Firefox, ни Chrome, ни Opera не будут подключаться к прокси, как только вы настроите их для этого, объяснить немного сложнее. Убедитесь, что вы настраиваете «HTTP-прокси», а не другие поддерживаемые типы прокси. После того, как вы дважды проверили это, вы можете использовать такой инструмент, как Wireshark, чтобы лучше понять, что происходит на сетевом уровне.

Возможно, что на самом деле устанавливаются соединения с прокси, но что-то еще идет не так, что мешает их завершению. В этом случае, если ведение журнала не включено, вы не сможете определить, что прокси-сервер получает соединения, просто посмотрев его выходные данные. Чтобы включить ведение журнала, попробуйте:

from sys import stdout
from twisted.python.log import startLogging
startLogging(stdout)
...