1 """BaseHTTPServer that implements the Python WSGI protocol (PEP 333, rev 1.21)
3 This is both an example of how WSGI can be implemented, and a basis for running
4 simple web applications on a local machine, such as might be done when testing
5 or debugging an application. It has not been reviewed for security issues,
6 however, and we strongly recommend that you use a "real" web server for
9 For example usage, see the 'if __name__=="__main__"' block at the end of the
10 module. See also the BaseHTTPServer module docs for other API information.
13 from BaseHTTPServer
import BaseHTTPRequestHandler
, HTTPServer
15 from wsgiref
.handlers
import SimpleHandler
18 __all__
= ['WSGIServer', 'WSGIRequestHandler', 'demo_app', 'make_server']
21 server_version
= "WSGIServer/" + __version__
22 sys_version
= "Python/" + sys
.version
.split()[0]
23 software_version
= server_version
+ ' ' + sys_version
26 class ServerHandler(SimpleHandler
):
28 server_software
= software_version
32 self
.request_handler
.log_request(
33 self
.status
.split(' ',1)[0], self
.bytes_sent
36 SimpleHandler
.close(self
)
42 class WSGIServer(HTTPServer
):
44 """BaseHTTPServer that implements the Python WSGI protocol"""
48 def server_bind(self
):
49 """Override server_bind to store the server name."""
50 HTTPServer
.server_bind(self
)
53 def setup_environ(self
):
54 # Set up base environment
55 env
= self
.base_environ
= {}
56 env
['SERVER_NAME'] = self
.server_name
57 env
['GATEWAY_INTERFACE'] = 'CGI/1.1'
58 env
['SERVER_PORT'] = str(self
.server_port
)
60 env
['CONTENT_LENGTH']=''
61 env
['SCRIPT_NAME'] = ''
64 return self
.application
66 def set_app(self
,application
):
67 self
.application
= application
83 class WSGIRequestHandler(BaseHTTPRequestHandler
):
85 server_version
= "WSGIServer/" + __version__
87 def get_environ(self
):
88 env
= self
.server
.base_environ
.copy()
89 env
['SERVER_PROTOCOL'] = self
.request_version
90 env
['REQUEST_METHOD'] = self
.command
92 path
,query
= self
.path
.split('?',1)
94 path
,query
= self
.path
,''
96 env
['PATH_INFO'] = urllib
.unquote(path
)
97 env
['QUERY_STRING'] = query
99 host
= self
.address_string()
100 if host
!= self
.client_address
[0]:
101 env
['REMOTE_HOST'] = host
102 env
['REMOTE_ADDR'] = self
.client_address
[0]
104 if self
.headers
.typeheader
is None:
105 env
['CONTENT_TYPE'] = self
.headers
.type
107 env
['CONTENT_TYPE'] = self
.headers
.typeheader
109 length
= self
.headers
.getheader('content-length')
111 env
['CONTENT_LENGTH'] = length
113 for h
in self
.headers
.headers
:
115 k
=k
.replace('-','_').upper(); v
=v
.strip()
117 continue # skip content length, type,etc.
119 env
['HTTP_'+k
] += ','+v
# comma-separate multiple headers
124 def get_stderr(self
):
128 """Handle a single HTTP request"""
130 self
.raw_requestline
= self
.rfile
.readline()
131 if not self
.parse_request(): # An error code has been sent, just exit
134 handler
= ServerHandler(
135 self
.rfile
, self
.wfile
, self
.get_stderr(), self
.get_environ()
137 handler
.request_handler
= self
# backpointer for logging
138 handler
.run(self
.server
.get_app())
165 def demo_app(environ
,start_response
):
166 from StringIO
import StringIO
168 print >>stdout
, "Hello world!"
170 h
= environ
.items(); h
.sort()
172 print >>stdout
, k
,'=',`v`
173 start_response("200 OK", [('Content-Type','text/plain')])
174 return [stdout
.getvalue()]
178 host
, port
, app
, server_class
=WSGIServer
, handler_class
=WSGIRequestHandler
180 """Create a new WSGI server listening on `host` and `port` for `app`"""
181 server
= server_class((host
, port
), handler_class
)
186 if __name__
== '__main__':
187 httpd
= make_server('', 8000, demo_app
)
188 sa
= httpd
.socket
.getsockname()
189 print "Serving HTTP on", sa
[0], "port", sa
[1], "..."
191 webbrowser
.open('http://localhost:8000/xyz?abc')
192 httpd
.handle_request() # serve one request, then exit