#c:/Python23/Python """quixote.server.medusa_http An HTTP handler for Medusa that publishes a Quixote application. """ __revision__ = "$Id: medusa_http.py 23942 2004-04-08 14:22:23Z nascheme $" # A simple HTTP server, using Medusa, that publishes a Quixote application. import os, sys import asyncore, rfc822, socket from StringIO import StringIO from medusa import http_server, xmlrpc_handler from quixote.http_response import Stream from quixote.publish import Publisher class StreamProducer: def __init__(self, stream): self.iterator = iter(stream) def more(self): try: return self.iterator.next() except StopIteration: return '' class QuixoteHandler: def __init__ (self, publisher, server_name, server): """QuixoteHandler(publisher:Publisher, server_name:string, server:medusa.http_server.http_server) Publish the specified Quixote publisher. 'server_name' will be passed as the SERVER_NAME environment variable. """ self.publisher = publisher self.server_name = server_name self.server = server def match (self, request): # Always match, since this is the only handler there is. return 1 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 = '' 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", 'HTTP_COOKIE': msg.get('Cookie'), 'HTTP_REFERER': msg.get('Referer'), 'HTTP_USER_AGENT': msg.get('User-agent'), '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': self.server_name, } # Propagate HTTP headers - copied from twisted_http.py for title, header in msg.items(): envname = title.replace('-', '_').upper() if title not in ('content-type', 'content-length'): envname = "HTTP_" + envname environ[envname] = header for k,v in environ.items(): if v == None: environ[k] = '' stdin = StringIO(data) qreq = self.publisher.create_request(stdin, environ) output = self.publisher.process_request(qreq, environ) qresponse = qreq.response if output: qresponse.set_body(output) # 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) # XXX should we set a default Last-Modified time? if qresponse.body is not None: if isinstance(qresponse.body, Stream): request.push(StreamProducer(qresponse.body)) else: request.push(qresponse.body) request.done() def main (): sys.stdout = file(os.path.join("c:/trading/pytradeweb/", "logs", "run.log"), 'w') sys.stderr = file(os.path.join("c:/trading/pytradeweb/", "logs", "run.err"), 'w') from quixote import enable_ptl enable_ptl() if len(sys.argv) == 2: port = int(sys.argv[1]) else: port = 8080 print 'Now serving the Quixote demo on port %d' % port server = http_server.http_server('127.0.0.1', port) publisher = Publisher('pytradeweb') # When initializing the Publisher in your own driver script, # you'll want to parse a configuration file. publisher.read_config("c:/trading/pytradeweb/config/quixote.conf") publisher.setup_logs() dh = QuixoteHandler(publisher, 'pytradeweb', server) server.install_handler(dh) asyncore.loop() sys.stdout.close() sys.stderr.close() sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ if __name__ == '__main__': main()