annotate Lib/BaseHTTPServer.py @ 6719:faebc1940432 legacy-trunk

Understand -Xlinker option.
author Guido van Rossum <guido@python.org>
date Tue, 02 Dec 1997 20:38:11 +0000
parents 8bba9bb864ae
children fb4b4d069cc7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1 """HTTP server base class.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3 Note: the class in this module doesn't implement any HTTP request; see
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4 SimpleHTTPServer for simple implementations of GET, HEAD and POST
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
5 (including CGI scripts).
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
6
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
7 Contents:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
8
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
9 - BaseHTTPRequestHandler: HTTP request handler base class
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
10 - test: test function
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
11
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
12 XXX To do:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
13
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
14 - send server version
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
15 - log requests even later (to capture byte count)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
16 - log user-agent header and other interesting goodies
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
17 - send error log to separate file
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
18 - are request names really case sensitive?
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
19
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
20 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
21
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
22
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
23 # See also:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
24 #
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
25 # HTTP Working Group T. Berners-Lee
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
26 # INTERNET-DRAFT R. T. Fielding
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
27 # <draft-ietf-http-v10-spec-00.txt> H. Frystyk Nielsen
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
28 # Expires September 8, 1995 March 8, 1995
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
29 #
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
30 # URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
31
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
32
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
33 # Log files
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
34 # ---------
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
35 #
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
36 # Here's a quote from the NCSA httpd docs about log file format.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
37 #
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
38 # | The logfile format is as follows. Each line consists of:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
39 # |
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
40 # | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
41 # |
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
42 # | host: Either the DNS name or the IP number of the remote client
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
43 # | rfc931: Any information returned by identd for this person,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
44 # | - otherwise.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
45 # | authuser: If user sent a userid for authentication, the user name,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
46 # | - otherwise.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
47 # | DD: Day
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
48 # | Mon: Month (calendar name)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
49 # | YYYY: Year
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
50 # | hh: hour (24-hour format, the machine's timezone)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
51 # | mm: minutes
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
52 # | ss: seconds
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
53 # | request: The first line of the HTTP request as sent by the client.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
54 # | ddd: the status code returned by the server, - if not available.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
55 # | bbbb: the total number of bytes sent,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
56 # | *not including the HTTP/1.0 header*, - if not available
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
57 # |
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
58 # | You can determine the name of the file accessed through request.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
59 #
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
60 # (Actually, the latter is only true if you know the server configuration
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
61 # at the time the request was made!)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
62
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
63
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
64 __version__ = "0.2"
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
65
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
66
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
67 import sys
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
68 import time
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
69 import socket # For gethostbyaddr()
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
70 import string
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
71 import rfc822
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
72 import mimetools
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
73 import SocketServer
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
74
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
75 # Default error message
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
76 DEFAULT_ERROR_MESSAGE = """\
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
77 <head>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
78 <title>Error response</title>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
79 </head>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
80 <body>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
81 <h1>Error response</h1>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
82 <p>Error code %(code)d.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
83 <p>Message: %(message)s.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
84 <p>Error code explanation: %(code)s = %(explain)s.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
85 </body>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
86 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
87
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
88
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
89 class HTTPServer(SocketServer.TCPServer):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
90
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
91 def server_bind(self):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
92 """Override server_bind to store the server name."""
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
93 SocketServer.TCPServer.server_bind(self)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
94 host, port = self.socket.getsockname()
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
95 if not host or host == '0.0.0.0':
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
96 host = socket.gethostname()
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
97 hostname, hostnames, hostaddrs = socket.gethostbyaddr(host)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
98 if '.' not in hostname:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
99 for host in hostnames:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
100 if '.' in host:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
101 hostname = host
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
102 break
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
103 self.server_name = hostname
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
104 self.server_port = port
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
105
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
106
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
107 class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
108
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
109 """HTTP request handler base class.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
110
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
111 The following explanation of HTTP serves to guide you through the
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
112 code as well as to expose any misunderstandings I may have about
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
113 HTTP (so you don't need to read the code to figure out I'm wrong
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
114 :-).
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
115
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
116 HTTP (HyperText Transfer Protocol) is an extensible protocol on
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
117 top of a reliable stream transport (e.g. TCP/IP). The protocol
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
118 recognizes three parts to a request:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
119
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
120 1. One line identifying the request type and path
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
121 2. An optional set of RFC-822-style headers
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
122 3. An optional data part
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
123
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
124 The headers and data are separated by a blank line.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
125
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
126 The first line of the request has the form
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
127
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
128 <command> <path> <version>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
129
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
130 where <command> is a (case-sensitive) keyword such as GET or POST,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
131 <path> is a string containing path information for the request,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
132 and <version> should be the string "HTTP/1.0". <path> is encoded
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
133 using the URL encoding scheme (using %xx to signify the ASCII
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
134 character with hex code xx).
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
135
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
136 The protocol is vague about whether lines are separated by LF
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
137 characters or by CRLF pairs -- for compatibility with the widest
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
138 range of clients, both should be accepted. Similarly, whitespace
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
139 in the request line should be treated sensibly (allowing multiple
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
140 spaces between components and allowing trailing whitespace).
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
141
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
142 Similarly, for output, lines ought to be separated by CRLF pairs
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
143 but most clients grok LF characters just fine.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
144
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
145 If the first line of the request has the form
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
146
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
147 <command> <path>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
148
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
149 (i.e. <version> is left out) then this is assumed to be an HTTP
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
150 0.9 request; this form has no optional headers and data part and
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
151 the reply consists of just the data.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
152
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
153 The reply form of the HTTP 1.0 protocol again has three parts:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
154
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
155 1. One line giving the response code
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
156 2. An optional set of RFC-822-style headers
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
157 3. The data
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
158
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
159 Again, the headers and data are separated by a blank line.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
160
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
161 The response code line has the form
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
162
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
163 <version> <responsecode> <responsestring>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
164
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
165 where <version> is the protocol version (always "HTTP/1.0"),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
166 <responsecode> is a 3-digit response code indicating success or
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
167 failure of the request, and <responsestring> is an optional
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
168 human-readable string explaining what the response code means.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
169
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
170 This server parses the request and the headers, and then calls a
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
171 function specific to the request type (<command>). Specifically,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
172 a request SPAM will be handled by a method handle_SPAM(). If no
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
173 such method exists the server sends an error response to the
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
174 client. If it exists, it is called with no arguments:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
175
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
176 do_SPAM()
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
177
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
178 Note that the request name is case sensitive (i.e. SPAM and spam
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
179 are different requests).
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
180
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
181 The various request details are stored in instance variables:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
182
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
183 - client_address is the client IP address in the form (host,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
184 port);
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
185
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
186 - command, path and version are the broken-down request line;
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
187
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
188 - headers is an instance of mimetools.Message (or a derived
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
189 class) containing the header information;
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
190
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
191 - rfile is a file object open for reading positioned at the
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
192 start of the optional input data part;
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
193
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
194 - wfile is a file object open for writing.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
195
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
196 IT IS IMPORTANT TO ADHERE TO THE PROTOCOL FOR WRITING!
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
197
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
198 The first thing to be written must be the response line. Then
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
199 follow 0 or more header lines, then a blank line, and then the
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
200 actual data (if any). The meaning of the header lines depends on
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
201 the command executed by the server; in most cases, when data is
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
202 returned, there should be at least one header line of the form
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
203
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
204 Content-type: <type>/<subtype>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
205
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
206 where <type> and <subtype> should be registered MIME types,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
207 e.g. "text/html" or "text/plain".
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
208
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
209 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
210
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
211 # The Python system version, truncated to its first component.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
212 sys_version = "Python/" + string.split(sys.version)[0]
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
213
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
214 # The server software version. You may want to override this.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
215 # The format is multiple whitespace-separated strings,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
216 # where each string is of the form name[/version].
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
217 server_version = "BaseHTTP/" + __version__
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
218
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
219 def handle(self):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
220 """Handle a single HTTP request.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
221
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
222 You normally don't need to override this method; see the class
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
223 __doc__ string for information on how to handle specific HTTP
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
224 commands such as GET and POST.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
225
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
226 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
227
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
228 self.raw_requestline = self.rfile.readline()
3381
b7b2c13b5e33 fix several bogus var refs in error reporting
Guido van Rossum <guido@python.org>
parents: 2887
diff changeset
229 self.request_version = version = "HTTP/0.9" # Default
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
230 requestline = self.raw_requestline
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
231 if requestline[-2:] == '\r\n':
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
232 requestline = requestline[:-2]
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
233 elif requestline[-1:] == '\n':
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
234 requestline = requestline[:-1]
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
235 self.requestline = requestline
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
236 words = string.split(requestline)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
237 if len(words) == 3:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
238 [command, path, version] = words
5975
8bba9bb864ae Treat all HTTP/1.* versions the same.
Guido van Rossum <guido@python.org>
parents: 3381
diff changeset
239 if version[:5] != 'HTTP/':
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
240 self.send_error(400, "Bad request version (%s)" % `version`)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
241 return
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
242 elif len(words) == 2:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
243 [command, path] = words
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
244 if command != 'GET':
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
245 self.send_error(400,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
246 "Bad HTTP/0.9 request type (%s)" % `command`)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
247 return
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
248 else:
3381
b7b2c13b5e33 fix several bogus var refs in error reporting
Guido van Rossum <guido@python.org>
parents: 2887
diff changeset
249 self.send_error(400, "Bad request syntax (%s)" % `requestline`)
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
250 return
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
251 self.command, self.path, self.request_version = command, path, version
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
252 self.headers = self.MessageClass(self.rfile, 0)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
253 mname = 'do_' + command
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
254 if not hasattr(self, mname):
3381
b7b2c13b5e33 fix several bogus var refs in error reporting
Guido van Rossum <guido@python.org>
parents: 2887
diff changeset
255 self.send_error(501, "Unsupported method (%s)" % `mname`)
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
256 return
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
257 method = getattr(self, mname)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
258 method()
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
259
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
260 def send_error(self, code, message=None):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
261 """Send and log an error reply.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
262
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
263 Arguments are the error code, and a detailed message.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
264 The detailed message defaults to the short entry matching the
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
265 response code.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
266
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
267 This sends an error response (so it must be called before any
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
268 output has been generated), logs the error, and finally sends
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
269 a piece of HTML explaining the error to the user.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
270
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
271 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
272
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
273 try:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
274 short, long = self.responses[code]
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
275 except KeyError:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
276 short, long = '???', '???'
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
277 if not message:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
278 message = short
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
279 explain = long
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
280 self.log_error("code %d, message %s", code, message)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
281 self.send_response(code, message)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
282 self.end_headers()
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
283 self.wfile.write(self.error_message_format %
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
284 {'code': code,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
285 'message': message,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
286 'explain': explain})
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
287
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
288 error_message_format = DEFAULT_ERROR_MESSAGE
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
289
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
290 def send_response(self, code, message=None):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
291 """Send the response header and log the response code.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
292
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
293 Also send two standard headers with the server software
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
294 version and the current date.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
295
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
296 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
297 self.log_request(code)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
298 if message is None:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
299 if self.responses.has_key(code):
5975
8bba9bb864ae Treat all HTTP/1.* versions the same.
Guido van Rossum <guido@python.org>
parents: 3381
diff changeset
300 message = self.responses[code][0]
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
301 else:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
302 message = ''
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
303 if self.request_version != 'HTTP/0.9':
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
304 self.wfile.write("%s %s %s\r\n" %
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
305 (self.protocol_version, str(code), message))
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
306 self.send_header('Server', self.version_string())
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
307 self.send_header('Date', self.date_time_string())
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
308
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
309 def send_header(self, keyword, value):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
310 """Send a MIME header."""
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
311 if self.request_version != 'HTTP/0.9':
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
312 self.wfile.write("%s: %s\r\n" % (keyword, value))
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
313
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
314 def end_headers(self):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
315 """Send the blank line ending the MIME headers."""
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
316 if self.request_version != 'HTTP/0.9':
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
317 self.wfile.write("\r\n")
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
318
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
319 def log_request(self, code='-', size='-'):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
320 """Log an accepted request.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
321
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
322 This is called by send_reponse().
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
323
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
324 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
325
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
326 self.log_message('"%s" %s %s',
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
327 self.requestline, str(code), str(size))
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
328
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
329 def log_error(self, *args):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
330 """Log an error.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
331
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
332 This is called when a request cannot be fulfilled. By
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
333 default it passes the message on to log_message().
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
334
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
335 Arguments are the same as for log_message().
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
336
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
337 XXX This should go to the separate error log.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
338
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
339 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
340
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
341 apply(self.log_message, args)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
342
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
343 def log_message(self, format, *args):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
344 """Log an arbitrary message.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
345
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
346 This is used by all other logging functions. Override
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
347 it if you have specific logging wishes.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
348
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
349 The first argument, FORMAT, is a format string for the
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
350 message to be logged. If the format string contains
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
351 any % escapes requiring parameters, they should be
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
352 specified as subsequent arguments (it's just like
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
353 printf!).
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
354
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
355 The client host and current date/time are prefixed to
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
356 every message.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
357
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
358 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
359
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
360 sys.stderr.write("%s - - [%s] %s\n" %
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
361 (self.address_string(),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
362 self.log_date_time_string(),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
363 format%args))
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
364
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
365 def version_string(self):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
366 """Return the server software version string."""
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
367 return self.server_version + ' ' + self.sys_version
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
368
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
369 def date_time_string(self):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
370 """Return the current date and time formatted for a message header."""
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
371 now = time.time()
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
372 year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
373 s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
374 self.weekdayname[wd],
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
375 day, self.monthname[month], year,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
376 hh, mm, ss)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
377 return s
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
378
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
379 def log_date_time_string(self):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
380 """Return the current time formatted for logging."""
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
381 now = time.time()
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
382 year, month, day, hh, mm, ss, x, y, z = time.localtime(now)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
383 s = "%02d/%3s/%04d %02d:%02d:%02d" % (
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
384 day, self.monthname[month], year, hh, mm, ss)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
385 return s
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
386
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
387 weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
388
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
389 monthname = [None,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
390 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
391 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
392
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
393 def address_string(self):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
394 """Return the client address formatted for logging.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
395
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
396 This version looks up the full hostname using gethostbyaddr(),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
397 and tries to find a name that contains at least one dot.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
398
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
399 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
400
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
401 (host, port) = self.client_address
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
402 try:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
403 name, names, addresses = socket.gethostbyaddr(host)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
404 except socket.error, msg:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
405 return host
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
406 names.insert(0, name)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
407 for name in names:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
408 if '.' in name: return name
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
409 return names[0]
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
410
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
411
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
412 # Essentially static class variables
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
413
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
414 # The version of the HTTP protocol we support.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
415 # Don't override unless you know what you're doing (hint: incoming
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
416 # requests are required to have exactly this version string).
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
417 protocol_version = "HTTP/1.0"
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
418
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
419 # The Message-like class used to parse headers
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
420 MessageClass = mimetools.Message
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
421
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
422 # Table mapping response codes to messages; entries have the
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
423 # form {code: (shortmessage, longmessage)}.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
424 # See http://www.w3.org/hypertext/WWW/Protocols/HTTP/HTRESP.html
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
425 responses = {
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
426 200: ('OK', 'Request fulfilled, document follows'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
427 201: ('Created', 'Document created, URL follows'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
428 202: ('Accepted',
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
429 'Request accepted, processing continues off-line'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
430 203: ('Partial information', 'Request fulfilled from cache'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
431 204: ('No response', 'Request fulfilled, nothing follows'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
432
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
433 301: ('Moved', 'Object moved permanently -- see URI list'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
434 302: ('Found', 'Object moved temporarily -- see URI list'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
435 303: ('Method', 'Object moved -- see Method and URL list'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
436 304: ('Not modified',
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
437 'Document has not changed singe given time'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
438
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
439 400: ('Bad request',
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
440 'Bad request syntax or unsupported method'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
441 401: ('Unauthorized',
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
442 'No permission -- see authorization schemes'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
443 402: ('Payment required',
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
444 'No payment -- see charging schemes'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
445 403: ('Forbidden',
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
446 'Request forbidden -- authorization will not help'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
447 404: ('Not found', 'Nothing matches the given URI'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
448
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
449 500: ('Internal error', 'Server got itself in trouble'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
450 501: ('Not implemented',
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
451 'Server does not support this operation'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
452 502: ('Service temporarily overloaded',
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
453 'The server cannot process the request due to a high load'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
454 503: ('Gateway timeout',
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
455 'The gateway server did not receive a timely response'),
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
456
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
457 }
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
458
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
459
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
460 def test(HandlerClass = BaseHTTPRequestHandler,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
461 ServerClass = HTTPServer):
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
462 """Test the HTTP request handler class.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
463
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
464 This runs an HTTP server on port 8000 (or the first command line
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
465 argument).
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
466
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
467 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
468
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
469 if sys.argv[1:]:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
470 port = string.atoi(sys.argv[1])
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
471 else:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
472 port = 8000
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
473 server_address = ('', port)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
474
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
475 httpd = ServerClass(server_address, HandlerClass)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
476
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
477 print "Serving HTTP on port", port, "..."
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
478 httpd.serve_forever()
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
479
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
480
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
481 if __name__ == '__main__':
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
482 test()