blob: 980f97ab37635622933141843b92761247c8b0a4 [file] [log] [blame]
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001"""BaseHTTPServer that implements the Python WSGI protocol (PEP 333, rev 1.21)
2
3This is both an example of how WSGI can be implemented, and a basis for running
4simple web applications on a local machine, such as might be done when testing
5or debugging an application. It has not been reviewed for security issues,
6however, and we strongly recommend that you use a "real" web server for
7production use.
8
9For example usage, see the 'if __name__=="__main__"' block at the end of the
10module. See also the BaseHTTPServer module docs for other API information.
11"""
12
13from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
14import urllib, sys
15from wsgiref.handlers import SimpleHandler
16
17__version__ = "0.1"
18__all__ = ['WSGIServer', 'WSGIRequestHandler', 'demo_app', 'make_server']
19
20
21server_version = "WSGIServer/" + __version__
22sys_version = "Python/" + sys.version.split()[0]
23software_version = server_version + ' ' + sys_version
24
25
26class ServerHandler(SimpleHandler):
27
28 server_software = software_version
29
30 def close(self):
31 try:
32 self.request_handler.log_request(
33 self.status.split(' ',1)[0], self.bytes_sent
34 )
35 finally:
36 SimpleHandler.close(self)
37
38
39
40
41
42class WSGIServer(HTTPServer):
43
44 """BaseHTTPServer that implements the Python WSGI protocol"""
45
46 application = None
47
48 def server_bind(self):
49 """Override server_bind to store the server name."""
50 HTTPServer.server_bind(self)
51 self.setup_environ()
52
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)
59 env['REMOTE_HOST']=''
60 env['CONTENT_LENGTH']=''
61 env['SCRIPT_NAME'] = ''
62
63 def get_app(self):
64 return self.application
65
66 def set_app(self,application):
67 self.application = application
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83class WSGIRequestHandler(BaseHTTPRequestHandler):
84
85 server_version = "WSGIServer/" + __version__
86
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
91 if '?' in self.path:
92 path,query = self.path.split('?',1)
93 else:
94 path,query = self.path,''
95
96 env['PATH_INFO'] = urllib.unquote(path)
97 env['QUERY_STRING'] = query
98
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]
103
104 if self.headers.typeheader is None:
105 env['CONTENT_TYPE'] = self.headers.type
106 else:
107 env['CONTENT_TYPE'] = self.headers.typeheader
108
109 length = self.headers.getheader('content-length')
110 if length:
111 env['CONTENT_LENGTH'] = length
112
113 for h in self.headers.headers:
114 k,v = h.split(':',1)
115 k=k.replace('-','_').upper(); v=v.strip()
116 if k in env:
117 continue # skip content length, type,etc.
118 if 'HTTP_'+k in env:
119 env['HTTP_'+k] += ','+v # comma-separate multiple headers
120 else:
121 env['HTTP_'+k] = v
122 return env
123
124 def get_stderr(self):
125 return sys.stderr
126
127 def handle(self):
128 """Handle a single HTTP request"""
129
130 self.raw_requestline = self.rfile.readline()
131 if not self.parse_request(): # An error code has been sent, just exit
132 return
133
134 handler = ServerHandler(
135 self.rfile, self.wfile, self.get_stderr(), self.get_environ()
136 )
137 handler.request_handler = self # backpointer for logging
138 handler.run(self.server.get_app())
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165def demo_app(environ,start_response):
Guido van Rossum6a10e022007-08-08 17:01:45 +0000166 from io import StringIO
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000167 stdout = StringIO()
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000168 print("Hello world!", file=stdout)
169 print(file=stdout)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000170 h = environ.items(); h.sort()
171 for k,v in h:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000172 print(k,'=',repr(v), file=stdout)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000173 start_response("200 OK", [('Content-Type','text/plain')])
174 return [stdout.getvalue()]
175
176
177def make_server(
178 host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler
179):
180 """Create a new WSGI server listening on `host` and `port` for `app`"""
181 server = server_class((host, port), handler_class)
182 server.set_app(app)
183 return server
184
185
186if __name__ == '__main__':
187 httpd = make_server('', 8000, demo_app)
188 sa = httpd.socket.getsockname()
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000189 print("Serving HTTP on", sa[0], "port", sa[1], "...")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000190 import webbrowser
191 webbrowser.open('http://localhost:8000/xyz?abc')
192 httpd.handle_request() # serve one request, then exit
193
194
195
196
197
198
199
200
201
202
203
204
205#