diff --git a/src/server/portal/portal.py b/src/server/portal/portal.py index be5b7c1f4..f35ae4e6d 100644 --- a/src/server/portal/portal.py +++ b/src/server/portal/portal.py @@ -9,6 +9,8 @@ by game/evennia.py). """ import sys import os +from src.server.webserver import EvenniaReverseProxyResource + if os.name == 'nt': # For Windows batchfile we need an extra path insertion here. sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname( @@ -256,7 +258,7 @@ if WEBSERVER_ENABLED: ifacestr = "-%s" % interface for proxyport, serverport in WEBSERVER_PORTS: pstring = "%s:%s<->%s" % (ifacestr, proxyport, serverport) - web_root = proxy.ReverseProxyResource('127.0.0.1', serverport, '') + web_root = EvenniaReverseProxyResource('127.0.0.1', serverport, '') webclientstr = "" if WEBCLIENT_ENABLED: # create ajax client processes at /webclientdata diff --git a/src/server/webserver.py b/src/server/webserver.py index 9daf5d8b2..fdea83bb9 100644 --- a/src/server/webserver.py +++ b/src/server/webserver.py @@ -11,10 +11,13 @@ application. a great example/aid on how to do this.) """ +import urlparse +from urllib import quote as urlquote from twisted.web import resource, http -from twisted.python import threadpool from twisted.internet import reactor from twisted.application import service, internet +from twisted.web.proxy import ReverseProxyResource +from twisted.web.server import NOT_DONE_YET from twisted.web.wsgi import WSGIResource from django.core.handlers.wsgi import WSGIHandler @@ -44,6 +47,36 @@ class HTTPChannelWithXForwardedFor(http.HTTPChannel): http.HTTPFactory.protocol = HTTPChannelWithXForwardedFor +class EvenniaReverseProxyResource(ReverseProxyResource): + def getChild(self, path, request): + """ + Create and return a proxy resource with the same proxy configuration + as this one, except that its path also contains the segment given by + C{path} at the end. + """ + return EvenniaReverseProxyResource( + self.host, self.port, self.path + '/' + urlquote(path, safe=""), + self.reactor) + + + def render(self, request): + """ + Render a request by forwarding it to the proxied server. + """ + # RFC 2616 tells us that we can omit the port if it's the default port, + # but we have to provide it otherwise + request.content.seek(0, 0) + qs = urlparse.urlparse(request.uri)[4] + if qs: + rest = self.path + '?' + qs + else: + rest = self.path + clientFactory = self.proxyClientFactoryClass( + request.method, rest, request.clientproto, + request.getAllHeaders(), request.content.read(), request) + self.reactor.connectTCP(self.host, self.port, clientFactory) + return NOT_DONE_YET + # # Website server resource #