使用Twisted和Python创建路由器
当一个客户端(比如说网页浏览器)访问 localhost:8080
时,它的请求应该被发送到一个由 SERVER_ADDR
定义的地址,比如 http://www.yahoo.com
。这更像是一个路由器或负载均衡器,而不是一个代理。
问题:当我的网页浏览器访问 localhost:8080
时,什么都没有返回给它。在Python控制台上,可以看到HTTP请求头已经到达了Twisted应用程序。也许这不能用来重定向浏览器的请求?
from twisted.internet import protocol, reactor
LISTEN_PORT = 8080
SERVER_PORT = 80
SERVER_ADDR = 'http://www.yahoo.com'
class ServerProtocol(protocol.Protocol):
def __init__(self):
self.buffer = None
self.client = None
def connectionMade(self):
factory = protocol.ClientFactory()
factory.protocol = ClientProtocol
factory.server = self
reactor.connectTCP(SERVER_ADDR, SERVER_PORT, factory)
# Client => Proxy
def dataReceived(self, data):
print 'Data received from Client:'
if self.client:
self.client.write(data)
else:
data = data.replace('localhost:8080', SERVER_ADDR)
print data
self.buffer = data
# Proxy => Client
def write(self, data):
self.transport.write(data)
class ClientProtocol(protocol.Protocol):
def connectionMade(self):
self.factory.server.client = self
self.write(self.factory.server.buffer)
self.factory.server.buffer = ''
# Server => Proxy
def dataReceived(self, data):
print 'Data received from Server: '
print data
self.factory.server.write(data)
# Proxy => Server
def write(self, data):
if data:
self.transport.write(data)
def main():
factory = protocol.ServerFactory()
factory.protocol = ServerProtocol
reactor.listenTCP(LISTEN_PORT, factory)
reactor.run()
if __name__ == '__main__':
main()
1 个回答
0
对我来说,这个方法部分有效:当我在浏览器中访问 http://localhost:8080
时,Yahoo 服务器给我返回了一个 HTTP 错误 400,表示请求有问题。这是因为你把 GET 请求中的 Host: localhost:8080
替换成了 Host: http://www.yahoo.com
,而这里的协议是不对的。正确的写法应该是 Host: www.yahoo.com
。
不过,这样做之后,它会返回一个 HTTP/1.1 301 Moved Permanently
的重定向,这样你可能会遇到其他问题。
补充一下:你应该去看看 twisted 网站上的代理示例(https://twistedmatrix.com/documents/12.3.0/web/examples/#auto2),深入了解一下它是怎么实现的。
from twisted.web import proxy, http
from twisted.internet import reactor
class ProxyFactory(http.HTTPFactory):
def buildProtocol(self, addr):
return proxy.Proxy()
reactor.listenTCP(8080, ProxyFactory())
reactor.run()