[Twisted-Python] Trying to proxy through multiple IPs
Erik Wickstrom
erik at erikwickstrom.com
Tue Nov 4 02:06:50 EST 2008
Hi all,
I'm trying to write a proxy server that accepts connections on
multiple ports, and depending on the port, using a different IP for
the outgoing connection. My code works except that adding additional
reactor.listenTCP(...)s overwrite the IP of the previous listenTCPs.
So the proxy accepts connections on all the desired ports, but only
uses the last IP address for outgoing connections.
The ip (bindIP) is somehow being overwritten. Based on advice from
IRC (exarkun --thanks!), I've tried a couple attempts at using
closures to solve the problem, but non of my implementations have done
the trick.
Can anyone see any other changes that might get this working?
# Also pasted at http://dpaste.com/88623/ incase of email garbling...
#from twisted.web import proxy, http
import urlparse
from urllib import quote as urlquote
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory
from twisted.web.resource import Resource
from twisted.web.server import NOT_DONE_YET
from twisted.web.http import HTTPClient, Request, HTTPChannel
from twisted.web.proxy import ProxyClient, ProxyClientFactory
from twisted.web import http
from twisted.internet import reactor
from twisted.python import log
import sys
log.startLogging(sys.stdout)
class ProxyRequest(Request):
"""
Used by Proxy to implement a simple web proxy.
@ivar reactor: the reactor used to create connections.
@type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
"""
protocols = {'http': ProxyClientFactory}
ports = {'http': 80}
def __init__(self, channel, queued, reactor=reactor):
Request.__init__(self, channel, queued)
self.reactor = reactor
def process(self):
parsed = urlparse.urlparse(self.uri)
protocol = parsed[0]
host = parsed[1]
port = self.ports[protocol]
if ':' in host:
host, port = host.split(':')
port = int(port)
rest = urlparse.urlunparse(('', '') + parsed[2:])
if not rest:
rest = rest + '/'
class_ = self.protocols[protocol]
headers = self.getAllHeaders().copy()
if 'host' not in headers:
headers['host'] = host
self.content.seek(0, 0)
s = self.content.read()
clientFactory = class_(self.method, rest, self.clientproto, headers,
s, self)
self.reactor.connectTCP(host, port, clientFactory,
bindAddress=(self.bindIP,0))
class Proxy(HTTPChannel):
requestFactory = ProxyRequest
class ProxyFactory(http.HTTPFactory):
def class_factory(self, bindIP):
def closure(ip):
klass2 = ProxyRequest
setattr(klass2, 'bindIP', ip)
return klass2
klass = Proxy
setattr(klass, 'requestFactory', closure(bindIP))
return klass
def __init__(self, ip):
http.HTTPFactory.__init__(self)
self.ip = ip
#self.protocol = proxy.Proxy
self.protocol = self.class_factory(ip)
reactor.listenTCP(8080, ProxyFactory('192.168.168.101'),
interface="192.168.168.1")
reactor.listenTCP(8081, ProxyFactory('192.168.168.102'),
interface="192.168.168.1")
reactor.run()
##
Thanks!
Erik
More information about the Twisted-Python
mailing list