NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

BaseHTTPServer.py (11188B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\BaseHTTPServer.py
      2 __version__ = '0.3'
      3 __all__ = ['HTTPServer', 'BaseHTTPRequestHandler']
      4 import sys
      5 import time
      6 import socket
      7 from warnings import filterwarnings, catch_warnings
      8 with catch_warnings():
      9     if sys.py3kwarning:
     10         filterwarnings('ignore', '.*mimetools has been removed', DeprecationWarning)
     11     import mimetools
     12 import SocketServer
     13 DEFAULT_ERROR_MESSAGE = '<head>\n<title>Error response</title>\n</head>\n<body>\n<h1>Error response</h1>\n<p>Error code %(code)d.\n<p>Message: %(message)s.\n<p>Error code explanation: %(code)s = %(explain)s.\n</body>\n'
     14 DEFAULT_ERROR_CONTENT_TYPE = 'text/html'
     15 
     16 def _quote_html(html):
     17     return html.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
     18 
     19 
     20 class HTTPServer(SocketServer.TCPServer):
     21     allow_reuse_address = 1
     22 
     23     def server_bind(self):
     24         SocketServer.TCPServer.server_bind(self)
     25         host, port = self.socket.getsockname()[:2]
     26         self.server_name = socket.getfqdn(host)
     27         self.server_port = port
     28 
     29 
     30 class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
     31     sys_version = 'Python/' + sys.version.split()[0]
     32     server_version = 'BaseHTTP/' + __version__
     33     default_request_version = 'HTTP/0.9'
     34 
     35     def parse_request(self):
     36         self.command = None
     37         self.request_version = version = self.default_request_version
     38         self.close_connection = 1
     39         requestline = self.raw_requestline
     40         if requestline[-2:] == '\r\n':
     41             requestline = requestline[:-2]
     42         elif requestline[-1:] == '\n':
     43             requestline = requestline[:-1]
     44         self.requestline = requestline
     45         words = requestline.split()
     46         if len(words) == 3:
     47             command, path, version = words
     48             if version[:5] != 'HTTP/':
     49                 self.send_error(400, 'Bad request version (%r)' % version)
     50                 return False
     51             try:
     52                 base_version_number = version.split('/', 1)[1]
     53                 version_number = base_version_number.split('.')
     54                 if len(version_number) != 2:
     55                     raise ValueError
     56                 version_number = (int(version_number[0]), int(version_number[1]))
     57             except (ValueError, IndexError):
     58                 self.send_error(400, 'Bad request version (%r)' % version)
     59                 return False
     60 
     61             if version_number >= (1, 1) and self.protocol_version >= 'HTTP/1.1':
     62                 self.close_connection = 0
     63             if version_number >= (2, 0):
     64                 self.send_error(505, 'Invalid HTTP Version (%s)' % base_version_number)
     65                 return False
     66         elif len(words) == 2:
     67             command, path = words
     68             self.close_connection = 1
     69             if command != 'GET':
     70                 self.send_error(400, 'Bad HTTP/0.9 request type (%r)' % command)
     71                 return False
     72         else:
     73             if not words:
     74                 return False
     75             self.send_error(400, 'Bad request syntax (%r)' % requestline)
     76             return False
     77         self.command, self.path, self.request_version = command, path, version
     78         self.headers = self.MessageClass(self.rfile, 0)
     79         conntype = self.headers.get('Connection', '')
     80         if conntype.lower() == 'close':
     81             self.close_connection = 1
     82         elif conntype.lower() == 'keep-alive' and self.protocol_version >= 'HTTP/1.1':
     83             self.close_connection = 0
     84         return True
     85 
     86     def handle_one_request(self):
     87         try:
     88             self.raw_requestline = self.rfile.readline()
     89             if not self.raw_requestline:
     90                 self.close_connection = 1
     91                 return
     92             if not self.parse_request():
     93                 return
     94             mname = 'do_' + self.command
     95             if not hasattr(self, mname):
     96                 self.send_error(501, 'Unsupported method (%r)' % self.command)
     97                 return
     98             method = getattr(self, mname)
     99             method()
    100             self.wfile.flush()
    101         except socket.timeout as e:
    102             self.log_error('Request timed out: %r', e)
    103             self.close_connection = 1
    104             return
    105 
    106     def handle(self):
    107         self.close_connection = 1
    108         self.handle_one_request()
    109         while not self.close_connection:
    110             self.handle_one_request()
    111 
    112     def send_error(self, code, message = None):
    113         try:
    114             short, long = self.responses[code]
    115         except KeyError:
    116             short, long = ('???', '???')
    117 
    118         if message is None:
    119             message = short
    120         explain = long
    121         self.log_error('code %d, message %s', code, message)
    122         content = self.error_message_format % {'code': code,
    123          'message': _quote_html(message),
    124          'explain': explain}
    125         self.send_response(code, message)
    126         self.send_header('Content-Type', self.error_content_type)
    127         self.send_header('Connection', 'close')
    128         self.end_headers()
    129         if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
    130             self.wfile.write(content)
    131 
    132     error_message_format = DEFAULT_ERROR_MESSAGE
    133     error_content_type = DEFAULT_ERROR_CONTENT_TYPE
    134 
    135     def send_response(self, code, message = None):
    136         self.log_request(code)
    137         if message is None:
    138             if code in self.responses:
    139                 message = self.responses[code][0]
    140             else:
    141                 message = ''
    142         if self.request_version != 'HTTP/0.9':
    143             self.wfile.write('%s %d %s\r\n' % (self.protocol_version, code, message))
    144         self.send_header('Server', self.version_string())
    145         self.send_header('Date', self.date_time_string())
    146 
    147     def send_header(self, keyword, value):
    148         if self.request_version != 'HTTP/0.9':
    149             self.wfile.write('%s: %s\r\n' % (keyword, value))
    150         if keyword.lower() == 'connection':
    151             if value.lower() == 'close':
    152                 self.close_connection = 1
    153             elif value.lower() == 'keep-alive':
    154                 self.close_connection = 0
    155 
    156     def end_headers(self):
    157         if self.request_version != 'HTTP/0.9':
    158             self.wfile.write('\r\n')
    159 
    160     def log_request(self, code = '-', size = '-'):
    161         self.log_message('"%s" %s %s', self.requestline, str(code), str(size))
    162 
    163     def log_error(self, format, *args):
    164         self.log_message(format, *args)
    165 
    166     def log_message(self, format, *args):
    167         sys.stderr.write('%s - - [%s] %s\n' % (self.address_string(), self.log_date_time_string(), format % args))
    168 
    169     def version_string(self):
    170         return self.server_version + ' ' + self.sys_version
    171 
    172     def date_time_string(self, timestamp = None):
    173         if timestamp is None:
    174             timestamp = time.time()
    175         year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp)
    176         s = '%s, %02d %3s %4d %02d:%02d:%02d GMT' % (self.weekdayname[wd],
    177          day,
    178          self.monthname[month],
    179          year,
    180          hh,
    181          mm,
    182          ss)
    183         return s
    184 
    185     def log_date_time_string(self):
    186         now = time.time()
    187         year, month, day, hh, mm, ss, x, y, z = time.localtime(now)
    188         s = '%02d/%3s/%04d %02d:%02d:%02d' % (day,
    189          self.monthname[month],
    190          year,
    191          hh,
    192          mm,
    193          ss)
    194         return s
    195 
    196     weekdayname = ['Mon',
    197      'Tue',
    198      'Wed',
    199      'Thu',
    200      'Fri',
    201      'Sat',
    202      'Sun']
    203     monthname = [None,
    204      'Jan',
    205      'Feb',
    206      'Mar',
    207      'Apr',
    208      'May',
    209      'Jun',
    210      'Jul',
    211      'Aug',
    212      'Sep',
    213      'Oct',
    214      'Nov',
    215      'Dec']
    216 
    217     def address_string(self):
    218         host, port = self.client_address[:2]
    219         return socket.getfqdn(host)
    220 
    221     protocol_version = 'HTTP/1.0'
    222     MessageClass = mimetools.Message
    223     responses = {100: ('Continue', 'Request received, please continue'),
    224      101: ('Switching Protocols', 'Switching to new protocol; obey Upgrade header'),
    225      200: ('OK', 'Request fulfilled, document follows'),
    226      201: ('Created', 'Document created, URL follows'),
    227      202: ('Accepted', 'Request accepted, processing continues off-line'),
    228      203: ('Non-Authoritative Information', 'Request fulfilled from cache'),
    229      204: ('No Content', 'Request fulfilled, nothing follows'),
    230      205: ('Reset Content', 'Clear input form for further input.'),
    231      206: ('Partial Content', 'Partial content follows.'),
    232      300: ('Multiple Choices', 'Object has several resources -- see URI list'),
    233      301: ('Moved Permanently', 'Object moved permanently -- see URI list'),
    234      302: ('Found', 'Object moved temporarily -- see URI list'),
    235      303: ('See Other', 'Object moved -- see Method and URL list'),
    236      304: ('Not Modified', 'Document has not changed since given time'),
    237      305: ('Use Proxy', 'You must use proxy specified in Location to access this resource.'),
    238      307: ('Temporary Redirect', 'Object moved temporarily -- see URI list'),
    239      400: ('Bad Request', 'Bad request syntax or unsupported method'),
    240      401: ('Unauthorized', 'No permission -- see authorization schemes'),
    241      402: ('Payment Required', 'No payment -- see charging schemes'),
    242      403: ('Forbidden', 'Request forbidden -- authorization will not help'),
    243      404: ('Not Found', 'Nothing matches the given URI'),
    244      405: ('Method Not Allowed', 'Specified method is invalid for this resource.'),
    245      406: ('Not Acceptable', 'URI not available in preferred format.'),
    246      407: ('Proxy Authentication Required', 'You must authenticate with this proxy before proceeding.'),
    247      408: ('Request Timeout', 'Request timed out; try again later.'),
    248      409: ('Conflict', 'Request conflict.'),
    249      410: ('Gone', 'URI no longer exists and has been permanently removed.'),
    250      411: ('Length Required', 'Client must specify Content-Length.'),
    251      412: ('Precondition Failed', 'Precondition in headers is false.'),
    252      413: ('Request Entity Too Large', 'Entity is too large.'),
    253      414: ('Request-URI Too Long', 'URI is too long.'),
    254      415: ('Unsupported Media Type', 'Entity body in unsupported format.'),
    255      416: ('Requested Range Not Satisfiable', 'Cannot satisfy request range.'),
    256      417: ('Expectation Failed', 'Expect condition could not be satisfied.'),
    257      500: ('Internal Server Error', 'Server got itself in trouble'),
    258      501: ('Not Implemented', 'Server does not support this operation'),
    259      502: ('Bad Gateway', 'Invalid responses from another server/proxy.'),
    260      503: ('Service Unavailable', 'The server cannot process the request due to a high load'),
    261      504: ('Gateway Timeout', 'The gateway server did not receive a timely response'),
    262      505: ('HTTP Version Not Supported', 'Cannot fulfill request.')}
    263 
    264 
    265 def test(HandlerClass = BaseHTTPRequestHandler, ServerClass = HTTPServer, protocol = 'HTTP/1.0'):
    266     if sys.argv[1:]:
    267         port = int(sys.argv[1])
    268     else:
    269         port = 8000
    270     server_address = ('', port)
    271     HandlerClass.protocol_version = protocol
    272     httpd = ServerClass(server_address, HandlerClass)
    273     sa = httpd.socket.getsockname()
    274     print 'Serving HTTP on', sa[0], 'port', sa[1], '...'
    275     httpd.serve_forever()
    276 
    277 
    278 if __name__ == '__main__':
    279     test()