annotate Lib/http/server.py @ 66978:aed2bbafa550 3.1

Blocked revisions 87324 via svnmerge ........ r87324 | r.david.murray | 2010-12-16 14:08:51 -0500 (Thu, 16 Dec 2010) | 9 lines #10719: restore messages generated on invalid compileall args Before the introduction of filename arguments to compileall it gave semi useful messages about not being able to 'list' names that weren't valid directories. This fix restores that behavior. In addition to the test for this case, the patch also adds a test for the default behavior of compileall when no arguments are provided, and fixes a bug in one of the previously added tests. ........
author R. David Murray <rdmurray@bitdance.com>
date Thu, 16 Dec 2010 19:10:16 +0000
parents dc32788f0e4e
children 3c182f71d4c9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1 """HTTP server classes.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
2
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
3 Note: BaseHTTPRequestHandler doesn't implement any HTTP request; see
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
4 SimpleHTTPRequestHandler for simple implementations of GET, HEAD and POST,
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
5 and CGIHTTPRequestHandler for CGI scripts.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
6
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
7 It does, however, optionally implement HTTP/1.1 persistent connections,
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
8 as of version 0.3.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
9
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
10 Notes on CGIHTTPRequestHandler
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
11 ------------------------------
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
12
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
13 This class implements GET and POST requests to cgi-bin scripts.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
14
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
15 If the os.fork() function is not present (e.g. on Windows),
48335
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
16 subprocess.Popen() is used as a fallback, with slightly altered semantics.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
17
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
18 In all cases, the implementation is intentionally naive -- all
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
19 requests are executed synchronously.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
20
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
21 SECURITY WARNING: DON'T USE THIS CODE UNLESS YOU ARE INSIDE A FIREWALL
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
22 -- it may execute arbitrary Python code or external programs.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
23
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
24 Note that status code 200 is sent prior to execution of a CGI script, so
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
25 scripts cannot send other status codes such as 302 (redirect).
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
26
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
27 XXX To do:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
28
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
29 - log requests even later (to capture byte count)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
30 - log user-agent header and other interesting goodies
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
31 - send error log to separate file
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
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 # See also:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
36 #
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
37 # HTTP Working Group T. Berners-Lee
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
38 # INTERNET-DRAFT R. T. Fielding
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
39 # <draft-ietf-http-v10-spec-00.txt> H. Frystyk Nielsen
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
40 # Expires September 8, 1995 March 8, 1995
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 # URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
43 #
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
44 # and
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
45 #
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
46 # Network Working Group R. Fielding
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
47 # Request for Comments: 2616 et al
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
48 # Obsoletes: 2068 June 1999
23075
b7e87732f6ab Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 22830
diff changeset
49 # Category: Standards Track
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
50 #
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
51 # URL: http://www.faqs.org/rfcs/rfc2616.html
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
52
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
53 # Log files
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
54 # ---------
15860
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
55 #
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
56 # Here's a quote from the NCSA httpd docs about log file format.
15860
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
57 #
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
58 # | The logfile format is as follows. Each line consists of:
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
59 # |
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
60 # | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
61 # |
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
62 # | host: Either the DNS name or the IP number of the remote client
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
63 # | rfc931: Any information returned by identd for this person,
15860
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
64 # | - otherwise.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
65 # | authuser: If user sent a userid for authentication, the user name,
15860
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
66 # | - otherwise.
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
67 # | DD: Day
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
68 # | Mon: Month (calendar name)
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
69 # | YYYY: Year
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
70 # | hh: hour (24-hour format, the machine's timezone)
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
71 # | mm: minutes
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
72 # | ss: seconds
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
73 # | request: The first line of the HTTP request as sent by the client.
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
74 # | ddd: the status code returned by the server, - if not available.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
75 # | bbbb: the total number of bytes sent,
15860
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
76 # | *not including the HTTP/1.0 header*, - if not available
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
77 # |
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
78 # | You can determine the name of the file accessed through request.
15860
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
79 #
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
80 # (Actually, the latter is only true if you know the server configuration
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
81 # at the time the request was made!)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
82
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
83 __version__ = "0.6"
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
84
16070
b5345e99596b added __all__ lists to a number of Python modules
Skip Montanaro <skip@pobox.com>
parents: 15860
diff changeset
85 __all__ = ["HTTPServer", "BaseHTTPRequestHandler"]
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
86
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
87 import cgi
47635
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
88 import email.message
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
89 import email.parser
52368
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
90 import http.client
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
91 import io
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
92 import mimetypes
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
93 import os
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
94 import posixpath
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
95 import select
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
96 import shutil
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
97 import socket # For gethostbyaddr()
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
98 import socketserver
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
99 import sys
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
100 import time
10a84c638eda Sort import list.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52367
diff changeset
101 import urllib.parse
65076
945a55d4e73e Merged revisions 85202 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 63443
diff changeset
102 import copy
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
103
45460
58c3f3439670 Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900,60902-60906,60908,60911-60917,60919-60920,60922,60926,60929-60931,60933-60935,60937,60939-60941,60943-60954,60959-60961,60963-60964,60966-60967,60971,60977,60979-60989 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43717
diff changeset
104 # Default error message template
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
105 DEFAULT_ERROR_MESSAGE = """\
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
106 <head>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
107 <title>Error response</title>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
108 </head>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
109 <body>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
110 <h1>Error response</h1>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
111 <p>Error code %(code)d.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
112 <p>Message: %(message)s.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
113 <p>Error code explanation: %(code)s = %(explain)s.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
114 </body>
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
45460
58c3f3439670 Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900,60902-60906,60908,60911-60917,60919-60920,60922,60926,60929-60931,60933-60935,60937,60939-60941,60943-60954,60959-60961,60963-60964,60966-60967,60971,60977,60979-60989 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43717
diff changeset
117 DEFAULT_ERROR_CONTENT_TYPE = "text/html;charset=utf-8"
58c3f3439670 Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900,60902-60906,60908,60911-60917,60919-60920,60922,60926,60929-60931,60933-60935,60937,60939-60941,60943-60954,60959-60961,60963-60964,60966-60967,60971,60977,60979-60989 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43717
diff changeset
118
35151
728a0de88395 backport bug [ 1100201 ] Cross-site scripting on BaseHTTPServer
Georg Brandl <georg@python.org>
parents: 31515
diff changeset
119 def _quote_html(html):
728a0de88395 backport bug [ 1100201 ] Cross-site scripting on BaseHTTPServer
Georg Brandl <georg@python.org>
parents: 31515
diff changeset
120 return html.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
121
46933
aca5c1d1c569 Renamed the SocketServer module to 'socketserver'.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 45460
diff changeset
122 class HTTPServer(socketserver.TCPServer):
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
123
12634
ddf986a971b5 Set HTTPServer class variable allow_reuse_address to 1, so restarting
Guido van Rossum <guido@python.org>
parents: 11409
diff changeset
124 allow_reuse_address = 1 # Seems to make sense in testing environment
ddf986a971b5 Set HTTPServer class variable allow_reuse_address to 1, so restarting
Guido van Rossum <guido@python.org>
parents: 11409
diff changeset
125
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
126 def server_bind(self):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
127 """Override server_bind to store the server name."""
46933
aca5c1d1c569 Renamed the SocketServer module to 'socketserver'.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 45460
diff changeset
128 socketserver.TCPServer.server_bind(self)
29340
c69ad9227afd Patch #744041: Use only first two elements of address to support IPv6.
Martin v. Löwis <martin@v.loewis.de>
parents: 28089
diff changeset
129 host, port = self.socket.getsockname()[:2]
14014
3d68d5bccd40 updated occurences of fqdn algorithm (closes patch #101197)
Peter Schneider-Kamp <nowonder@nowonder.de>
parents: 12634
diff changeset
130 self.server_name = socket.getfqdn(host)
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
131 self.server_port = port
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
132
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
133
46933
aca5c1d1c569 Renamed the SocketServer module to 'socketserver'.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 45460
diff changeset
134 class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
2887
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 """HTTP request handler base class.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
137
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
138 The following explanation of HTTP serves to guide you through the
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
139 code as well as to expose any misunderstandings I may have about
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
140 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
141 :-).
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
142
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
143 HTTP (HyperText Transfer Protocol) is an extensible protocol on
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
144 top of a reliable stream transport (e.g. TCP/IP). The protocol
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
145 recognizes three parts to a request:
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 1. One line identifying the request type and path
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
148 2. An optional set of RFC-822-style headers
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
149 3. An optional data part
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
150
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
151 The headers and data are separated by a blank line.
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 first line of the request has the form
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 <command> <path> <version>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
156
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
157 where <command> is a (case-sensitive) keyword such as GET or POST,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
158 <path> is a string containing path information for the request,
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
159 and <version> should be the string "HTTP/1.0" or "HTTP/1.1".
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
160 <path> is encoded using the URL encoding scheme (using %xx to signify
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
161 the ASCII character with hex code xx).
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
162
27637
601549c64039 Bug #676273: Rewrite paragraph in module docstring
Andrew M. Kuchling <amk@amk.ca>
parents: 23608
diff changeset
163 The specification specifies that lines are separated by CRLF but
601549c64039 Bug #676273: Rewrite paragraph in module docstring
Andrew M. Kuchling <amk@amk.ca>
parents: 23608
diff changeset
164 for compatibility with the widest range of clients recommends
601549c64039 Bug #676273: Rewrite paragraph in module docstring
Andrew M. Kuchling <amk@amk.ca>
parents: 23608
diff changeset
165 servers also handle LF. Similarly, whitespace in the request line
601549c64039 Bug #676273: Rewrite paragraph in module docstring
Andrew M. Kuchling <amk@amk.ca>
parents: 23608
diff changeset
166 is treated sensibly (allowing multiple spaces between components
601549c64039 Bug #676273: Rewrite paragraph in module docstring
Andrew M. Kuchling <amk@amk.ca>
parents: 23608
diff changeset
167 and allowing trailing whitespace).
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
168
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
169 Similarly, for output, lines ought to be separated by CRLF pairs
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
170 but most clients grok LF characters just fine.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
171
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
172 If the first line of the request has the form
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
173
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
174 <command> <path>
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 (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
177 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
178 the reply consists of just the data.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
179
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
180 The reply form of the HTTP 1.x protocol again has three parts:
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
181
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
182 1. One line giving the response code
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
183 2. An optional set of RFC-822-style headers
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
184 3. The data
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 Again, the headers and data are separated by a blank 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 The response code line has the form
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
189
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
190 <version> <responsecode> <responsestring>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
191
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
192 where <version> is the protocol version ("HTTP/1.0" or "HTTP/1.1"),
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
193 <responsecode> is a 3-digit response code indicating success or
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
194 failure of the request, and <responsestring> is an optional
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
195 human-readable string explaining what the response code means.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
196
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
197 This server parses the request and the headers, and then calls a
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
198 function specific to the request type (<command>). Specifically,
11287
f67ce152719a Typo: the method called is do_SPAM, not handle_SPAM.
Guido van Rossum <guido@python.org>
parents: 10939
diff changeset
199 a request SPAM will be handled by a method do_SPAM(). If no
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
200 such method exists the server sends an error response to the
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
201 client. If it exists, it is called with no arguments:
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
202
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
203 do_SPAM()
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
204
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
205 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
206 are different requests).
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
207
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
208 The various request details are stored in instance variables:
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 - client_address is the client IP address in the form (host,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
211 port);
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
212
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
213 - command, path and version are the broken-down request line;
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
214
47635
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
215 - headers is an instance of email.message.Message (or a derived
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
216 class) containing the header information;
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
217
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
218 - rfile is a file object open for reading positioned at the
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
219 start of the optional input data part;
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
220
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
221 - wfile is a file object open for writing.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
222
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
223 IT IS IMPORTANT TO ADHERE TO THE PROTOCOL FOR WRITING!
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
224
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
225 The first thing to be written must be the response line. Then
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
226 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
227 actual data (if any). The meaning of the header lines depends on
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
228 the command executed by the server; in most cases, when data is
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
229 returned, there should be at least one header line of the form
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
230
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
231 Content-type: <type>/<subtype>
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
232
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
233 where <type> and <subtype> should be registered MIME types,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
234 e.g. "text/html" or "text/plain".
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
235
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
236 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
237
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
238 # The Python system version, truncated to its first component.
16479
d59663d3e433 String method conversion.
Eric S. Raymond <esr@thyrsus.com>
parents: 16070
diff changeset
239 sys_version = "Python/" + sys.version.split()[0]
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
240
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
241 # The server software version. You may want to override this.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
242 # The format is multiple whitespace-separated strings,
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
243 # where each string is of the form name[/version].
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
244 server_version = "BaseHTTP/" + __version__
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
245
45460
58c3f3439670 Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900,60902-60906,60908,60911-60917,60919-60920,60922,60926,60929-60931,60933-60935,60937,60939-60941,60943-60954,60959-60961,60963-60964,60966-60967,60971,60977,60979-60989 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43717
diff changeset
246 error_message_format = DEFAULT_ERROR_MESSAGE
58c3f3439670 Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900,60902-60906,60908,60911-60917,60919-60920,60922,60926,60929-60931,60933-60935,60937,60939-60941,60943-60954,60959-60961,60963-60964,60966-60967,60971,60977,60979-60989 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43717
diff changeset
247 error_content_type = DEFAULT_ERROR_CONTENT_TYPE
58c3f3439670 Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900,60902-60906,60908,60911-60917,60919-60920,60922,60926,60929-60931,60933-60935,60937,60939-60941,60943-60954,60959-60961,60963-60964,60966-60967,60971,60977,60979-60989 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43717
diff changeset
248
47278
f762a9ab69dd Merged revisions 63412,63445-63447,63449-63450,63452,63454,63459,63463,63465,63470,63483-63484,63496-63497,63499-63501,63530-63531,63540,63614 via svnmerge from
Georg Brandl <georg@python.org>
parents: 46933
diff changeset
249 # The default request version. This only affects responses up until
f762a9ab69dd Merged revisions 63412,63445-63447,63449-63450,63452,63454,63459,63463,63465,63470,63483-63484,63496-63497,63499-63501,63530-63531,63540,63614 via svnmerge from
Georg Brandl <georg@python.org>
parents: 46933
diff changeset
250 # the point where the request line is parsed, so it mainly decides what
f762a9ab69dd Merged revisions 63412,63445-63447,63449-63450,63452,63454,63459,63463,63465,63470,63483-63484,63496-63497,63499-63501,63530-63531,63540,63614 via svnmerge from
Georg Brandl <georg@python.org>
parents: 46933
diff changeset
251 # the client gets back when sending a malformed request line.
f762a9ab69dd Merged revisions 63412,63445-63447,63449-63450,63452,63454,63459,63463,63465,63470,63483-63484,63496-63497,63499-63501,63530-63531,63540,63614 via svnmerge from
Georg Brandl <georg@python.org>
parents: 46933
diff changeset
252 # Most web servers default to HTTP 0.9, i.e. don't send a status line.
f762a9ab69dd Merged revisions 63412,63445-63447,63449-63450,63452,63454,63459,63463,63465,63470,63483-63484,63496-63497,63499-63501,63530-63531,63540,63614 via svnmerge from
Georg Brandl <georg@python.org>
parents: 46933
diff changeset
253 default_request_version = "HTTP/0.9"
f762a9ab69dd Merged revisions 63412,63445-63447,63449-63450,63452,63454,63459,63463,63465,63470,63483-63484,63496-63497,63499-63501,63530-63531,63540,63614 via svnmerge from
Georg Brandl <georg@python.org>
parents: 46933
diff changeset
254
11409
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
255 def parse_request(self):
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
256 """Parse a request (internal).
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
257
29357
20894dbc7f6a Fix SF bug #747348 docstring mistake in BaseHTTPServer.py. \n\nBackport Candidate
Raymond Hettinger <python@rcn.com>
parents: 29340
diff changeset
258 The request should be stored in self.raw_requestline; the results
11409
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
259 are in self.command, self.path, self.request_version and
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
260 self.headers.
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
261
22830
a9dd5e6d6805 Convert a pile of obvious "yes/no" functions to return bool.
Tim Peters <tim.peters@gmail.com>
parents: 22346
diff changeset
262 Return True for success, False for failure; on failure, an
11409
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
263 error is sent back.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
264
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
265 """
27648
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
266 self.command = None # set in case of error on the first line
47278
f762a9ab69dd Merged revisions 63412,63445-63447,63449-63450,63452,63454,63459,63463,63465,63470,63483-63484,63496-63497,63499-63501,63530-63531,63540,63614 via svnmerge from
Georg Brandl <georg@python.org>
parents: 46933
diff changeset
267 self.request_version = version = self.default_request_version
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
268 self.close_connection = 1
42433
e319d2d285ba Treat HTTP status line as ISO-8859-1 as in httplib module.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 40775
diff changeset
269 requestline = str(self.raw_requestline, 'iso-8859-1')
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
270 if requestline[-2:] == '\r\n':
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
271 requestline = requestline[:-2]
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
272 elif requestline[-1:] == '\n':
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
273 requestline = requestline[:-1]
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
274 self.requestline = requestline
16479
d59663d3e433 String method conversion.
Eric S. Raymond <esr@thyrsus.com>
parents: 16070
diff changeset
275 words = requestline.split()
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
276 if len(words) == 3:
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
277 [command, path, version] = words
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
278 if version[:5] != 'HTTP/':
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30105
diff changeset
279 self.send_error(400, "Bad request version (%r)" % version)
22830
a9dd5e6d6805 Convert a pile of obvious "yes/no" functions to return bool.
Tim Peters <tim.peters@gmail.com>
parents: 22346
diff changeset
280 return False
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
281 try:
27648
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
282 base_version_number = version.split('/', 1)[1]
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
283 version_number = base_version_number.split(".")
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
284 # RFC 2145 section 3.1 says there can be only one "." and
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
285 # - major and minor numbers MUST be treated as
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
286 # separate integers;
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
287 # - HTTP/2.4 is a lower version than HTTP/2.13, which in
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
288 # turn is lower than HTTP/12.3;
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
289 # - Leading zeros MUST be ignored by recipients.
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
290 if len(version_number) != 2:
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
291 raise ValueError
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
292 version_number = int(version_number[0]), int(version_number[1])
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
293 except (ValueError, IndexError):
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30105
diff changeset
294 self.send_error(400, "Bad request version (%r)" % version)
22830
a9dd5e6d6805 Convert a pile of obvious "yes/no" functions to return bool.
Tim Peters <tim.peters@gmail.com>
parents: 22346
diff changeset
295 return False
27648
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
296 if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1":
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
297 self.close_connection = 0
27648
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
298 if version_number >= (2, 0):
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
299 self.send_error(505,
27648
db784d29f481 [Bug #676292] BaseHTTPServer incorrectly parses protocol; fix by Andrew Dalke
Andrew M. Kuchling <amk@amk.ca>
parents: 27637
diff changeset
300 "Invalid HTTP Version (%s)" % base_version_number)
22830
a9dd5e6d6805 Convert a pile of obvious "yes/no" functions to return bool.
Tim Peters <tim.peters@gmail.com>
parents: 22346
diff changeset
301 return False
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
302 elif len(words) == 2:
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
303 [command, path] = words
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
304 self.close_connection = 1
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
305 if command != 'GET':
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
306 self.send_error(400,
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30105
diff changeset
307 "Bad HTTP/0.9 request type (%r)" % command)
22830
a9dd5e6d6805 Convert a pile of obvious "yes/no" functions to return bool.
Tim Peters <tim.peters@gmail.com>
parents: 22346
diff changeset
308 return False
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
309 elif not words:
22830
a9dd5e6d6805 Convert a pile of obvious "yes/no" functions to return bool.
Tim Peters <tim.peters@gmail.com>
parents: 22346
diff changeset
310 return False
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
311 else:
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30105
diff changeset
312 self.send_error(400, "Bad request syntax (%r)" % requestline)
22830
a9dd5e6d6805 Convert a pile of obvious "yes/no" functions to return bool.
Tim Peters <tim.peters@gmail.com>
parents: 22346
diff changeset
313 return False
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
314 self.command, self.path, self.request_version = command, path, version
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
315
42720
eae10d9c9c4e Fixes by John Reese and Jacques Frechet that make test_xmlrpc pass.
Guido van Rossum <guido@python.org>
parents: 42528
diff changeset
316 # Examine the headers and look for a Connection directive.
52369
8d6918af232b Fix compatibility issue with HTTPMessage class.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52368
diff changeset
317 self.headers = http.client.parse_headers(self.rfile,
8d6918af232b Fix compatibility issue with HTTPMessage class.
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 52368
diff changeset
318 _class=self.MessageClass)
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
319
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
320 conntype = self.headers.get('Connection', "")
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
321 if conntype.lower() == 'close':
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
322 self.close_connection = 1
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
323 elif (conntype.lower() == 'keep-alive' and
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
324 self.protocol_version >= "HTTP/1.1"):
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
325 self.close_connection = 0
22830
a9dd5e6d6805 Convert a pile of obvious "yes/no" functions to return bool.
Tim Peters <tim.peters@gmail.com>
parents: 22346
diff changeset
326 return True
11409
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
327
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
328 def handle_one_request(self):
11409
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
329 """Handle a single HTTP request.
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
330
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
331 You normally don't need to override this method; see the class
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
332 __doc__ string for information on how to handle specific HTTP
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
333 commands such as GET and POST.
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
334
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
335 """
66971
dc32788f0e4e Merged revisions 87317 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 65966
diff changeset
336 self.raw_requestline = self.rfile.readline(65537)
dc32788f0e4e Merged revisions 87317 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 65966
diff changeset
337 if len(self.raw_requestline) > 65536:
dc32788f0e4e Merged revisions 87317 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 65966
diff changeset
338 self.requestline = ''
dc32788f0e4e Merged revisions 87317 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 65966
diff changeset
339 self.request_version = ''
dc32788f0e4e Merged revisions 87317 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 65966
diff changeset
340 self.command = ''
dc32788f0e4e Merged revisions 87317 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 65966
diff changeset
341 self.send_error(414)
dc32788f0e4e Merged revisions 87317 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 65966
diff changeset
342 return
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
343 if not self.raw_requestline:
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
344 self.close_connection = 1
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
345 return
11409
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
346 if not self.parse_request(): # An error code has been sent, just exit
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
347 return
061156451d36 Fix by Moshe Zadka (cleaned up and documented by GvR) to break out the
Guido van Rossum <guido@python.org>
parents: 11287
diff changeset
348 mname = 'do_' + self.command
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
349 if not hasattr(self, mname):
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 30105
diff changeset
350 self.send_error(501, "Unsupported method (%r)" % self.command)
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
351 return
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
352 method = getattr(self, mname)
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
353 method()
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
354
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
355 def handle(self):
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
356 """Handle multiple requests if necessary."""
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
357 self.close_connection = 1
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
358
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
359 self.handle_one_request()
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
360 while not self.close_connection:
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
361 self.handle_one_request()
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
362
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
363 def send_error(self, code, message=None):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
364 """Send and log an error reply.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
365
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
366 Arguments are the error code, and a detailed message.
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
367 The detailed message defaults to the short entry matching the
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
368 response code.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
369
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
370 This sends an error response (so it must be called before any
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
371 output has been generated), logs the error, and finally sends
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
372 a piece of HTML explaining the error to the user.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
373
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
374 """
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
375
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
376 try:
40644
1c26505c1de6 Rip out 'long' and 'L'-suffixed integer literals.
Guido van Rossum <guido@python.org>
parents: 40643
diff changeset
377 shortmsg, longmsg = self.responses[code]
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
378 except KeyError:
40644
1c26505c1de6 Rip out 'long' and 'L'-suffixed integer literals.
Guido van Rossum <guido@python.org>
parents: 40643
diff changeset
379 shortmsg, longmsg = '???', '???'
23608
ec27ac19f9e3 Use is None rather than general boolean
Raymond Hettinger <python@rcn.com>
parents: 23075
diff changeset
380 if message is None:
40644
1c26505c1de6 Rip out 'long' and 'L'-suffixed integer literals.
Guido van Rossum <guido@python.org>
parents: 40643
diff changeset
381 message = shortmsg
1c26505c1de6 Rip out 'long' and 'L'-suffixed integer literals.
Guido van Rossum <guido@python.org>
parents: 40643
diff changeset
382 explain = longmsg
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
383 self.log_error("code %d, message %s", code, message)
35151
728a0de88395 backport bug [ 1100201 ] Cross-site scripting on BaseHTTPServer
Georg Brandl <georg@python.org>
parents: 31515
diff changeset
384 # using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201)
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
385 content = (self.error_message_format %
35151
728a0de88395 backport bug [ 1100201 ] Cross-site scripting on BaseHTTPServer
Georg Brandl <georg@python.org>
parents: 31515
diff changeset
386 {'code': code, 'message': _quote_html(message), 'explain': explain})
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
387 self.send_response(code, message)
45460
58c3f3439670 Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900,60902-60906,60908,60911-60917,60919-60920,60922,60926,60929-60931,60933-60935,60937,60939-60941,60943-60954,60959-60961,60963-60964,60966-60967,60971,60977,60979-60989 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 43717
diff changeset
388 self.send_header("Content-Type", self.error_content_type)
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
389 self.send_header('Connection', 'close')
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
390 self.end_headers()
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
391 if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
43717
c1214bd6ed16 make sure to write bytes instead of strings to underlying socket channel
Bill Janssen <janssen@parc.com>
parents: 42720
diff changeset
392 self.wfile.write(content.encode('UTF-8', 'replace'))
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
393
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
394 def send_response(self, code, message=None):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
395 """Send the response header and log the response code.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
396
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
397 Also send two standard headers with the server software
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
398 version and the current date.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
399
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
400 """
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
401 self.log_request(code)
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
402 if message is None:
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
403 if code in self.responses:
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
404 message = self.responses[code][0]
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
405 else:
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
406 message = ''
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
407 if self.request_version != 'HTTP/0.9':
43717
c1214bd6ed16 make sure to write bytes instead of strings to underlying socket channel
Bill Janssen <janssen@parc.com>
parents: 42720
diff changeset
408 self.wfile.write(("%s %d %s\r\n" %
c1214bd6ed16 make sure to write bytes instead of strings to underlying socket channel
Bill Janssen <janssen@parc.com>
parents: 42720
diff changeset
409 (self.protocol_version, code, message)).encode('ASCII', 'strict'))
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
410 # print (self.protocol_version, code, message)
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
411 self.send_header('Server', self.version_string())
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
412 self.send_header('Date', self.date_time_string())
2887
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 def send_header(self, keyword, value):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
415 """Send a MIME header."""
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
416 if self.request_version != 'HTTP/0.9':
43717
c1214bd6ed16 make sure to write bytes instead of strings to underlying socket channel
Bill Janssen <janssen@parc.com>
parents: 42720
diff changeset
417 self.wfile.write(("%s: %s\r\n" % (keyword, value)).encode('ASCII', 'strict'))
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
418
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
419 if keyword.lower() == 'connection':
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
420 if value.lower() == 'close':
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
421 self.close_connection = 1
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
422 elif value.lower() == 'keep-alive':
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
423 self.close_connection = 0
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
424
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
425 def end_headers(self):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
426 """Send the blank line ending the MIME headers."""
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
427 if self.request_version != 'HTTP/0.9':
43717
c1214bd6ed16 make sure to write bytes instead of strings to underlying socket channel
Bill Janssen <janssen@parc.com>
parents: 42720
diff changeset
428 self.wfile.write(b"\r\n")
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
429
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
430 def log_request(self, code='-', size='-'):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
431 """Log an accepted request.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
432
36879
8d41ddc31e61 Typo fix
Andrew M. Kuchling <amk@amk.ca>
parents: 36559
diff changeset
433 This is called by send_response().
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
434
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
435 """
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
436
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
437 self.log_message('"%s" %s %s',
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
438 self.requestline, str(code), str(size))
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
439
40643
47f9efdc0855 Merged revisions 53304-53433,53435-53450 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36879
diff changeset
440 def log_error(self, format, *args):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
441 """Log an error.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
442
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
443 This is called when a request cannot be fulfilled. By
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
444 default it passes the message on to log_message().
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
445
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
446 Arguments are the same as for log_message().
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
447
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
448 XXX This should go to the separate error log.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
449
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
450 """
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
451
40643
47f9efdc0855 Merged revisions 53304-53433,53435-53450 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36879
diff changeset
452 self.log_message(format, *args)
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
453
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
454 def log_message(self, format, *args):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
455 """Log an arbitrary message.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
456
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
457 This is used by all other logging functions. Override
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
458 it if you have specific logging wishes.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
459
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
460 The first argument, FORMAT, is a format string for the
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
461 message to be logged. If the format string contains
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
462 any % escapes requiring parameters, they should be
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
463 specified as subsequent arguments (it's just like
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
464 printf!).
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
465
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
466 The client host and current date/time are prefixed to
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
467 every message.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
468
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
469 """
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
470
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
471 sys.stderr.write("%s - - [%s] %s\n" %
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
472 (self.address_string(),
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
473 self.log_date_time_string(),
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
474 format%args))
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
475
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
476 def version_string(self):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
477 """Return the server software version string."""
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
478 return self.server_version + ' ' + self.sys_version
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
479
36555
4668df450672 Patch #1417555: SimpleHTTPServer now returns Last-Modified headers.
Georg Brandl <georg@python.org>
parents: 35151
diff changeset
480 def date_time_string(self, timestamp=None):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
481 """Return the current date and time formatted for a message header."""
36555
4668df450672 Patch #1417555: SimpleHTTPServer now returns Last-Modified headers.
Georg Brandl <georg@python.org>
parents: 35151
diff changeset
482 if timestamp is None:
4668df450672 Patch #1417555: SimpleHTTPServer now returns Last-Modified headers.
Georg Brandl <georg@python.org>
parents: 35151
diff changeset
483 timestamp = time.time()
4668df450672 Patch #1417555: SimpleHTTPServer now returns Last-Modified headers.
Georg Brandl <georg@python.org>
parents: 35151
diff changeset
484 year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp)
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
485 s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
486 self.weekdayname[wd],
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
487 day, self.monthname[month], year,
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
488 hh, mm, ss)
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
489 return s
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
490
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
491 def log_date_time_string(self):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
492 """Return the current time formatted for logging."""
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
493 now = time.time()
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
494 year, month, day, hh, mm, ss, x, y, z = time.localtime(now)
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
495 s = "%02d/%3s/%04d %02d:%02d:%02d" % (
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
496 day, self.monthname[month], year, hh, mm, ss)
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
497 return s
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
498
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
499 weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
500
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
501 monthname = [None,
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
502 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
503 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
504
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
505 def address_string(self):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
506 """Return the client address formatted for logging.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
507
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
508 This version looks up the full hostname using gethostbyaddr(),
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
509 and tries to find a name that contains at least one dot.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
510
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
511 """
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
512
29340
c69ad9227afd Patch #744041: Use only first two elements of address to support IPv6.
Martin v. Löwis <martin@v.loewis.de>
parents: 28089
diff changeset
513 host, port = self.client_address[:2]
14014
3d68d5bccd40 updated occurences of fqdn algorithm (closes patch #101197)
Peter Schneider-Kamp <nowonder@nowonder.de>
parents: 12634
diff changeset
514 return socket.getfqdn(host)
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
515
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
516 # Essentially static class variables
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
517
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
518 # The version of the HTTP protocol we support.
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
519 # Set this to HTTP/1.1 to enable automatic keepalive
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
520 protocol_version = "HTTP/1.0"
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
521
47635
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
522 # MessageClass used to parse headers
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
523 MessageClass = http.client.HTTPMessage
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
524
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
525 # Table mapping response codes to messages; entries have the
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
526 # form {code: (shortmessage, longmessage)}.
36559
09230357f927 Move "httpresponses" dict from urllib2 to httplib where it belongs.
Georg Brandl <georg@python.org>
parents: 36555
diff changeset
527 # See RFC 2616.
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
528 responses = {
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
529 100: ('Continue', 'Request received, please continue'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
530 101: ('Switching Protocols',
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
531 'Switching to new protocol; obey Upgrade header'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
532
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
533 200: ('OK', 'Request fulfilled, document follows'),
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
534 201: ('Created', 'Document created, URL follows'),
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
535 202: ('Accepted',
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
536 'Request accepted, processing continues off-line'),
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
537 203: ('Non-Authoritative Information', 'Request fulfilled from cache'),
36559
09230357f927 Move "httpresponses" dict from urllib2 to httplib where it belongs.
Georg Brandl <georg@python.org>
parents: 36555
diff changeset
538 204: ('No Content', 'Request fulfilled, nothing follows'),
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
539 205: ('Reset Content', 'Clear input form for further input.'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
540 206: ('Partial Content', 'Partial content follows.'),
15860
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
541
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
542 300: ('Multiple Choices',
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
543 'Object has several resources -- see URI list'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
544 301: ('Moved Permanently', 'Object moved permanently -- see URI list'),
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
545 302: ('Found', 'Object moved temporarily -- see URI list'),
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
546 303: ('See Other', 'Object moved -- see Method and URL list'),
36559
09230357f927 Move "httpresponses" dict from urllib2 to httplib where it belongs.
Georg Brandl <georg@python.org>
parents: 36555
diff changeset
547 304: ('Not Modified',
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
548 'Document has not changed since given time'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
549 305: ('Use Proxy',
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
550 'You must use proxy specified in Location to access this '
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
551 'resource.'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
552 307: ('Temporary Redirect',
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
553 'Object moved temporarily -- see URI list'),
15860
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
554
36559
09230357f927 Move "httpresponses" dict from urllib2 to httplib where it belongs.
Georg Brandl <georg@python.org>
parents: 36555
diff changeset
555 400: ('Bad Request',
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
556 'Bad request syntax or unsupported method'),
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
557 401: ('Unauthorized',
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
558 'No permission -- see authorization schemes'),
36559
09230357f927 Move "httpresponses" dict from urllib2 to httplib where it belongs.
Georg Brandl <georg@python.org>
parents: 36555
diff changeset
559 402: ('Payment Required',
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
560 'No payment -- see charging schemes'),
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
561 403: ('Forbidden',
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
562 'Request forbidden -- authorization will not help'),
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
563 404: ('Not Found', 'Nothing matches the given URI'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
564 405: ('Method Not Allowed',
58996
0369bbaa5d2d Merged revisions 78301 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 57186
diff changeset
565 'Specified method is invalid for this resource.'),
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
566 406: ('Not Acceptable', 'URI not available in preferred format.'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
567 407: ('Proxy Authentication Required', 'You must authenticate with '
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
568 'this proxy before proceeding.'),
36559
09230357f927 Move "httpresponses" dict from urllib2 to httplib where it belongs.
Georg Brandl <georg@python.org>
parents: 36555
diff changeset
569 408: ('Request Timeout', 'Request timed out; try again later.'),
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
570 409: ('Conflict', 'Request conflict.'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
571 410: ('Gone',
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
572 'URI no longer exists and has been permanently removed.'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
573 411: ('Length Required', 'Client must specify Content-Length.'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
574 412: ('Precondition Failed', 'Precondition in headers is false.'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
575 413: ('Request Entity Too Large', 'Entity is too large.'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
576 414: ('Request-URI Too Long', 'URI is too long.'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
577 415: ('Unsupported Media Type', 'Entity body in unsupported format.'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
578 416: ('Requested Range Not Satisfiable',
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
579 'Cannot satisfy request range.'),
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
580 417: ('Expectation Failed',
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
581 'Expect condition could not be satisfied.'),
15860
083a5c75ed90 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 14014
diff changeset
582
36559
09230357f927 Move "httpresponses" dict from urllib2 to httplib where it belongs.
Georg Brandl <georg@python.org>
parents: 36555
diff changeset
583 500: ('Internal Server Error', 'Server got itself in trouble'),
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
584 501: ('Not Implemented',
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
585 'Server does not support this operation'),
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
586 502: ('Bad Gateway', 'Invalid responses from another server/proxy.'),
36559
09230357f927 Move "httpresponses" dict from urllib2 to httplib where it belongs.
Georg Brandl <georg@python.org>
parents: 36555
diff changeset
587 503: ('Service Unavailable',
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
588 'The server cannot process the request due to a high load'),
36559
09230357f927 Move "httpresponses" dict from urllib2 to httplib where it belongs.
Georg Brandl <georg@python.org>
parents: 36555
diff changeset
589 504: ('Gateway Timeout',
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
590 'The gateway server did not receive a timely response'),
36559
09230357f927 Move "httpresponses" dict from urllib2 to httplib where it belongs.
Georg Brandl <georg@python.org>
parents: 36555
diff changeset
591 505: ('HTTP Version Not Supported', 'Cannot fulfill request.'),
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
592 }
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
593
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
594
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
595 class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
596
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
597 """Simple HTTP request handler with GET and HEAD commands.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
598
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
599 This serves files from the current directory and any of its
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
600 subdirectories. The MIME type for files is determined by
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
601 calling the .guess_type() method.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
602
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
603 The GET and HEAD requests are identical except that the HEAD
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
604 request omits the actual contents of the file.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
605
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
606 """
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
607
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
608 server_version = "SimpleHTTP/" + __version__
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
609
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
610 def do_GET(self):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
611 """Serve a GET request."""
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
612 f = self.send_head()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
613 if f:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
614 self.copyfile(f, self.wfile)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
615 f.close()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
616
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
617 def do_HEAD(self):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
618 """Serve a HEAD request."""
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
619 f = self.send_head()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
620 if f:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
621 f.close()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
622
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
623 def send_head(self):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
624 """Common code for GET and HEAD commands.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
625
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
626 This sends the response code and MIME headers.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
627
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
628 Return value is either a file object (which has to be copied
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
629 to the outputfile by the caller unless the command was HEAD,
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
630 and must be closed by the caller under all circumstances), or
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
631 None, in which case the caller has nothing further to do.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
632
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
633 """
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
634 path = self.translate_path(self.path)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
635 f = None
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
636 if os.path.isdir(path):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
637 if not self.path.endswith('/'):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
638 # redirect browser - doing basically what apache does
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
639 self.send_response(301)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
640 self.send_header("Location", self.path + "/")
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
641 self.end_headers()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
642 return None
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
643 for index in "index.html", "index.htm":
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
644 index = os.path.join(path, index)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
645 if os.path.exists(index):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
646 path = index
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
647 break
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
648 else:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
649 return self.list_directory(path)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
650 ctype = self.guess_type(path)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
651 try:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
652 f = open(path, 'rb')
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
653 except IOError:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
654 self.send_error(404, "File not found")
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
655 return None
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
656 self.send_response(200)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
657 self.send_header("Content-type", ctype)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
658 fs = os.fstat(f.fileno())
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
659 self.send_header("Content-Length", str(fs[6]))
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
660 self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
661 self.end_headers()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
662 return f
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
663
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
664 def list_directory(self, path):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
665 """Helper to produce a directory listing (absent index.html).
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
666
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
667 Return value is either a file object, or None (indicating an
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
668 error). In either case, the headers are sent, making the
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
669 interface the same as for send_head().
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
670
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
671 """
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
672 try:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
673 list = os.listdir(path)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
674 except os.error:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
675 self.send_error(404, "No permission to list directory")
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
676 return None
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
677 list.sort(key=lambda a: a.lower())
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
678 r = []
48334
5a416a6417d3 Make a new urllib package .
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 47657
diff changeset
679 displaypath = cgi.escape(urllib.parse.unquote(self.path))
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
680 r.append('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
681 r.append("<html>\n<title>Directory listing for %s</title>\n" % displaypath)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
682 r.append("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
683 r.append("<hr>\n<ul>\n")
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
684 for name in list:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
685 fullname = os.path.join(path, name)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
686 displayname = linkname = name
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
687 # Append / for directories or @ for symbolic links
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
688 if os.path.isdir(fullname):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
689 displayname = name + "/"
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
690 linkname = name + "/"
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
691 if os.path.islink(fullname):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
692 displayname = name + "@"
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
693 # Note: a link to a directory displays with @ and links with /
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
694 r.append('<li><a href="%s">%s</a>\n'
48334
5a416a6417d3 Make a new urllib package .
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 47657
diff changeset
695 % (urllib.parse.quote(linkname), cgi.escape(displayname)))
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
696 r.append("</ul>\n<hr>\n</body>\n</html>\n")
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
697 enc = sys.getfilesystemencoding()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
698 encoded = ''.join(r).encode(enc)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
699 f = io.BytesIO()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
700 f.write(encoded)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
701 f.seek(0)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
702 self.send_response(200)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
703 self.send_header("Content-type", "text/html; charset=%s" % enc)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
704 self.send_header("Content-Length", str(len(encoded)))
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
705 self.end_headers()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
706 return f
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
707
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
708 def translate_path(self, path):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
709 """Translate a /-separated PATH to the local filename syntax.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
710
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
711 Components that mean special things to the local file system
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
712 (e.g. drive or directory names) are ignored. (XXX They should
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
713 probably be diagnosed.)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
714
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
715 """
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
716 # abandon query parameters
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
717 path = path.split('?',1)[0]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
718 path = path.split('#',1)[0]
48334
5a416a6417d3 Make a new urllib package .
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 47657
diff changeset
719 path = posixpath.normpath(urllib.parse.unquote(path))
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
720 words = path.split('/')
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
721 words = filter(None, words)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
722 path = os.getcwd()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
723 for word in words:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
724 drive, word = os.path.splitdrive(word)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
725 head, word = os.path.split(word)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
726 if word in (os.curdir, os.pardir): continue
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
727 path = os.path.join(path, word)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
728 return path
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
729
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
730 def copyfile(self, source, outputfile):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
731 """Copy all data between two file objects.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
732
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
733 The SOURCE argument is a file object open for reading
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
734 (or anything with a read() method) and the DESTINATION
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
735 argument is a file object open for writing (or
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
736 anything with a write() method).
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
737
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
738 The only reason for overriding this would be to change
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
739 the block size or perhaps to replace newlines by CRLF
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
740 -- note however that this the default server uses this
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
741 to copy binary data as well.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
742
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
743 """
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
744 shutil.copyfileobj(source, outputfile)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
745
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
746 def guess_type(self, path):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
747 """Guess the type of a file.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
748
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
749 Argument is a PATH (a filename).
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
750
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
751 Return value is a string of the form type/subtype,
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
752 usable for a MIME Content-type header.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
753
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
754 The default implementation looks the file's extension
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
755 up in the table self.extensions_map, using application/octet-stream
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
756 as a default; however it would be permissible (if
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
757 slow) to look inside the data to make a better guess.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
758
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
759 """
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
760
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
761 base, ext = posixpath.splitext(path)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
762 if ext in self.extensions_map:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
763 return self.extensions_map[ext]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
764 ext = ext.lower()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
765 if ext in self.extensions_map:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
766 return self.extensions_map[ext]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
767 else:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
768 return self.extensions_map['']
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
769
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
770 if not mimetypes.inited:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
771 mimetypes.init() # try to read system mime.types
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
772 extensions_map = mimetypes.types_map.copy()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
773 extensions_map.update({
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
774 '': 'application/octet-stream', # Default
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
775 '.py': 'text/plain',
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
776 '.c': 'text/plain',
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
777 '.h': 'text/plain',
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
778 })
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
779
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
780
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
781 # Utilities for CGIHTTPRequestHandler
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
782
53073
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
783 # TODO(gregory.p.smith): Move this into an appropriate library.
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
784 def _url_collapse_path_split(path):
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
785 """
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
786 Given a URL path, remove extra '/'s and '.' path elements and collapse
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
787 any '..' references.
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
788
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
789 Implements something akin to RFC-2396 5.2 step 6 to parse relative paths.
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
790
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
791 Returns: A tuple of (head, tail) where tail is everything after the final /
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
792 and head is everything before it. Head will always start with a '/' and,
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
793 if it contains anything else, never have a trailing '/'.
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
794
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
795 Raises: IndexError if too many '..' occur within the path.
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
796 """
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
797 # Similar to os.path.split(os.path.normpath(path)) but specific to URL
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
798 # path semantics rather than local operating system semantics.
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
799 path_parts = []
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
800 for part in path.split('/'):
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
801 if part == '.':
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
802 path_parts.append('')
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
803 else:
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
804 path_parts.append(part)
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
805 # Filter out blank non trailing parts before consuming the '..'.
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
806 path_parts = [part for part in path_parts[:-1] if part] + path_parts[-1:]
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
807 if path_parts:
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
808 tail_part = path_parts.pop()
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
809 else:
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
810 tail_part = ''
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
811 head_parts = []
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
812 for part in path_parts:
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
813 if part == '..':
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
814 head_parts.pop()
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
815 else:
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
816 head_parts.append(part)
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
817 if tail_part and tail_part == '..':
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
818 head_parts.pop()
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
819 tail_part = ''
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
820 return ('/' + '/'.join(head_parts), tail_part)
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
821
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
822
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
823 nobody = None
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
824
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
825 def nobody_uid():
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
826 """Internal routine to get nobody's uid"""
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
827 global nobody
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
828 if nobody:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
829 return nobody
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
830 try:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
831 import pwd
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
832 except ImportError:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
833 return -1
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
834 try:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
835 nobody = pwd.getpwnam('nobody')[2]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
836 except KeyError:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
837 nobody = 1 + max(map(lambda x: x[2], pwd.getpwall()))
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
838 return nobody
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
839
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
840
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
841 def executable(path):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
842 """Test for executable file."""
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
843 try:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
844 st = os.stat(path)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
845 except os.error:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
846 return False
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
847 return st.st_mode & 0o111 != 0
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
848
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
849
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
850 class CGIHTTPRequestHandler(SimpleHTTPRequestHandler):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
851
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
852 """Complete HTTP server with GET, HEAD and POST commands.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
853
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
854 GET and HEAD also support running CGI scripts.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
855
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
856 The POST command is *only* implemented for CGI scripts.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
857
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
858 """
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
859
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
860 # Determine platform specifics
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
861 have_fork = hasattr(os, 'fork')
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
862
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
863 # Make rfile unbuffered -- we need to read one line and then pass
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
864 # the rest to a subprocess, so we can't use buffered input.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
865 rbufsize = 0
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
866
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
867 def do_POST(self):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
868 """Serve a POST request.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
869
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
870 This is only implemented for CGI scripts.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
871
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
872 """
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
873
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
874 if self.is_cgi():
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
875 self.run_cgi()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
876 else:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
877 self.send_error(501, "Can only POST to CGI scripts")
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
878
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
879 def send_head(self):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
880 """Version of send_head that support CGI scripts"""
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
881 if self.is_cgi():
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
882 return self.run_cgi()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
883 else:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
884 return SimpleHTTPRequestHandler.send_head(self)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
885
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
886 def is_cgi(self):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
887 """Test whether self.path corresponds to a CGI script.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
888
53073
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
889 Returns True and updates the cgi_info attribute to the tuple
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
890 (dir, rest) if self.path requires running a CGI script.
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
891 Returns False otherwise.
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
892
53921
cb7be63b91d8 port r72246
Benjamin Peterson <benjamin@python.org>
parents: 53073
diff changeset
893 If any exception is raised, the caller should assume that
cb7be63b91d8 port r72246
Benjamin Peterson <benjamin@python.org>
parents: 53073
diff changeset
894 self.path was rejected as invalid and act accordingly.
cb7be63b91d8 port r72246
Benjamin Peterson <benjamin@python.org>
parents: 53073
diff changeset
895
53073
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
896 The default implementation tests whether the normalized url
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
897 path begins with one of the strings in self.cgi_directories
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
898 (and the next character is a '/' or the end of the string).
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
899
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
900 """
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
901
53073
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
902 splitpath = _url_collapse_path_split(self.path)
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
903 if splitpath[0] in self.cgi_directories:
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
904 self.cgi_info = splitpath
3b1b6142690a Merged revisions 71303 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 52770
diff changeset
905 return True
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
906 return False
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
907
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
908 cgi_directories = ['/cgi-bin', '/htbin']
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
909
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
910 def is_executable(self, path):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
911 """Test whether argument path is an executable file."""
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
912 return executable(path)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
913
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
914 def is_python(self, path):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
915 """Test whether argument path is a Python script."""
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
916 head, tail = os.path.splitext(path)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
917 return tail.lower() in (".py", ".pyw")
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
918
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
919 def run_cgi(self):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
920 """Execute a CGI script."""
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
921 path = self.path
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
922 dir, rest = self.cgi_info
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
923
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
924 i = path.find('/', len(dir) + 1)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
925 while i >= 0:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
926 nextdir = path[:i]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
927 nextrest = path[i+1:]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
928
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
929 scriptdir = self.translate_path(nextdir)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
930 if os.path.isdir(scriptdir):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
931 dir, rest = nextdir, nextrest
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
932 i = path.find('/', len(dir) + 1)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
933 else:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
934 break
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
935
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
936 # find an explicit query string, if present.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
937 i = rest.rfind('?')
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
938 if i >= 0:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
939 rest, query = rest[:i], rest[i+1:]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
940 else:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
941 query = ''
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
942
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
943 # dissect the part after the directory name into a script name &
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
944 # a possible additional path, to be stored in PATH_INFO.
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
945 i = rest.find('/')
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
946 if i >= 0:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
947 script, rest = rest[:i], rest[i:]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
948 else:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
949 script, rest = rest, ''
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
950
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
951 scriptname = dir + '/' + script
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
952 scriptfile = self.translate_path(scriptname)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
953 if not os.path.exists(scriptfile):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
954 self.send_error(404, "No such CGI script (%r)" % scriptname)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
955 return
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
956 if not os.path.isfile(scriptfile):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
957 self.send_error(403, "CGI script is not a plain file (%r)" %
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
958 scriptname)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
959 return
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
960 ispy = self.is_python(scriptname)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
961 if not ispy:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
962 if not self.is_executable(scriptfile):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
963 self.send_error(403, "CGI script is not executable (%r)" %
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
964 scriptname)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
965 return
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
966
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
967 # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
968 # XXX Much of the following could be prepared ahead of time!
65076
945a55d4e73e Merged revisions 85202 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 63443
diff changeset
969 env = copy.deepcopy(os.environ)
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
970 env['SERVER_SOFTWARE'] = self.version_string()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
971 env['SERVER_NAME'] = self.server.server_name
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
972 env['GATEWAY_INTERFACE'] = 'CGI/1.1'
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
973 env['SERVER_PROTOCOL'] = self.protocol_version
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
974 env['SERVER_PORT'] = str(self.server.server_port)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
975 env['REQUEST_METHOD'] = self.command
48334
5a416a6417d3 Make a new urllib package .
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 47657
diff changeset
976 uqrest = urllib.parse.unquote(rest)
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
977 env['PATH_INFO'] = uqrest
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
978 env['PATH_TRANSLATED'] = self.translate_path(uqrest)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
979 env['SCRIPT_NAME'] = scriptname
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
980 if query:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
981 env['QUERY_STRING'] = query
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
982 host = self.address_string()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
983 if host != self.client_address[0]:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
984 env['REMOTE_HOST'] = host
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
985 env['REMOTE_ADDR'] = self.client_address[0]
47635
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
986 authorization = self.headers.get("authorization")
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
987 if authorization:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
988 authorization = authorization.split()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
989 if len(authorization) == 2:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
990 import base64, binascii
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
991 env['AUTH_TYPE'] = authorization[0]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
992 if authorization[0].lower() == "basic":
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
993 try:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
994 authorization = authorization[1].encode('ascii')
54568
031b963f2bc2 More codestring -> codebytes.
Georg Brandl <georg@python.org>
parents: 53921
diff changeset
995 authorization = base64.decodebytes(authorization).\
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
996 decode('ascii')
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
997 except (binascii.Error, UnicodeError):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
998 pass
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
999 else:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1000 authorization = authorization.split(':')
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1001 if len(authorization) == 2:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1002 env['REMOTE_USER'] = authorization[0]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1003 # XXX REMOTE_IDENT
47635
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
1004 if self.headers.get('content-type') is None:
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
1005 env['CONTENT_TYPE'] = self.headers.get_content_type()
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1006 else:
47635
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
1007 env['CONTENT_TYPE'] = self.headers['content-type']
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
1008 length = self.headers.get('content-length')
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1009 if length:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1010 env['CONTENT_LENGTH'] = length
47635
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
1011 referer = self.headers.get('referer')
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1012 if referer:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1013 env['HTTP_REFERER'] = referer
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1014 accept = []
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1015 for line in self.headers.getallmatchingheaders('accept'):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1016 if line[:1] in "\t\n\r ":
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1017 accept.append(line.strip())
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1018 else:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1019 accept = accept + line[7:].split(',')
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1020 env['HTTP_ACCEPT'] = ','.join(accept)
47635
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
1021 ua = self.headers.get('user-agent')
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1022 if ua:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1023 env['HTTP_USER_AGENT'] = ua
47635
f31e32a2013c Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
Barry Warsaw <barry@python.org>
parents: 47318
diff changeset
1024 co = filter(None, self.headers.get_all('cookie', []))
63443
93b3ae63d2f3 Merged revisions 83371,83390 via svnmerge from
Georg Brandl <georg@python.org>
parents: 58996
diff changeset
1025 cookie_str = ', '.join(co)
93b3ae63d2f3 Merged revisions 83371,83390 via svnmerge from
Georg Brandl <georg@python.org>
parents: 58996
diff changeset
1026 if cookie_str:
93b3ae63d2f3 Merged revisions 83371,83390 via svnmerge from
Georg Brandl <georg@python.org>
parents: 58996
diff changeset
1027 env['HTTP_COOKIE'] = cookie_str
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1028 # XXX Other HTTP_* headers
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1029 # Since we're setting the env in the parent, provide empty
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1030 # values to override previously set values
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1031 for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1032 'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1033 env.setdefault(k, "")
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1034
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1035 self.send_response(200, "Script output follows")
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1036
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1037 decoded_query = query.replace('+', ' ')
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1038
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1039 if self.have_fork:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1040 # Unix -- fork as we should
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1041 args = [script]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1042 if '=' not in decoded_query:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1043 args.append(decoded_query)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1044 nobody = nobody_uid()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1045 self.wfile.flush() # Always flush before forking
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1046 pid = os.fork()
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1047 if pid != 0:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1048 # Parent
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1049 pid, sts = os.waitpid(pid, 0)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1050 # throw away additional data [see bug #427345]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1051 while select.select([self.rfile], [], [], 0)[0]:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1052 if not self.rfile.read(1):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1053 break
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1054 if sts:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1055 self.log_error("CGI script exit status %#x", sts)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1056 return
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1057 # Child
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1058 try:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1059 try:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1060 os.setuid(nobody)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1061 except os.error:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1062 pass
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1063 os.dup2(self.rfile.fileno(), 0)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1064 os.dup2(self.wfile.fileno(), 1)
65076
945a55d4e73e Merged revisions 85202 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 63443
diff changeset
1065 os.execve(scriptfile, args, env)
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1066 except:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1067 self.server.handle_error(self.request, self.client_address)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1068 os._exit(127)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1069
48335
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1070 else:
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1071 # Non-Unix -- use subprocess
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1072 import subprocess
57186
c85eb5946614 Merged revisions 76210 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 54568
diff changeset
1073 cmdline = [scriptfile]
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1074 if self.is_python(scriptfile):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1075 interp = sys.executable
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1076 if interp.lower().endswith("w.exe"):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1077 # On Windows, use python.exe, not pythonw.exe
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1078 interp = interp[:-5] + interp[-4:]
57186
c85eb5946614 Merged revisions 76210 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 54568
diff changeset
1079 cmdline = [interp, '-u'] + cmdline
c85eb5946614 Merged revisions 76210 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 54568
diff changeset
1080 if '=' not in query:
c85eb5946614 Merged revisions 76210 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 54568
diff changeset
1081 cmdline.append(query)
c85eb5946614 Merged revisions 76210 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 54568
diff changeset
1082 self.log_message("command: %s", subprocess.list2cmdline(cmdline))
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1083 try:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1084 nbytes = int(length)
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1085 except (TypeError, ValueError):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1086 nbytes = 0
48335
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1087 p = subprocess.Popen(cmdline,
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1088 stdin=subprocess.PIPE,
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1089 stdout=subprocess.PIPE,
65076
945a55d4e73e Merged revisions 85202 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 63443
diff changeset
1090 stderr=subprocess.PIPE,
945a55d4e73e Merged revisions 85202 via svnmerge from
Senthil Kumaran <orsenthil@gmail.com>
parents: 63443
diff changeset
1091 env = env
48335
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1092 )
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1093 if self.command.lower() == "post" and nbytes > 0:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1094 data = self.rfile.read(nbytes)
48335
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1095 else:
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1096 data = None
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1097 # throw away additional data [see bug #427345]
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1098 while select.select([self.rfile._sock], [], [], 0)[0]:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1099 if not self.rfile._sock.recv(1):
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1100 break
48335
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1101 stdout, stderr = p.communicate(data)
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1102 self.wfile.write(stdout)
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1103 if stderr:
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1104 self.log_error('%s', stderr)
65966
1243ec679c29 Merged revisions 86195 via svnmerge from
Brian Curtin <brian.curtin@gmail.com>
parents: 65076
diff changeset
1105 p.stderr.close()
1243ec679c29 Merged revisions 86195 via svnmerge from
Brian Curtin <brian.curtin@gmail.com>
parents: 65076
diff changeset
1106 p.stdout.close()
48335
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1107 status = p.returncode
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1108 if status:
69040092b8f8 Issue3113: tests for CGIHTTPRequestHandler failed on windows:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 48334
diff changeset
1109 self.log_error("CGI script exit status %#x", status)
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1110 else:
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1111 self.log_message("CGI script exited OK")
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1112
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1113
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1114 def test(HandlerClass = BaseHTTPRequestHandler,
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
1115 ServerClass = HTTPServer, protocol="HTTP/1.0"):
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1116 """Test the HTTP request handler class.
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1117
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1118 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
1119 argument).
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1120
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1121 """
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1122
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1123 if sys.argv[1:]:
16482
1fb7befb59f0 Correction to test main.
Eric S. Raymond <esr@thyrsus.com>
parents: 16479
diff changeset
1124 port = int(sys.argv[1])
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1125 else:
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 5975
diff changeset
1126 port = 8000
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1127 server_address = ('', port)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1128
22346
27f36f4bf525 Patch #430706: Persistent connections in BaseHTTPServer.
Martin v. Löwis <martin@v.loewis.de>
parents: 22182
diff changeset
1129 HandlerClass.protocol_version = protocol
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1130 httpd = ServerClass(server_address, HandlerClass)
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1131
18825
40900620293e Patch #401196: Use getaddrinfo and AF_INET6 in TCP servers and clients.
Martin v. Löwis <martin@v.loewis.de>
parents: 16482
diff changeset
1132 sa = httpd.socket.getsockname()
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1133 print("Serving HTTP on", sa[0], "port", sa[1], "...")
52770
4757ddaa897d Make http.server main program nicer for interactive use.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 52369
diff changeset
1134 try:
4757ddaa897d Make http.server main program nicer for interactive use.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 52369
diff changeset
1135 httpd.serve_forever()
4757ddaa897d Make http.server main program nicer for interactive use.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 52369
diff changeset
1136 except KeyboardInterrupt:
4757ddaa897d Make http.server main program nicer for interactive use.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 52369
diff changeset
1137 print("\nKeyboard interrupt received, exiting.")
4757ddaa897d Make http.server main program nicer for interactive use.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 52369
diff changeset
1138 httpd.server_close()
4757ddaa897d Make http.server main program nicer for interactive use.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 52369
diff changeset
1139 sys.exit(0)
2887
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1140
ec0b42889243 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1141 if __name__ == '__main__':
47318
e1fcc3881cb6 Create http package. #2883.
Georg Brandl <georg@python.org>
parents: 47278
diff changeset
1142 test(HandlerClass=SimpleHTTPRequestHandler)