symbian-qemu-0.9.1-12/python-win32-2.6.1/lib/SimpleHTTPServer.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """Simple HTTP Server.
       
     2 
       
     3 This module builds on BaseHTTPServer by implementing the standard GET
       
     4 and HEAD requests in a fairly straightforward manner.
       
     5 
       
     6 """
       
     7 
       
     8 
       
     9 __version__ = "0.6"
       
    10 
       
    11 __all__ = ["SimpleHTTPRequestHandler"]
       
    12 
       
    13 import os
       
    14 import posixpath
       
    15 import BaseHTTPServer
       
    16 import urllib
       
    17 import cgi
       
    18 import shutil
       
    19 import mimetypes
       
    20 try:
       
    21     from cStringIO import StringIO
       
    22 except ImportError:
       
    23     from StringIO import StringIO
       
    24 
       
    25 
       
    26 class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
       
    27 
       
    28     """Simple HTTP request handler with GET and HEAD commands.
       
    29 
       
    30     This serves files from the current directory and any of its
       
    31     subdirectories.  The MIME type for files is determined by
       
    32     calling the .guess_type() method.
       
    33 
       
    34     The GET and HEAD requests are identical except that the HEAD
       
    35     request omits the actual contents of the file.
       
    36 
       
    37     """
       
    38 
       
    39     server_version = "SimpleHTTP/" + __version__
       
    40 
       
    41     def do_GET(self):
       
    42         """Serve a GET request."""
       
    43         f = self.send_head()
       
    44         if f:
       
    45             self.copyfile(f, self.wfile)
       
    46             f.close()
       
    47 
       
    48     def do_HEAD(self):
       
    49         """Serve a HEAD request."""
       
    50         f = self.send_head()
       
    51         if f:
       
    52             f.close()
       
    53 
       
    54     def send_head(self):
       
    55         """Common code for GET and HEAD commands.
       
    56 
       
    57         This sends the response code and MIME headers.
       
    58 
       
    59         Return value is either a file object (which has to be copied
       
    60         to the outputfile by the caller unless the command was HEAD,
       
    61         and must be closed by the caller under all circumstances), or
       
    62         None, in which case the caller has nothing further to do.
       
    63 
       
    64         """
       
    65         path = self.translate_path(self.path)
       
    66         f = None
       
    67         if os.path.isdir(path):
       
    68             if not self.path.endswith('/'):
       
    69                 # redirect browser - doing basically what apache does
       
    70                 self.send_response(301)
       
    71                 self.send_header("Location", self.path + "/")
       
    72                 self.end_headers()
       
    73                 return None
       
    74             for index in "index.html", "index.htm":
       
    75                 index = os.path.join(path, index)
       
    76                 if os.path.exists(index):
       
    77                     path = index
       
    78                     break
       
    79             else:
       
    80                 return self.list_directory(path)
       
    81         ctype = self.guess_type(path)
       
    82         try:
       
    83             # Always read in binary mode. Opening files in text mode may cause
       
    84             # newline translations, making the actual size of the content
       
    85             # transmitted *less* than the content-length!
       
    86             f = open(path, 'rb')
       
    87         except IOError:
       
    88             self.send_error(404, "File not found")
       
    89             return None
       
    90         self.send_response(200)
       
    91         self.send_header("Content-type", ctype)
       
    92         fs = os.fstat(f.fileno())
       
    93         self.send_header("Content-Length", str(fs[6]))
       
    94         self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
       
    95         self.end_headers()
       
    96         return f
       
    97 
       
    98     def list_directory(self, path):
       
    99         """Helper to produce a directory listing (absent index.html).
       
   100 
       
   101         Return value is either a file object, or None (indicating an
       
   102         error).  In either case, the headers are sent, making the
       
   103         interface the same as for send_head().
       
   104 
       
   105         """
       
   106         try:
       
   107             list = os.listdir(path)
       
   108         except os.error:
       
   109             self.send_error(404, "No permission to list directory")
       
   110             return None
       
   111         list.sort(key=lambda a: a.lower())
       
   112         f = StringIO()
       
   113         displaypath = cgi.escape(urllib.unquote(self.path))
       
   114         f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
       
   115         f.write("<html>\n<title>Directory listing for %s</title>\n" % displaypath)
       
   116         f.write("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)
       
   117         f.write("<hr>\n<ul>\n")
       
   118         for name in list:
       
   119             fullname = os.path.join(path, name)
       
   120             displayname = linkname = name
       
   121             # Append / for directories or @ for symbolic links
       
   122             if os.path.isdir(fullname):
       
   123                 displayname = name + "/"
       
   124                 linkname = name + "/"
       
   125             if os.path.islink(fullname):
       
   126                 displayname = name + "@"
       
   127                 # Note: a link to a directory displays with @ and links with /
       
   128             f.write('<li><a href="%s">%s</a>\n'
       
   129                     % (urllib.quote(linkname), cgi.escape(displayname)))
       
   130         f.write("</ul>\n<hr>\n</body>\n</html>\n")
       
   131         length = f.tell()
       
   132         f.seek(0)
       
   133         self.send_response(200)
       
   134         self.send_header("Content-type", "text/html")
       
   135         self.send_header("Content-Length", str(length))
       
   136         self.end_headers()
       
   137         return f
       
   138 
       
   139     def translate_path(self, path):
       
   140         """Translate a /-separated PATH to the local filename syntax.
       
   141 
       
   142         Components that mean special things to the local file system
       
   143         (e.g. drive or directory names) are ignored.  (XXX They should
       
   144         probably be diagnosed.)
       
   145 
       
   146         """
       
   147         # abandon query parameters
       
   148         path = path.split('?',1)[0]
       
   149         path = path.split('#',1)[0]
       
   150         path = posixpath.normpath(urllib.unquote(path))
       
   151         words = path.split('/')
       
   152         words = filter(None, words)
       
   153         path = os.getcwd()
       
   154         for word in words:
       
   155             drive, word = os.path.splitdrive(word)
       
   156             head, word = os.path.split(word)
       
   157             if word in (os.curdir, os.pardir): continue
       
   158             path = os.path.join(path, word)
       
   159         return path
       
   160 
       
   161     def copyfile(self, source, outputfile):
       
   162         """Copy all data between two file objects.
       
   163 
       
   164         The SOURCE argument is a file object open for reading
       
   165         (or anything with a read() method) and the DESTINATION
       
   166         argument is a file object open for writing (or
       
   167         anything with a write() method).
       
   168 
       
   169         The only reason for overriding this would be to change
       
   170         the block size or perhaps to replace newlines by CRLF
       
   171         -- note however that this the default server uses this
       
   172         to copy binary data as well.
       
   173 
       
   174         """
       
   175         shutil.copyfileobj(source, outputfile)
       
   176 
       
   177     def guess_type(self, path):
       
   178         """Guess the type of a file.
       
   179 
       
   180         Argument is a PATH (a filename).
       
   181 
       
   182         Return value is a string of the form type/subtype,
       
   183         usable for a MIME Content-type header.
       
   184 
       
   185         The default implementation looks the file's extension
       
   186         up in the table self.extensions_map, using application/octet-stream
       
   187         as a default; however it would be permissible (if
       
   188         slow) to look inside the data to make a better guess.
       
   189 
       
   190         """
       
   191 
       
   192         base, ext = posixpath.splitext(path)
       
   193         if ext in self.extensions_map:
       
   194             return self.extensions_map[ext]
       
   195         ext = ext.lower()
       
   196         if ext in self.extensions_map:
       
   197             return self.extensions_map[ext]
       
   198         else:
       
   199             return self.extensions_map['']
       
   200 
       
   201     if not mimetypes.inited:
       
   202         mimetypes.init() # try to read system mime.types
       
   203     extensions_map = mimetypes.types_map.copy()
       
   204     extensions_map.update({
       
   205         '': 'application/octet-stream', # Default
       
   206         '.py': 'text/plain',
       
   207         '.c': 'text/plain',
       
   208         '.h': 'text/plain',
       
   209         })
       
   210 
       
   211 
       
   212 def test(HandlerClass = SimpleHTTPRequestHandler,
       
   213          ServerClass = BaseHTTPServer.HTTPServer):
       
   214     BaseHTTPServer.test(HandlerClass, ServerClass)
       
   215 
       
   216 
       
   217 if __name__ == '__main__':
       
   218     test()