Back to index

python3.2  3.2.2
Public Member Functions | Public Attributes | Static Public Attributes
http.server.CGIHTTPRequestHandler Class Reference
Inheritance diagram for http.server.CGIHTTPRequestHandler:
Inheritance graph
[legend]
Collaboration diagram for http.server.CGIHTTPRequestHandler:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def do_POST
def send_head
def is_cgi
def is_executable
def is_python
def run_cgi
def do_GET
def do_HEAD
def list_directory
def translate_path
def copyfile
def guess_type
def parse_request
def handle_expect_100
def handle_one_request
def handle
def send_error
def send_response
def send_response_only
def send_header
def end_headers
def log_request
def log_error
def log_message
def version_string
def date_time_string
def log_date_time_string
def address_string
def setup
def finish

Public Attributes

 cgi_info
 command
 request_version
 close_connection
 requestline
 headers
 raw_requestline
 connection
 rfile
 wfile
 request
 client_address
 server

Static Public Attributes

tuple have_fork = hasattr(os, 'fork')
int rbufsize = 0
list cgi_directories = ['/cgi-bin', '/htbin']
string server_version = "SimpleHTTP/"
tuple extensions_map = mimetypes.types_map.copy()
string sys_version = "Python/"
 error_message_format = DEFAULT_ERROR_MESSAGE
 error_content_type = DEFAULT_ERROR_CONTENT_TYPE
string default_request_version = "HTTP/0.9"
list weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
list monthname
string protocol_version = "HTTP/1.0"
 MessageClass = http.client.HTTPMessage
dictionary responses
int wbufsize = 0
 timeout = None
 disable_nagle_algorithm = False

Detailed Description

Complete HTTP server with GET, HEAD and POST commands.

GET and HEAD also support running CGI scripts.

The POST command is *only* implemented for CGI scripts.

Definition at line 898 of file server.py.


Member Function Documentation

Return the client address formatted for logging.

This version looks up the full hostname using gethostbyaddr(),
and tries to find a name that contains at least one dot.

Definition at line 553 of file server.py.

00553 
00554     def address_string(self):
00555         """Return the client address formatted for logging.
00556 
00557         This version looks up the full hostname using gethostbyaddr(),
00558         and tries to find a name that contains at least one dot.
00559 
00560         """
00561 
00562         host, port = self.client_address[:2]
00563         return socket.getfqdn(host)

Here is the call graph for this function:

Here is the caller graph for this function:

def http.server.SimpleHTTPRequestHandler.copyfile (   self,
  source,
  outputfile 
) [inherited]
Copy all data between two file objects.

The SOURCE argument is a file object open for reading
(or anything with a read() method) and the DESTINATION
argument is a file object open for writing (or
anything with a write() method).

The only reason for overriding this would be to change
the block size or perhaps to replace newlines by CRLF
-- note however that this the default server uses this
to copy binary data as well.

Definition at line 778 of file server.py.

00778 
00779     def copyfile(self, source, outputfile):
00780         """Copy all data between two file objects.
00781 
00782         The SOURCE argument is a file object open for reading
00783         (or anything with a read() method) and the DESTINATION
00784         argument is a file object open for writing (or
00785         anything with a write() method).
00786 
00787         The only reason for overriding this would be to change
00788         the block size or perhaps to replace newlines by CRLF
00789         -- note however that this the default server uses this
00790         to copy binary data as well.
00791 
00792         """
00793         shutil.copyfileobj(source, outputfile)

Here is the call graph for this function:

Here is the caller graph for this function:

def http.server.BaseHTTPRequestHandler.date_time_string (   self,
  timestamp = None 
) [inherited]
Return the current date and time formatted for a message header.

Definition at line 528 of file server.py.

00528 
00529     def date_time_string(self, timestamp=None):
00530         """Return the current date and time formatted for a message header."""
00531         if timestamp is None:
00532             timestamp = time.time()
00533         year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp)
00534         s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
00535                 self.weekdayname[wd],
00536                 day, self.monthname[month], year,
00537                 hh, mm, ss)
00538         return s

Here is the caller graph for this function:

def http.server.SimpleHTTPRequestHandler.do_GET (   self) [inherited]
Serve a GET request.

Definition at line 658 of file server.py.

00658 
00659     def do_GET(self):
00660         """Serve a GET request."""
00661         f = self.send_head()
00662         if f:
00663             self.copyfile(f, self.wfile)
00664             f.close()

Here is the call graph for this function:

Here is the caller graph for this function:

Serve a HEAD request.

Definition at line 665 of file server.py.

00665 
00666     def do_HEAD(self):
00667         """Serve a HEAD request."""
00668         f = self.send_head()
00669         if f:
00670             f.close()

Here is the call graph for this function:

Serve a POST request.

This is only implemented for CGI scripts.

Definition at line 915 of file server.py.

00915 
00916     def do_POST(self):
00917         """Serve a POST request.
00918 
00919         This is only implemented for CGI scripts.
00920 
00921         """
00922 
00923         if self.is_cgi():
00924             self.run_cgi()
00925         else:
00926             self.send_error(501, "Can only POST to CGI scripts")

Here is the call graph for this function:

Send the blank line ending the MIME headers.

Definition at line 471 of file server.py.

00471 
00472     def end_headers(self):
00473         """Send the blank line ending the MIME headers."""
00474         if self.request_version != 'HTTP/0.9':
00475             self._headers_buffer.append(b"\r\n")
00476             self.wfile.write(b"".join(self._headers_buffer))
00477             self._headers_buffer = []

Here is the caller graph for this function:

def socketserver.StreamRequestHandler.finish (   self) [inherited]

Reimplemented from socketserver.BaseRequestHandler.

Reimplemented in test.test_wsgiref.MockHandler.

Definition at line 691 of file socketserver.py.

00691 
00692     def finish(self):
00693         if not self.wfile.closed:
00694             self.wfile.flush()
00695         self.wfile.close()
00696         self.rfile.close()
00697 

Here is the caller graph for this function:

def http.server.SimpleHTTPRequestHandler.guess_type (   self,
  path 
) [inherited]
Guess the type of a file.

Argument is a PATH (a filename).

Return value is a string of the form type/subtype,
usable for a MIME Content-type header.

The default implementation looks the file's extension
up in the table self.extensions_map, using application/octet-stream
as a default; however it would be permissible (if
slow) to look inside the data to make a better guess.

Definition at line 794 of file server.py.

00794 
00795     def guess_type(self, path):
00796         """Guess the type of a file.
00797 
00798         Argument is a PATH (a filename).
00799 
00800         Return value is a string of the form type/subtype,
00801         usable for a MIME Content-type header.
00802 
00803         The default implementation looks the file's extension
00804         up in the table self.extensions_map, using application/octet-stream
00805         as a default; however it would be permissible (if
00806         slow) to look inside the data to make a better guess.
00807 
00808         """
00809 
00810         base, ext = posixpath.splitext(path)
00811         if ext in self.extensions_map:
00812             return self.extensions_map[ext]
00813         ext = ext.lower()
00814         if ext in self.extensions_map:
00815             return self.extensions_map[ext]
00816         else:
00817             return self.extensions_map['']

Here is the call graph for this function:

Here is the caller graph for this function:

def http.server.BaseHTTPRequestHandler.handle (   self) [inherited]
Handle multiple requests if necessary.

Reimplemented from socketserver.BaseRequestHandler.

Reimplemented in test.test_xmlrpc.BaseKeepaliveServerTestCase.RequestHandler, and wsgiref.simple_server.WSGIRequestHandler.

Definition at line 395 of file server.py.

00395 
00396     def handle(self):
00397         """Handle multiple requests if necessary."""
00398         self.close_connection = 1
00399 
00400         self.handle_one_request()
00401         while not self.close_connection:
00402             self.handle_one_request()

Here is the call graph for this function:

Here is the caller graph for this function:

Decide what to do with an "Expect: 100-continue" header.

If the client is expecting a 100 Continue response, we must
respond with either a 100 Continue or a final response before
waiting for the request body. The default is to always respond
with a 100 Continue. You can behave differently (for example,
reject unauthorized requests) by overriding this method.

This method should either return True (possibly after sending
a 100 Continue response) or send an error response and return
False.

Definition at line 343 of file server.py.

00343 
00344     def handle_expect_100(self):
00345         """Decide what to do with an "Expect: 100-continue" header.
00346 
00347         If the client is expecting a 100 Continue response, we must
00348         respond with either a 100 Continue or a final response before
00349         waiting for the request body. The default is to always respond
00350         with a 100 Continue. You can behave differently (for example,
00351         reject unauthorized requests) by overriding this method.
00352 
00353         This method should either return True (possibly after sending
00354         a 100 Continue response) or send an error response and return
00355         False.
00356 
00357         """
00358         self.send_response_only(100)
00359         return True

Here is the call graph for this function:

Handle a single HTTP request.

You normally don't need to override this method; see the class
__doc__ string for information on how to handle specific HTTP
commands such as GET and POST.

Reimplemented in test.test_xmlrpc.BaseKeepaliveServerTestCase.RequestHandler.

Definition at line 360 of file server.py.

00360 
00361     def handle_one_request(self):
00362         """Handle a single HTTP request.
00363 
00364         You normally don't need to override this method; see the class
00365         __doc__ string for information on how to handle specific HTTP
00366         commands such as GET and POST.
00367 
00368         """
00369         try:
00370             self.raw_requestline = self.rfile.readline(65537)
00371             if len(self.raw_requestline) > 65536:
00372                 self.requestline = ''
00373                 self.request_version = ''
00374                 self.command = ''
00375                 self.send_error(414)
00376                 return
00377             if not self.raw_requestline:
00378                 self.close_connection = 1
00379                 return
00380             if not self.parse_request():
00381                 # An error code has been sent, just exit
00382                 return
00383             mname = 'do_' + self.command
00384             if not hasattr(self, mname):
00385                 self.send_error(501, "Unsupported method (%r)" % self.command)
00386                 return
00387             method = getattr(self, mname)
00388             method()
00389             self.wfile.flush() #actually send the response if not already done.
00390         except socket.timeout as e:
00391             #a read or a write timed out.  Discard this connection
00392             self.log_error("Request timed out: %r", e)
00393             self.close_connection = 1
00394             return

Here is the caller graph for this function:

Test whether self.path corresponds to a CGI script.

Returns True and updates the cgi_info attribute to the tuple
(dir, rest) if self.path requires running a CGI script.
Returns False otherwise.

If any exception is raised, the caller should assume that
self.path was rejected as invalid and act accordingly.

The default implementation tests whether the normalized url
path begins with one of the strings in self.cgi_directories
(and the next character is a '/' or the end of the string).

Definition at line 934 of file server.py.

00934 
00935     def is_cgi(self):
00936         """Test whether self.path corresponds to a CGI script.
00937 
00938         Returns True and updates the cgi_info attribute to the tuple
00939         (dir, rest) if self.path requires running a CGI script.
00940         Returns False otherwise.
00941 
00942         If any exception is raised, the caller should assume that
00943         self.path was rejected as invalid and act accordingly.
00944 
00945         The default implementation tests whether the normalized url
00946         path begins with one of the strings in self.cgi_directories
00947         (and the next character is a '/' or the end of the string).
00948 
00949         """
00950 
00951         splitpath = _url_collapse_path_split(self.path)
00952         if splitpath[0] in self.cgi_directories:
00953             self.cgi_info = splitpath
00954             return True
00955         return False

Here is the call graph for this function:

Here is the caller graph for this function:

Test whether argument path is an executable file.

Definition at line 958 of file server.py.

00958 
00959     def is_executable(self, path):
00960         """Test whether argument path is an executable file."""
00961         return executable(path)

Here is the call graph for this function:

Here is the caller graph for this function:

def http.server.CGIHTTPRequestHandler.is_python (   self,
  path 
)
Test whether argument path is a Python script.

Definition at line 962 of file server.py.

00962 
00963     def is_python(self, path):
00964         """Test whether argument path is a Python script."""
00965         head, tail = os.path.splitext(path)
00966         return tail.lower() in (".py", ".pyw")

Here is the caller graph for this function:

def http.server.SimpleHTTPRequestHandler.list_directory (   self,
  path 
) [inherited]
Helper to produce a directory listing (absent index.html).

Return value is either a file object, or None (indicating an
error).  In either case, the headers are sent, making the
interface the same as for send_head().

Definition at line 712 of file server.py.

00712 
00713     def list_directory(self, path):
00714         """Helper to produce a directory listing (absent index.html).
00715 
00716         Return value is either a file object, or None (indicating an
00717         error).  In either case, the headers are sent, making the
00718         interface the same as for send_head().
00719 
00720         """
00721         try:
00722             list = os.listdir(path)
00723         except os.error:
00724             self.send_error(404, "No permission to list directory")
00725             return None
00726         list.sort(key=lambda a: a.lower())
00727         r = []
00728         displaypath = html.escape(urllib.parse.unquote(self.path))
00729         r.append('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
00730         r.append("<html>\n<title>Directory listing for %s</title>\n" % displaypath)
00731         r.append("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)
00732         r.append("<hr>\n<ul>\n")
00733         for name in list:
00734             fullname = os.path.join(path, name)
00735             displayname = linkname = name
00736             # Append / for directories or @ for symbolic links
00737             if os.path.isdir(fullname):
00738                 displayname = name + "/"
00739                 linkname = name + "/"
00740             if os.path.islink(fullname):
00741                 displayname = name + "@"
00742                 # Note: a link to a directory displays with @ and links with /
00743             r.append('<li><a href="%s">%s</a>\n'
00744                     % (urllib.parse.quote(linkname), html.escape(displayname)))
00745         r.append("</ul>\n<hr>\n</body>\n</html>\n")
00746         enc = sys.getfilesystemencoding()
00747         encoded = ''.join(r).encode(enc)
00748         f = io.BytesIO()
00749         f.write(encoded)
00750         f.seek(0)
00751         self.send_response(200)
00752         self.send_header("Content-type", "text/html; charset=%s" % enc)
00753         self.send_header("Content-Length", str(len(encoded)))
00754         self.end_headers()
00755         return f

Here is the call graph for this function:

Here is the caller graph for this function:

Return the current time formatted for logging.

Definition at line 539 of file server.py.

00539 
00540     def log_date_time_string(self):
00541         """Return the current time formatted for logging."""
00542         now = time.time()
00543         year, month, day, hh, mm, ss, x, y, z = time.localtime(now)
00544         s = "%02d/%3s/%04d %02d:%02d:%02d" % (
00545                 day, self.monthname[month], year, hh, mm, ss)
00546         return s

Here is the caller graph for this function:

def http.server.BaseHTTPRequestHandler.log_error (   self,
  format,
  args 
) [inherited]
Log an error.

This is called when a request cannot be fulfilled.  By
default it passes the message on to log_message().

Arguments are the same as for log_message().

XXX This should go to the separate error log.

Definition at line 488 of file server.py.

00488 
00489     def log_error(self, format, *args):
00490         """Log an error.
00491 
00492         This is called when a request cannot be fulfilled.  By
00493         default it passes the message on to log_message().
00494 
00495         Arguments are the same as for log_message().
00496 
00497         XXX This should go to the separate error log.
00498 
00499         """
00500 
00501         self.log_message(format, *args)

Here is the call graph for this function:

Here is the caller graph for this function:

def http.server.BaseHTTPRequestHandler.log_message (   self,
  format,
  args 
) [inherited]
Log an arbitrary message.

This is used by all other logging functions.  Override
it if you have specific logging wishes.

The first argument, FORMAT, is a format string for the
message to be logged.  If the format string contains
any % escapes requiring parameters, they should be
specified as subsequent arguments (it's just like
printf!).

The client host and current date/time are prefixed to
every message.

Reimplemented in test.test_urllib2_localnet.FakeProxyHandler, and mp_webserver.RequestHandler.

Definition at line 502 of file server.py.

00502 
00503     def log_message(self, format, *args):
00504         """Log an arbitrary message.
00505 
00506         This is used by all other logging functions.  Override
00507         it if you have specific logging wishes.
00508 
00509         The first argument, FORMAT, is a format string for the
00510         message to be logged.  If the format string contains
00511         any % escapes requiring parameters, they should be
00512         specified as subsequent arguments (it's just like
00513         printf!).
00514 
00515         The client host and current date/time are prefixed to
00516         every message.
00517 
00518         """
00519 
00520         sys.stderr.write("%s - - [%s] %s\n" %
00521                          (self.address_string(),
00522                           self.log_date_time_string(),
00523                           format%args))

Here is the call graph for this function:

Here is the caller graph for this function:

def http.server.BaseHTTPRequestHandler.log_request (   self,
  code = '-',
  size = '-' 
) [inherited]
Log an accepted request.

This is called by send_response().

Reimplemented in xmlrpc.server.SimpleXMLRPCRequestHandler.

Definition at line 478 of file server.py.

00478 
00479     def log_request(self, code='-', size='-'):
00480         """Log an accepted request.
00481 
00482         This is called by send_response().
00483 
00484         """
00485 
00486         self.log_message('"%s" %s %s',
00487                          self.requestline, str(code), str(size))

Here is the call graph for this function:

Here is the caller graph for this function:

Parse a request (internal).

The request should be stored in self.raw_requestline; the results
are in self.command, self.path, self.request_version and
self.headers.

Return True for success, False for failure; on failure, an
error is sent back.

Definition at line 259 of file server.py.

00259 
00260     def parse_request(self):
00261         """Parse a request (internal).
00262 
00263         The request should be stored in self.raw_requestline; the results
00264         are in self.command, self.path, self.request_version and
00265         self.headers.
00266 
00267         Return True for success, False for failure; on failure, an
00268         error is sent back.
00269 
00270         """
00271         self.command = None  # set in case of error on the first line
00272         self.request_version = version = self.default_request_version
00273         self.close_connection = 1
00274         requestline = str(self.raw_requestline, 'iso-8859-1')
00275         if requestline[-2:] == '\r\n':
00276             requestline = requestline[:-2]
00277         elif requestline[-1:] == '\n':
00278             requestline = requestline[:-1]
00279         self.requestline = requestline
00280         words = requestline.split()
00281         if len(words) == 3:
00282             [command, path, version] = words
00283             if version[:5] != 'HTTP/':
00284                 self.send_error(400, "Bad request version (%r)" % version)
00285                 return False
00286             try:
00287                 base_version_number = version.split('/', 1)[1]
00288                 version_number = base_version_number.split(".")
00289                 # RFC 2145 section 3.1 says there can be only one "." and
00290                 #   - major and minor numbers MUST be treated as
00291                 #      separate integers;
00292                 #   - HTTP/2.4 is a lower version than HTTP/2.13, which in
00293                 #      turn is lower than HTTP/12.3;
00294                 #   - Leading zeros MUST be ignored by recipients.
00295                 if len(version_number) != 2:
00296                     raise ValueError
00297                 version_number = int(version_number[0]), int(version_number[1])
00298             except (ValueError, IndexError):
00299                 self.send_error(400, "Bad request version (%r)" % version)
00300                 return False
00301             if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1":
00302                 self.close_connection = 0
00303             if version_number >= (2, 0):
00304                 self.send_error(505,
00305                           "Invalid HTTP Version (%s)" % base_version_number)
00306                 return False
00307         elif len(words) == 2:
00308             [command, path] = words
00309             self.close_connection = 1
00310             if command != 'GET':
00311                 self.send_error(400,
00312                                 "Bad HTTP/0.9 request type (%r)" % command)
00313                 return False
00314         elif not words:
00315             return False
00316         else:
00317             self.send_error(400, "Bad request syntax (%r)" % requestline)
00318             return False
00319         self.command, self.path, self.request_version = command, path, version
00320 
00321         # Examine the headers and look for a Connection directive.
00322         try:
00323             self.headers = http.client.parse_headers(self.rfile,
00324                                                      _class=self.MessageClass)
00325         except http.client.LineTooLong:
00326             self.send_error(400, "Line too long")
00327             return False
00328 
00329         conntype = self.headers.get('Connection', "")
00330         if conntype.lower() == 'close':
00331             self.close_connection = 1
00332         elif (conntype.lower() == 'keep-alive' and
00333               self.protocol_version >= "HTTP/1.1"):
00334             self.close_connection = 0
00335         # Examine the headers and look for an Expect directive
00336         expect = self.headers.get('Expect', "")
00337         if (expect.lower() == "100-continue" and
00338                 self.protocol_version >= "HTTP/1.1" and
00339                 self.request_version >= "HTTP/1.1"):
00340             if not self.handle_expect_100():
00341                 return False
00342         return True

Execute a CGI script.

Definition at line 967 of file server.py.

00967 
00968     def run_cgi(self):
00969         """Execute a CGI script."""
00970         path = self.path
00971         dir, rest = self.cgi_info
00972 
00973         i = path.find('/', len(dir) + 1)
00974         while i >= 0:
00975             nextdir = path[:i]
00976             nextrest = path[i+1:]
00977 
00978             scriptdir = self.translate_path(nextdir)
00979             if os.path.isdir(scriptdir):
00980                 dir, rest = nextdir, nextrest
00981                 i = path.find('/', len(dir) + 1)
00982             else:
00983                 break
00984 
00985         # find an explicit query string, if present.
00986         i = rest.rfind('?')
00987         if i >= 0:
00988             rest, query = rest[:i], rest[i+1:]
00989         else:
00990             query = ''
00991 
00992         # dissect the part after the directory name into a script name &
00993         # a possible additional path, to be stored in PATH_INFO.
00994         i = rest.find('/')
00995         if i >= 0:
00996             script, rest = rest[:i], rest[i:]
00997         else:
00998             script, rest = rest, ''
00999 
01000         scriptname = dir + '/' + script
01001         scriptfile = self.translate_path(scriptname)
01002         if not os.path.exists(scriptfile):
01003             self.send_error(404, "No such CGI script (%r)" % scriptname)
01004             return
01005         if not os.path.isfile(scriptfile):
01006             self.send_error(403, "CGI script is not a plain file (%r)" %
01007                             scriptname)
01008             return
01009         ispy = self.is_python(scriptname)
01010         if not ispy:
01011             if not self.is_executable(scriptfile):
01012                 self.send_error(403, "CGI script is not executable (%r)" %
01013                                 scriptname)
01014                 return
01015 
01016         # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
01017         # XXX Much of the following could be prepared ahead of time!
01018         env = copy.deepcopy(os.environ)
01019         env['SERVER_SOFTWARE'] = self.version_string()
01020         env['SERVER_NAME'] = self.server.server_name
01021         env['GATEWAY_INTERFACE'] = 'CGI/1.1'
01022         env['SERVER_PROTOCOL'] = self.protocol_version
01023         env['SERVER_PORT'] = str(self.server.server_port)
01024         env['REQUEST_METHOD'] = self.command
01025         uqrest = urllib.parse.unquote(rest)
01026         env['PATH_INFO'] = uqrest
01027         env['PATH_TRANSLATED'] = self.translate_path(uqrest)
01028         env['SCRIPT_NAME'] = scriptname
01029         if query:
01030             env['QUERY_STRING'] = query
01031         host = self.address_string()
01032         if host != self.client_address[0]:
01033             env['REMOTE_HOST'] = host
01034         env['REMOTE_ADDR'] = self.client_address[0]
01035         authorization = self.headers.get("authorization")
01036         if authorization:
01037             authorization = authorization.split()
01038             if len(authorization) == 2:
01039                 import base64, binascii
01040                 env['AUTH_TYPE'] = authorization[0]
01041                 if authorization[0].lower() == "basic":
01042                     try:
01043                         authorization = authorization[1].encode('ascii')
01044                         authorization = base64.decodebytes(authorization).\
01045                                         decode('ascii')
01046                     except (binascii.Error, UnicodeError):
01047                         pass
01048                     else:
01049                         authorization = authorization.split(':')
01050                         if len(authorization) == 2:
01051                             env['REMOTE_USER'] = authorization[0]
01052         # XXX REMOTE_IDENT
01053         if self.headers.get('content-type') is None:
01054             env['CONTENT_TYPE'] = self.headers.get_content_type()
01055         else:
01056             env['CONTENT_TYPE'] = self.headers['content-type']
01057         length = self.headers.get('content-length')
01058         if length:
01059             env['CONTENT_LENGTH'] = length
01060         referer = self.headers.get('referer')
01061         if referer:
01062             env['HTTP_REFERER'] = referer
01063         accept = []
01064         for line in self.headers.getallmatchingheaders('accept'):
01065             if line[:1] in "\t\n\r ":
01066                 accept.append(line.strip())
01067             else:
01068                 accept = accept + line[7:].split(',')
01069         env['HTTP_ACCEPT'] = ','.join(accept)
01070         ua = self.headers.get('user-agent')
01071         if ua:
01072             env['HTTP_USER_AGENT'] = ua
01073         co = filter(None, self.headers.get_all('cookie', []))
01074         cookie_str = ', '.join(co)
01075         if cookie_str:
01076             env['HTTP_COOKIE'] = cookie_str
01077         # XXX Other HTTP_* headers
01078         # Since we're setting the env in the parent, provide empty
01079         # values to override previously set values
01080         for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
01081                   'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'):
01082             env.setdefault(k, "")
01083 
01084         self.send_response(200, "Script output follows")
01085 
01086         decoded_query = query.replace('+', ' ')
01087 
01088         if self.have_fork:
01089             # Unix -- fork as we should
01090             args = [script]
01091             if '=' not in decoded_query:
01092                 args.append(decoded_query)
01093             nobody = nobody_uid()
01094             self.wfile.flush() # Always flush before forking
01095             pid = os.fork()
01096             if pid != 0:
01097                 # Parent
01098                 pid, sts = os.waitpid(pid, 0)
01099                 # throw away additional data [see bug #427345]
01100                 while select.select([self.rfile], [], [], 0)[0]:
01101                     if not self.rfile.read(1):
01102                         break
01103                 if sts:
01104                     self.log_error("CGI script exit status %#x", sts)
01105                 return
01106             # Child
01107             try:
01108                 try:
01109                     os.setuid(nobody)
01110                 except os.error:
01111                     pass
01112                 os.dup2(self.rfile.fileno(), 0)
01113                 os.dup2(self.wfile.fileno(), 1)
01114                 os.execve(scriptfile, args, env)
01115             except:
01116                 self.server.handle_error(self.request, self.client_address)
01117                 os._exit(127)
01118 
01119         else:
01120             # Non-Unix -- use subprocess
01121             import subprocess
01122             cmdline = [scriptfile]
01123             if self.is_python(scriptfile):
01124                 interp = sys.executable
01125                 if interp.lower().endswith("w.exe"):
01126                     # On Windows, use python.exe, not pythonw.exe
01127                     interp = interp[:-5] + interp[-4:]
01128                 cmdline = [interp, '-u'] + cmdline
01129             if '=' not in query:
01130                 cmdline.append(query)
01131             self.log_message("command: %s", subprocess.list2cmdline(cmdline))
01132             try:
01133                 nbytes = int(length)
01134             except (TypeError, ValueError):
01135                 nbytes = 0
01136             p = subprocess.Popen(cmdline,
01137                                  stdin=subprocess.PIPE,
01138                                  stdout=subprocess.PIPE,
01139                                  stderr=subprocess.PIPE,
01140                                  env = env
01141                                  )
01142             if self.command.lower() == "post" and nbytes > 0:
01143                 data = self.rfile.read(nbytes)
01144             else:
01145                 data = None
01146             # throw away additional data [see bug #427345]
01147             while select.select([self.rfile._sock], [], [], 0)[0]:
01148                 if not self.rfile._sock.recv(1):
01149                     break
01150             stdout, stderr = p.communicate(data)
01151             self.wfile.write(stdout)
01152             if stderr:
01153                 self.log_error('%s', stderr)
01154             p.stderr.close()
01155             p.stdout.close()
01156             status = p.returncode
01157             if status:
01158                 self.log_error("CGI script exit status %#x", status)
01159             else:
01160                 self.log_message("CGI script exited OK")
01161 

Here is the call graph for this function:

Here is the caller graph for this function:

def http.server.BaseHTTPRequestHandler.send_error (   self,
  code,
  message = None 
) [inherited]
Send and log an error reply.

Arguments are the error code, and a detailed message.
The detailed message defaults to the short entry matching the
response code.

This sends an error response (so it must be called before any
output has been generated), logs the error, and finally sends
a piece of HTML explaining the error to the user.

Definition at line 403 of file server.py.

00403 
00404     def send_error(self, code, message=None):
00405         """Send and log an error reply.
00406 
00407         Arguments are the error code, and a detailed message.
00408         The detailed message defaults to the short entry matching the
00409         response code.
00410 
00411         This sends an error response (so it must be called before any
00412         output has been generated), logs the error, and finally sends
00413         a piece of HTML explaining the error to the user.
00414 
00415         """
00416 
00417         try:
00418             shortmsg, longmsg = self.responses[code]
00419         except KeyError:
00420             shortmsg, longmsg = '???', '???'
00421         if message is None:
00422             message = shortmsg
00423         explain = longmsg
00424         self.log_error("code %d, message %s", code, message)
00425         # using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201)
00426         content = (self.error_message_format %
00427                    {'code': code, 'message': _quote_html(message), 'explain': explain})
00428         self.send_response(code, message)
00429         self.send_header("Content-Type", self.error_content_type)
00430         self.send_header('Connection', 'close')
00431         self.end_headers()
00432         if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
00433             self.wfile.write(content.encode('UTF-8', 'replace'))

Here is the call graph for this function:

Here is the caller graph for this function:

Version of send_head that support CGI scripts

Reimplemented from http.server.SimpleHTTPRequestHandler.

Definition at line 927 of file server.py.

00927 
00928     def send_head(self):
00929         """Version of send_head that support CGI scripts"""
00930         if self.is_cgi():
00931             return self.run_cgi()
00932         else:
00933             return SimpleHTTPRequestHandler.send_head(self)

Here is the call graph for this function:

def http.server.BaseHTTPRequestHandler.send_header (   self,
  keyword,
  value 
) [inherited]
Send a MIME header.

Definition at line 457 of file server.py.

00457 
00458     def send_header(self, keyword, value):
00459         """Send a MIME header."""
00460         if self.request_version != 'HTTP/0.9':
00461             if not hasattr(self, '_headers_buffer'):
00462                 self._headers_buffer = []
00463             self._headers_buffer.append(
00464                 ("%s: %s\r\n" % (keyword, value)).encode('latin1', 'strict'))
00465 
00466         if keyword.lower() == 'connection':
00467             if value.lower() == 'close':
00468                 self.close_connection = 1
00469             elif value.lower() == 'keep-alive':
00470                 self.close_connection = 0

Here is the caller graph for this function:

def http.server.BaseHTTPRequestHandler.send_response (   self,
  code,
  message = None 
) [inherited]
Send the response header and log the response code.

Also send two standard headers with the server software
version and the current date.

Definition at line 434 of file server.py.

00434 
00435     def send_response(self, code, message=None):
00436         """Send the response header and log the response code.
00437 
00438         Also send two standard headers with the server software
00439         version and the current date.
00440 
00441         """
00442         self.log_request(code)
00443         self.send_response_only(code, message)
00444         self.send_header('Server', self.version_string())
00445         self.send_header('Date', self.date_time_string())

Here is the call graph for this function:

Here is the caller graph for this function:

def http.server.BaseHTTPRequestHandler.send_response_only (   self,
  code,
  message = None 
) [inherited]
Send the response header only.

Definition at line 446 of file server.py.

00446 
00447     def send_response_only(self, code, message=None):
00448         """Send the response header only."""
00449         if message is None:
00450             if code in self.responses:
00451                 message = self.responses[code][0]
00452             else:
00453                 message = ''
00454         if self.request_version != 'HTTP/0.9':
00455             self.wfile.write(("%s %d %s\r\n" %
00456                               (self.protocol_version, code, message)).encode('latin1', 'strict'))

Here is the caller graph for this function:

def socketserver.StreamRequestHandler.setup (   self) [inherited]

Reimplemented from socketserver.BaseRequestHandler.

Reimplemented in test.test_wsgiref.MockHandler.

Definition at line 681 of file socketserver.py.

00681 
00682     def setup(self):
00683         self.connection = self.request
00684         if self.timeout is not None:
00685             self.connection.settimeout(self.timeout)
00686         if self.disable_nagle_algorithm:
00687             self.connection.setsockopt(socket.IPPROTO_TCP,
00688                                        socket.TCP_NODELAY, True)
00689         self.rfile = self.connection.makefile('rb', self.rbufsize)
00690         self.wfile = self.connection.makefile('wb', self.wbufsize)

Here is the caller graph for this function:

def http.server.SimpleHTTPRequestHandler.translate_path (   self,
  path 
) [inherited]
Translate a /-separated PATH to the local filename syntax.

Components that mean special things to the local file system
(e.g. drive or directory names) are ignored.  (XXX They should
probably be diagnosed.)

Definition at line 756 of file server.py.

00756 
00757     def translate_path(self, path):
00758         """Translate a /-separated PATH to the local filename syntax.
00759 
00760         Components that mean special things to the local file system
00761         (e.g. drive or directory names) are ignored.  (XXX They should
00762         probably be diagnosed.)
00763 
00764         """
00765         # abandon query parameters
00766         path = path.split('?',1)[0]
00767         path = path.split('#',1)[0]
00768         path = posixpath.normpath(urllib.parse.unquote(path))
00769         words = path.split('/')
00770         words = filter(None, words)
00771         path = os.getcwd()
00772         for word in words:
00773             drive, word = os.path.splitdrive(word)
00774             head, word = os.path.split(word)
00775             if word in (os.curdir, os.pardir): continue
00776             path = os.path.join(path, word)
00777         return path

Here is the call graph for this function:

Here is the caller graph for this function:

Return the server software version string.

Definition at line 524 of file server.py.

00524 
00525     def version_string(self):
00526         """Return the server software version string."""
00527         return self.server_version + ' ' + self.sys_version

Here is the caller graph for this function:


Member Data Documentation

list http.server.CGIHTTPRequestHandler.cgi_directories = ['/cgi-bin', '/htbin'] [static]

Definition at line 956 of file server.py.

Definition at line 952 of file server.py.

Definition at line 634 of file socketserver.py.

Definition at line 272 of file server.py.

Definition at line 270 of file server.py.

Reimplemented in test.test_wsgiref.MockHandler.

Definition at line 682 of file socketserver.py.

Reimplemented in test.test_httpservers.BaseHTTPServerTestCase.request_handler.

Definition at line 257 of file server.py.

Reimplemented in xmlrpc.server.SimpleXMLRPCRequestHandler.

Definition at line 679 of file socketserver.py.

Definition at line 251 of file server.py.

Definition at line 250 of file server.py.

tuple http.server.SimpleHTTPRequestHandler.extensions_map = mimetypes.types_map.copy() [static, inherited]

Definition at line 820 of file server.py.

tuple http.server.CGIHTTPRequestHandler.have_fork = hasattr(os, 'fork') [static]

Definition at line 909 of file server.py.

Definition at line 322 of file server.py.

Definition at line 571 of file server.py.

Initial value:
[None,
                 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

Definition at line 549 of file server.py.

Reimplemented in wsgiref.simple_server.WSGIRequestHandler.

Definition at line 369 of file server.py.

Reimplemented from socketserver.StreamRequestHandler.

Definition at line 913 of file server.py.

Definition at line 633 of file socketserver.py.

Definition at line 271 of file server.py.

Definition at line 278 of file server.py.

Definition at line 576 of file server.py.

Definition at line 688 of file socketserver.py.

Definition at line 635 of file socketserver.py.

string http.server.SimpleHTTPRequestHandler.server_version = "SimpleHTTP/" [static, inherited]

Reimplemented from http.server.BaseHTTPRequestHandler.

Definition at line 656 of file server.py.

string http.server.BaseHTTPRequestHandler.sys_version = "Python/" [static, inherited]

Definition at line 243 of file server.py.

socketserver.StreamRequestHandler.timeout = None [static, inherited]

Reimplemented in test.test_imaplib.SimpleIMAPHandler.

Definition at line 675 of file socketserver.py.

Reimplemented in xmlrpc.server.SimpleXMLRPCRequestHandler.

Definition at line 672 of file socketserver.py.

list http.server.BaseHTTPRequestHandler.weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] [static, inherited]

Definition at line 547 of file server.py.

Reimplemented in test.test_wsgiref.MockHandler.

Definition at line 689 of file socketserver.py.


The documentation for this class was generated from the following file: