From 304270ce19450a1ca701d5d4cdbe41cb5de18a83 Mon Sep 17 00:00:00 2001 From: pje Date: Fri, 8 Oct 2004 00:24:25 +0000 Subject: Moved 'peak.util.WSGIServer' to 'wsgiref.simple_server'. git-svn-id: svn://svn.eby-sarna.com/svnroot/wsgiref@255 571e12c6-e1fa-0310-aee7-ff1267fa46bd --- src/wsgiref/__init__.py | 8 +- src/wsgiref/simple_server.py | 205 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+), 3 deletions(-) create mode 100644 src/wsgiref/simple_server.py diff --git a/src/wsgiref/__init__.py b/src/wsgiref/__init__.py index d79e3f8..9f37850 100644 --- a/src/wsgiref/__init__.py +++ b/src/wsgiref/__init__.py @@ -8,10 +8,12 @@ Current Contents: * handlers -- base classes for server/gateway implementations -To-Do: - - * server -- a SimpleHTTPServer that supports WSGI + * simple_server -- a simple BaseHTTPServer that supports WSGI +To-Do: + + * validate -- validation library and "lint"-like functions + * cgi_gateway -- Run WSGI apps under CGI * cgi_wrapper -- Run CGI apps under WSGI diff --git a/src/wsgiref/simple_server.py b/src/wsgiref/simple_server.py new file mode 100644 index 0000000..cb6ba23 --- /dev/null +++ b/src/wsgiref/simple_server.py @@ -0,0 +1,205 @@ +"""BaseHTTPServer that implements the Python WSGI protocol (PEP 333, rev 1.21) + +This is both an example of how WSGI can be implemented, and a basis for running +simple web applications on a local machine, such as might be done when testing +or debugging an application. It has not been reviewed for security issues, +however, and we strongly recommend that you use a "real" web server for +production use. + +For example usage, see the 'if __name__=="__main__"' block at the end of the +module. See also the BaseHTTPServer module docs for other API information. +""" + +from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer +import urllib, sys +from wsgiref.handlers import SimpleHandler + +__version__ = "0.1" +__all__ = ['WSGIServer','WSGIRequestHandler','DemoService'] + + +server_version = "WSGIServer/" + __version__ +sys_version = "Python/" + sys.version.split()[0] +software_version = server_version + ' ' + sys_version + + +class ServerHandler(SimpleHandler): + + server_software = software_version + + def close(self): + try: + self.request_handler.log_request( + self.status.split(' ',1)[0], self.bytes_sent + ) + finally: + SimpleHandler.close(self) + + + + + +class WSGIServer(HTTPServer): + + """BaseHTTPServer that implements the Python WSGI protocol""" + + application = None + + def server_bind(self): + """Override server_bind to store the server name.""" + HTTPServer.server_bind(self) + self.setup_environ() + + def setup_environ(self): + # Set up base environment + env = self.base_environ = {} + env['SERVER_NAME'] = self.server_name + env['GATEWAY_INTERFACE'] = 'CGI/1.1' + env['SERVER_PORT'] = str(self.server_port) + env['REMOTE_HOST']='' + env['CONTENT_LENGTH']='' + env['SCRIPT_NAME'] = '' + + def get_app(self): + return self.application + + def set_app(self,application): + self.application = application + + + + + + + + + + + + + + + +class WSGIRequestHandler(BaseHTTPRequestHandler): + + server_version = "WSGIServer/" + __version__ + + def get_environ(self): + env = self.server.base_environ.copy() + env['SERVER_PROTOCOL'] = self.request_version + env['REQUEST_METHOD'] = self.command + if '?' in self.path: + path,query = self.path.split('?',1) + else: + path,query = self.path,'' + + env['PATH_INFO'] = urllib.unquote(path) + env['QUERY_STRING'] = query + + host = self.address_string() + if host != self.client_address[0]: + env['REMOTE_HOST'] = host + env['REMOTE_ADDR'] = self.client_address[0] + + if self.headers.typeheader is None: + env['CONTENT_TYPE'] = self.headers.type + else: + env['CONTENT_TYPE'] = self.headers.typeheader + + length = self.headers.getheader('content-length') + if length: + env['CONTENT_LENGTH'] = length + + for h in self.headers.headers: + k,v = h.split(':',1) + k=k.replace('-','_').upper(); v=v.strip() + if k in env: + continue # skip content length, type,etc. + if 'HTTP_'+k in env: + env['HTTP_'+k] += ','+v # comma-separate multiple headers + else: + env['HTTP_'+k] = v + return env + + def get_stderr(self): + return sys.stderr + + def handle(self): + """Handle a single HTTP request""" + + self.raw_requestline = self.rfile.readline() + if not self.parse_request(): # An error code has been sent, just exit + return + + handler = ServerHandler( + self.rfile, self.wfile, self.get_stderr(), self.get_environ() + ) + handler.request_handler = self # backpointer for logging + handler.run(self.server.get_app()) + + + + + + + + + + + + + + + + + + + + + + + + + + +def demo_app(environ,start_response): + from StringIO import StringIO + stdout = StringIO() + print >>stdout, "Hello world!" + print >>stdout + h = environ.items(); h.sort() + for k,v in h: + print >>stdout, k,'=',`v` + start_response("200 OK", [('Content-Type','text/plain')]) + return [stdout.getvalue()] + + +if __name__ == '__main__': + server_address = ('', 8000) + httpd = WSGIServer(server_address, WSGIRequestHandler) + httpd.set_app(demo_app) + sa = httpd.socket.getsockname() + print "Serving HTTP on", sa[0], "port", sa[1], "..." + import webbrowser + webbrowser.open('http://localhost:8000/xyz?abc') + httpd.handle_request() # serve one request, then exit + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.1