扭曲网络代理
我一直在运行这段代码(来自: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: ''
每次我设置火狐、谷歌浏览器或欧朋浏览器使用localhost:8000的代理时,都没有连接到代理(而且我也无法访问任何页面,这可能是因为没有连接到代理)。
好吧,它还是失败了,通过日志我发现,当我把火狐设置为使用localhost:8000的代理,并且没有直接在浏览器中访问代理(比如在火狐的地址栏输入localhost:8000)时,我得到了这个输出:
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似乎无法监控本地流量,而如果我使用Fiddler 2,它会自己设置为代理(这样我就不再使用我的代理服务器),然后就能工作(因为它使用的是Fiddler 2的代理)。
1 个回答
你看到的 KeyError
错误是因为连接代理时,发送的请求必须包含完整的网址,而不是简短的相对网址。如果你的浏览器不知道它在和代理通信,它会请求像 /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)