summaryrefslogtreecommitdiff
path: root/pypers/europython05/Quixote-2.0/server/medusa_server.py
diff options
context:
space:
mode:
Diffstat (limited to 'pypers/europython05/Quixote-2.0/server/medusa_server.py')
-rwxr-xr-xpypers/europython05/Quixote-2.0/server/medusa_server.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/pypers/europython05/Quixote-2.0/server/medusa_server.py b/pypers/europython05/Quixote-2.0/server/medusa_server.py
new file mode 100755
index 0000000..239d95e
--- /dev/null
+++ b/pypers/europython05/Quixote-2.0/server/medusa_server.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+"""$URL: svn+ssh://svn.mems-exchange.org/repos/trunk/quixote/server/medusa_server.py $
+$Id: medusa_server.py 25579 2004-11-11 20:56:32Z nascheme $
+
+An HTTP handler for Medusa that publishes a Quixote application.
+"""
+
+import asyncore, rfc822, socket, urllib
+from StringIO import StringIO
+from medusa import http_server, xmlrpc_handler
+import quixote
+from quixote.http_request import HTTPRequest
+
+
+class StreamProducer:
+ def __init__(self, chunks):
+ self.chunks = chunks # a generator
+
+ def more(self):
+ try:
+ return self.chunks.next()
+ except StopIteration:
+ return ''
+
+
+class QuixoteHandler:
+ def __init__(self, publisher, server):
+ self.publisher = publisher
+ self.server = server
+
+ def match(self, request):
+ # Always match, since this is the only handler there is.
+ return True
+
+ def handle_request(self, request):
+ msg = rfc822.Message(StringIO('\n'.join(request.header)))
+ length = int(msg.get('Content-Length', '0'))
+ if length:
+ request.collector = xmlrpc_handler.collector(self, request)
+ else:
+ self.continue_request('', request)
+
+ def continue_request(self, data, request):
+ msg = rfc822.Message(StringIO('\n'.join(request.header)))
+ remote_addr, remote_port = request.channel.addr
+ if '#' in request.uri:
+ # MSIE is buggy and sometimes includes fragments in URLs
+ [request.uri, fragment] = request.uri.split('#', 1)
+ if '?' in request.uri:
+ [path, query_string] = request.uri.split('?', 1)
+ else:
+ path = request.uri
+ query_string = ''
+
+ path = urllib.unquote(path)
+ server_port = str(self.server.port)
+ http_host = msg.get("Host")
+ if http_host:
+ if ":" in http_host:
+ server_name, server_port = http_host.split(":", 1)
+ else:
+ server_name = http_host
+ else:
+ server_name = (self.server.ip or
+ socket.gethostbyaddr(socket.gethostname())[0])
+
+ environ = {'REQUEST_METHOD': request.command,
+ 'ACCEPT_ENCODING': msg.get('Accept-encoding', ''),
+ 'CONTENT_TYPE': msg.get('Content-type', ''),
+ 'CONTENT_LENGTH': len(data),
+ "GATEWAY_INTERFACE": "CGI/1.1",
+ 'PATH_INFO': path,
+ 'QUERY_STRING': query_string,
+ 'REMOTE_ADDR': remote_addr,
+ 'REMOTE_PORT': str(remote_port),
+ 'REQUEST_URI': request.uri,
+ 'SCRIPT_NAME': '',
+ "SCRIPT_FILENAME": '',
+ 'SERVER_NAME': server_name,
+ 'SERVER_PORT': server_port,
+ 'SERVER_PROTOCOL': 'HTTP/1.1',
+ 'SERVER_SOFTWARE': 'Quixote/%s' % quixote.__version__,
+ }
+ for title, header in msg.items():
+ envname = 'HTTP_' + title.replace('-', '_').upper()
+ environ[envname] = header
+
+ stdin = StringIO(data)
+ qrequest = HTTPRequest(stdin, environ)
+ qresponse = self.publisher.process_request(qrequest)
+
+ # Copy headers from Quixote's HTTP response
+ for name, value in qresponse.generate_headers():
+ # XXX Medusa's HTTP request is buggy, and only allows unique
+ # headers.
+ request[name] = value
+
+ request.response(qresponse.status_code)
+ request.push(StreamProducer(qresponse.generate_body_chunks()))
+ request.done()
+
+
+def run(create_publisher, host='', port=80):
+ """Runs a Medusa HTTP server that publishes a Quixote
+ application.
+ """
+ server = http_server.http_server(host, port)
+ publisher = create_publisher()
+ handler = QuixoteHandler(publisher, server)
+ server.install_handler(handler)
+ asyncore.loop()
+
+
+if __name__ == '__main__':
+ from quixote.server.util import main
+ main(run)