I have the following:
- My webserver running on twisted
- My comet server, aka orbited
Note that 1 and 2 are different processes.
Basically, I want 1 and 2 to share the same port. Request that are http://mysite.com/a/b/c should go to the webserver and anything starting with http://mysite.com/orbited/ should go to the orbited server, i.e. (http://mysite.com/orbited/a/b/c => do a request to http://mysite.com:12345/a/b/c and return that).
This is what I have right now:
# Reverse Proxy
class OrbitedResource(Resource):
isLeaf = True
def __init__(self, orbited_url='http://127.0.0.1:12345'):
self.orbited = orbited_url
Resource.__init__(self)
def render_GET(self, request):
def callback(html):
request.write(html)
request.finish()
def errback(failure, *args):
request.setResponseCode(http.INTERNAL_SERVER_ERROR)
request.write(failure.getErrorMessage())
request.finish()
request.setHeader('Connection', 'close')
# TODO find cleaner way to do this:
# Currently request.uri is "/orbited/....", you must trim it
target_uri = request.uri.replace('/orbited', '')
final_uri = self.orbited + target_uri
print "final_uri is", final_uri
deferred = getPage(final_uri)
deferred.addCallbacks(callback, errback)
return server.NOT_DONE_YET
class SimpleRoutingResource(Resource):
isLeaf = False
def __init__(self, wsgiApp):
Resource.__init__(self)
self.WSGIApp = wsgiApp
self.orbitedResource = OrbitedResource()
def getChild(self, name, request):
if name == "orbited":
request.prepath.pop()
print "Simple request.path is", request.path
return self.orbitedResource
else:
request.prepath.pop()
request.postpath.insert(0,name)
return self.WSGIApp
# Attaching proxy + django
log_dir = './.log'
if not os.path.exists(log_dir):
os.makedirs(log_dir)
reactor.listenTCP(DJANGO_PORT, server.Site(SimpleRoutingResource(WSGIRoot),
logPath=os.path.join(log_dir, '.django.log')))
Currently this works . However, I see that there's a class called ReverseProxyProtocol, and I have been doing tried it with the following modification:
class SimpleRoutingResource(Resource):
isLeaf = False
def __init__(self, wsgiApp):
Resource.__init__(self)
self.WSGIApp = wsgiApp
def getChild(self, name, request):
if name == "orbited":
request.prepath.pop()
print "Simple request.path is", request.path, name
return ReverseProxyResource( 'http://localhost', 12345, name )
else:
request.prepath.pop()
request.postpath.insert(0,name)
return self.WSGIApp
This is NOT Working. I have inserted a lot of prints into the twisted's reverseProxyResource class, and I discovered the following:
- Given http://mysite.com/orbited/a/b/c
- OrbitedResource will keep calling ReverseProxyResource with getChild until c
- by the time you get to c, the url is messed up and the client class calling the orbited server will be wrong
- I tried setting isLeaf = True in the ReverseProxyResource, but to no avail.
Anybody can point me a more effecient way to write the getPage? Do I really need to use ReverseProxyResource if it's such a black box in nature?