home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / httplib.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  33.2 KB  |  1,196 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''HTTP/1.1 client library
  5.  
  6. <intro stuff goes here>
  7. <other stuff, too>
  8.  
  9. HTTPConnection goes through a number of "states", which define when a client
  10. may legally make another request or fetch the response for a particular
  11. request. This diagram details these state transitions:
  12.  
  13.     (null)
  14.       |
  15.       | HTTPConnection()
  16.       v
  17.     Idle
  18.       |
  19.       | putrequest()
  20.       v
  21.     Request-started
  22.       |
  23.       | ( putheader() )*  endheaders()
  24.       v
  25.     Request-sent
  26.       |
  27.       | response = getresponse()
  28.       v
  29.     Unread-response   [Response-headers-read]
  30.       |\\____________________
  31.       |                     |
  32.       | response.read()     | putrequest()
  33.       v                     v
  34.     Idle                  Req-started-unread-response
  35.                      ______/|
  36.                    /        |
  37.    response.read() |        | ( putheader() )*  endheaders()
  38.                    v        v
  39.        Request-started    Req-sent-unread-response
  40.                             |
  41.                             | response.read()
  42.                             v
  43.                           Request-sent
  44.  
  45. This diagram presents the following rules:
  46.   -- a second request may not be started until {response-headers-read}
  47.   -- a response [object] cannot be retrieved until {request-sent}
  48.   -- there is no differentiation between an unread response body and a
  49.      partially read response body
  50.  
  51. Note: this enforcement is applied by the HTTPConnection class. The
  52.       HTTPResponse class does not enforce this state machine, which
  53.       implies sophisticated clients may accelerate the request/response
  54.       pipeline. Caution should be taken, though: accelerating the states
  55.       beyond the above pattern may imply knowledge of the server\'s
  56.       connection-close behavior for certain requests. For example, it
  57.       is impossible to tell whether the server will close the connection
  58.       UNTIL the response headers have been read; this means that further
  59.       requests cannot be placed into the pipeline until it is known that
  60.       the server will NOT be closing the connection.
  61.  
  62. Logical State                  __state            __response
  63. -------------                  -------            ----------
  64. Idle                           _CS_IDLE           None
  65. Request-started                _CS_REQ_STARTED    None
  66. Request-sent                   _CS_REQ_SENT       None
  67. Unread-response                _CS_IDLE           <response_class>
  68. Req-started-unread-response    _CS_REQ_STARTED    <response_class>
  69. Req-sent-unread-response       _CS_REQ_SENT       <response_class>
  70. '''
  71. import socket
  72. from sys import py3kwarning
  73. from urlparse import urlsplit
  74. import warnings
  75. warnings.catch_warnings().__enter__()
  76.  
  77. try:
  78.     import mimetools
  79. finally:
  80.     pass
  81.  
  82.  
  83. try:
  84.     from cStringIO import StringIO
  85. except ImportError:
  86.     warnings.catch_warnings().__exit__
  87.     warnings.catch_warnings().__exit__
  88.     warnings.catch_warnings()
  89.     from StringIO import StringIO
  90. except:
  91.     warnings.catch_warnings().__exit__
  92.  
  93. __all__ = [
  94.     'HTTP',
  95.     'HTTPResponse',
  96.     'HTTPConnection',
  97.     'HTTPException',
  98.     'NotConnected',
  99.     'UnknownProtocol',
  100.     'UnknownTransferEncoding',
  101.     'UnimplementedFileMode',
  102.     'IncompleteRead',
  103.     'InvalidURL',
  104.     'ImproperConnectionState',
  105.     'CannotSendRequest',
  106.     'CannotSendHeader',
  107.     'ResponseNotReady',
  108.     'BadStatusLine',
  109.     'error',
  110.     'responses']
  111. HTTP_PORT = 80
  112. HTTPS_PORT = 443
  113. _UNKNOWN = 'UNKNOWN'
  114. _CS_IDLE = 'Idle'
  115. _CS_REQ_STARTED = 'Request-started'
  116. _CS_REQ_SENT = 'Request-sent'
  117. CONTINUE = 100
  118. SWITCHING_PROTOCOLS = 101
  119. PROCESSING = 102
  120. OK = 200
  121. CREATED = 201
  122. ACCEPTED = 202
  123. NON_AUTHORITATIVE_INFORMATION = 203
  124. NO_CONTENT = 204
  125. RESET_CONTENT = 205
  126. PARTIAL_CONTENT = 206
  127. MULTI_STATUS = 207
  128. IM_USED = 226
  129. MULTIPLE_CHOICES = 300
  130. MOVED_PERMANENTLY = 301
  131. FOUND = 302
  132. SEE_OTHER = 303
  133. NOT_MODIFIED = 304
  134. USE_PROXY = 305
  135. TEMPORARY_REDIRECT = 307
  136. BAD_REQUEST = 400
  137. UNAUTHORIZED = 401
  138. PAYMENT_REQUIRED = 402
  139. FORBIDDEN = 403
  140. NOT_FOUND = 404
  141. METHOD_NOT_ALLOWED = 405
  142. NOT_ACCEPTABLE = 406
  143. PROXY_AUTHENTICATION_REQUIRED = 407
  144. REQUEST_TIMEOUT = 408
  145. CONFLICT = 409
  146. GONE = 410
  147. LENGTH_REQUIRED = 411
  148. PRECONDITION_FAILED = 412
  149. REQUEST_ENTITY_TOO_LARGE = 413
  150. REQUEST_URI_TOO_LONG = 414
  151. UNSUPPORTED_MEDIA_TYPE = 415
  152. REQUESTED_RANGE_NOT_SATISFIABLE = 416
  153. EXPECTATION_FAILED = 417
  154. UNPROCESSABLE_ENTITY = 422
  155. LOCKED = 423
  156. FAILED_DEPENDENCY = 424
  157. UPGRADE_REQUIRED = 426
  158. INTERNAL_SERVER_ERROR = 500
  159. NOT_IMPLEMENTED = 501
  160. BAD_GATEWAY = 502
  161. SERVICE_UNAVAILABLE = 503
  162. GATEWAY_TIMEOUT = 504
  163. HTTP_VERSION_NOT_SUPPORTED = 505
  164. INSUFFICIENT_STORAGE = 507
  165. NOT_EXTENDED = 510
  166. responses = {
  167.     100: 'Continue',
  168.     101: 'Switching Protocols',
  169.     200: 'OK',
  170.     201: 'Created',
  171.     202: 'Accepted',
  172.     203: 'Non-Authoritative Information',
  173.     204: 'No Content',
  174.     205: 'Reset Content',
  175.     206: 'Partial Content',
  176.     300: 'Multiple Choices',
  177.     301: 'Moved Permanently',
  178.     302: 'Found',
  179.     303: 'See Other',
  180.     304: 'Not Modified',
  181.     305: 'Use Proxy',
  182.     306: '(Unused)',
  183.     307: 'Temporary Redirect',
  184.     400: 'Bad Request',
  185.     401: 'Unauthorized',
  186.     402: 'Payment Required',
  187.     403: 'Forbidden',
  188.     404: 'Not Found',
  189.     405: 'Method Not Allowed',
  190.     406: 'Not Acceptable',
  191.     407: 'Proxy Authentication Required',
  192.     408: 'Request Timeout',
  193.     409: 'Conflict',
  194.     410: 'Gone',
  195.     411: 'Length Required',
  196.     412: 'Precondition Failed',
  197.     413: 'Request Entity Too Large',
  198.     414: 'Request-URI Too Long',
  199.     415: 'Unsupported Media Type',
  200.     416: 'Requested Range Not Satisfiable',
  201.     417: 'Expectation Failed',
  202.     500: 'Internal Server Error',
  203.     501: 'Not Implemented',
  204.     502: 'Bad Gateway',
  205.     503: 'Service Unavailable',
  206.     504: 'Gateway Timeout',
  207.     505: 'HTTP Version Not Supported' }
  208. MAXAMOUNT = 1048576
  209.  
  210. class HTTPMessage(mimetools.Message):
  211.     
  212.     def addheader(self, key, value):
  213.         '''Add header for field key handling repeats.'''
  214.         prev = self.dict.get(key)
  215.         if prev is None:
  216.             self.dict[key] = value
  217.         else:
  218.             combined = ', '.join((prev, value))
  219.             self.dict[key] = combined
  220.  
  221.     
  222.     def addcontinue(self, key, more):
  223.         '''Add more field data from a continuation line.'''
  224.         prev = self.dict[key]
  225.         self.dict[key] = prev + '\n ' + more
  226.  
  227.     
  228.     def readheaders(self):
  229.         '''Read header lines.
  230.  
  231.         Read header lines up to the entirely blank line that terminates them.
  232.         The (normally blank) line that ends the headers is skipped, but not
  233.         included in the returned list.  If a non-header line ends the headers,
  234.         (which is an error), an attempt is made to backspace over it; it is
  235.         never included in the returned list.
  236.  
  237.         The variable self.status is set to the empty string if all went well,
  238.         otherwise it is an error message.  The variable self.headers is a
  239.         completely uninterpreted list of lines contained in the header (so
  240.         printing them will reproduce the header exactly as it appears in the
  241.         file).
  242.  
  243.         If multiple header fields with the same name occur, they are combined
  244.         according to the rules in RFC 2616 sec 4.2:
  245.  
  246.         Appending each subsequent field-value to the first, each separated
  247.         by a comma. The order in which header fields with the same field-name
  248.         are received is significant to the interpretation of the combined
  249.         field value.
  250.         '''
  251.         self.dict = { }
  252.         self.unixfrom = ''
  253.         self.headers = hlist = []
  254.         self.status = ''
  255.         headerseen = ''
  256.         firstline = 1
  257.         startofline = None
  258.         unread = None
  259.         tell = None
  260.         if hasattr(self.fp, 'unread'):
  261.             unread = self.fp.unread
  262.         elif self.seekable:
  263.             tell = self.fp.tell
  264.         
  265.         while True:
  266.             if tell:
  267.                 
  268.                 try:
  269.                     startofline = tell()
  270.                 except IOError:
  271.                     startofline = None
  272.                     tell = None
  273.                     self.seekable = 0
  274.                 except:
  275.                     None<EXCEPTION MATCH>IOError
  276.                 
  277.  
  278.             None<EXCEPTION MATCH>IOError
  279.             line = self.fp.readline()
  280.             if not line:
  281.                 self.status = 'EOF in headers'
  282.                 break
  283.             
  284.             if firstline and line.startswith('From '):
  285.                 self.unixfrom = self.unixfrom + line
  286.                 continue
  287.             
  288.             firstline = 0
  289.             if headerseen and line[0] in ' \t':
  290.                 hlist.append(line)
  291.                 self.addcontinue(headerseen, line.strip())
  292.                 continue
  293.             elif self.iscomment(line):
  294.                 continue
  295.             elif self.islast(line):
  296.                 break
  297.             
  298.             headerseen = self.isheader(line)
  299.             if headerseen:
  300.                 hlist.append(line)
  301.                 self.addheader(headerseen, line[len(headerseen) + 1:].strip())
  302.                 continue
  303.                 continue
  304.             if not self.dict:
  305.                 self.status = 'No headers'
  306.             else:
  307.                 self.status = 'Non-header line where header expected'
  308.             if unread:
  309.                 unread(line)
  310.             elif tell:
  311.                 self.fp.seek(startofline)
  312.             else:
  313.                 self.status = self.status + '; bad seek'
  314.             break
  315.  
  316.  
  317.  
  318. class HTTPResponse:
  319.     
  320.     def __init__(self, sock, debuglevel = 0, strict = 0, method = None):
  321.         self.fp = sock.makefile('rb', 0)
  322.         self.debuglevel = debuglevel
  323.         self.strict = strict
  324.         self._method = method
  325.         self.msg = None
  326.         self.version = _UNKNOWN
  327.         self.status = _UNKNOWN
  328.         self.reason = _UNKNOWN
  329.         self.chunked = _UNKNOWN
  330.         self.chunk_left = _UNKNOWN
  331.         self.length = _UNKNOWN
  332.         self.will_close = _UNKNOWN
  333.  
  334.     
  335.     def _read_status(self):
  336.         line = self.fp.readline()
  337.         if self.debuglevel > 0:
  338.             print 'reply:', repr(line)
  339.         
  340.         if not line:
  341.             raise BadStatusLine(line)
  342.         line
  343.         
  344.         try:
  345.             (version, status, reason) = line.split(None, 2)
  346.         except ValueError:
  347.             
  348.             try:
  349.                 (version, status) = line.split(None, 1)
  350.                 reason = ''
  351.             except ValueError:
  352.                 version = ''
  353.             except:
  354.                 None<EXCEPTION MATCH>ValueError
  355.             
  356.  
  357.             None<EXCEPTION MATCH>ValueError
  358.  
  359.         if not version.startswith('HTTP/'):
  360.             if self.strict:
  361.                 self.close()
  362.                 raise BadStatusLine(line)
  363.             self.strict
  364.             self.fp = LineAndFileWrapper(line, self.fp)
  365.             return ('HTTP/0.9', 200, '')
  366.         version.startswith('HTTP/')
  367.         
  368.         try:
  369.             status = int(status)
  370.             if status < 100 or status > 999:
  371.                 raise BadStatusLine(line)
  372.             status > 999
  373.         except ValueError:
  374.             raise BadStatusLine(line)
  375.  
  376.         return (version, status, reason)
  377.  
  378.     
  379.     def begin(self):
  380.         if self.msg is not None:
  381.             return None
  382.         while True:
  383.             (version, status, reason) = self._read_status()
  384.             if status != CONTINUE:
  385.                 break
  386.             
  387.             while True:
  388.                 skip = self.fp.readline().strip()
  389.                 if not skip:
  390.                     break
  391.                 
  392.                 if self.debuglevel > 0:
  393.                     print 'header:', skip
  394.                     continue
  395.         self.status = status
  396.         self.reason = reason.strip()
  397.         if version == 'HTTP/1.0':
  398.             self.version = 10
  399.         elif version.startswith('HTTP/1.'):
  400.             self.version = 11
  401.         elif version == 'HTTP/0.9':
  402.             self.version = 9
  403.         else:
  404.             raise UnknownProtocol(version)
  405.         if (version == 'HTTP/1.0').version == 9:
  406.             self.length = None
  407.             self.chunked = 0
  408.             self.will_close = 1
  409.             self.msg = HTTPMessage(StringIO())
  410.             return None
  411.         self.msg = HTTPMessage(self.fp, 0)
  412.         if self.debuglevel > 0:
  413.             for hdr in self.msg.headers:
  414.                 print 'header:', hdr,
  415.             
  416.         
  417.         self.msg.fp = None
  418.         tr_enc = self.msg.getheader('transfer-encoding')
  419.         if tr_enc and tr_enc.lower() == 'chunked':
  420.             self.chunked = 1
  421.             self.chunk_left = None
  422.         else:
  423.             self.chunked = 0
  424.         self.will_close = self._check_close()
  425.         length = self.msg.getheader('content-length')
  426.         if length and not (self.chunked):
  427.             
  428.             try:
  429.                 self.length = int(length)
  430.             except ValueError:
  431.                 self.length = None
  432.  
  433.             if self.length < 0:
  434.                 self.length = None
  435.             
  436.         else:
  437.             self.length = None
  438.         if not status == NO_CONTENT and status == NOT_MODIFIED:
  439.             if status <= status:
  440.                 pass
  441.             elif status < 200 or self._method == 'HEAD':
  442.                 self.length = 0
  443.             
  444.         if not (self.will_close) and not (self.chunked) and self.length is None:
  445.             self.will_close = 1
  446.         
  447.  
  448.     
  449.     def _check_close(self):
  450.         conn = self.msg.getheader('connection')
  451.         if self.version == 11:
  452.             conn = self.msg.getheader('connection')
  453.             if conn and 'close' in conn.lower():
  454.                 return True
  455.             return False
  456.         if self.msg.getheader('keep-alive'):
  457.             return False
  458.         if conn and 'keep-alive' in conn.lower():
  459.             return False
  460.         pconn = self.msg.getheader('proxy-connection')
  461.         if pconn and 'keep-alive' in pconn.lower():
  462.             return False
  463.         return True
  464.  
  465.     
  466.     def close(self):
  467.         if self.fp:
  468.             self.fp.close()
  469.             self.fp = None
  470.         
  471.  
  472.     
  473.     def isclosed(self):
  474.         return self.fp is None
  475.  
  476.     
  477.     def read(self, amt = None):
  478.         if self.fp is None:
  479.             return ''
  480.         if self.chunked:
  481.             return self._read_chunked(amt)
  482.         if amt is None:
  483.             self.close()
  484.             return s
  485.         s = self.fp.read(amt)
  486.         return s
  487.  
  488.     
  489.     def _read_chunked(self, amt):
  490.         if not self.chunked != _UNKNOWN:
  491.             raise AssertionError
  492.         chunk_left = self.chunk_left
  493.         value = ''
  494.         while True:
  495.             if chunk_left is None:
  496.                 line = self.fp.readline()
  497.                 i = line.find(';')
  498.                 if i >= 0:
  499.                     line = line[:i]
  500.                 
  501.                 
  502.                 try:
  503.                     chunk_left = int(line, 16)
  504.                 except ValueError:
  505.                     self.close()
  506.                     raise IncompleteRead(value)
  507.  
  508.                 if chunk_left == 0:
  509.                     break
  510.                 
  511.             
  512.             if amt is None:
  513.                 value += self._safe_read(chunk_left)
  514.             elif amt < chunk_left:
  515.                 value += self._safe_read(amt)
  516.                 self.chunk_left = chunk_left - amt
  517.                 return value
  518.             if amt == chunk_left:
  519.                 value += self._safe_read(amt)
  520.                 self._safe_read(2)
  521.                 self.chunk_left = None
  522.                 return value
  523.             value += self._safe_read(chunk_left)
  524.             amt -= chunk_left
  525.             self._safe_read(2)
  526.             chunk_left = None
  527.             continue
  528.             amt == chunk_left
  529.         while True:
  530.             line = self.fp.readline()
  531.             if not line:
  532.                 break
  533.             
  534.             if line == '\r\n':
  535.                 break
  536.                 continue
  537.         self.close()
  538.         return value
  539.  
  540.     
  541.     def _safe_read(self, amt):
  542.         '''Read the number of bytes requested, compensating for partial reads.
  543.  
  544.         Normally, we have a blocking socket, but a read() can be interrupted
  545.         by a signal (resulting in a partial read).
  546.  
  547.         Note that we cannot distinguish between EOF and an interrupt when zero
  548.         bytes have been read. IncompleteRead() will be raised in this
  549.         situation.
  550.  
  551.         This function should be used when <amt> bytes "should" be present for
  552.         reading. If the bytes are truly not available (due to EOF), then the
  553.         IncompleteRead exception can be used to detect the problem.
  554.         '''
  555.         s = []
  556.         while amt > 0:
  557.             chunk = self.fp.read(min(amt, MAXAMOUNT))
  558.             if not chunk:
  559.                 raise IncompleteRead(''.join(s), amt)
  560.             chunk
  561.             s.append(chunk)
  562.             amt -= len(chunk)
  563.         return ''.join(s)
  564.  
  565.     
  566.     def getheader(self, name, default = None):
  567.         if self.msg is None:
  568.             raise ResponseNotReady()
  569.         self.msg is None
  570.         return self.msg.getheader(name, default)
  571.  
  572.     
  573.     def getheaders(self):
  574.         '''Return list of (header, value) tuples.'''
  575.         if self.msg is None:
  576.             raise ResponseNotReady()
  577.         self.msg is None
  578.         return self.msg.items()
  579.  
  580.  
  581.  
  582. class HTTPConnection:
  583.     _http_vsn = 11
  584.     _http_vsn_str = 'HTTP/1.1'
  585.     response_class = HTTPResponse
  586.     default_port = HTTP_PORT
  587.     auto_open = 1
  588.     debuglevel = 0
  589.     strict = 0
  590.     
  591.     def __init__(self, host, port = None, strict = None, timeout = socket._GLOBAL_DEFAULT_TIMEOUT):
  592.         self.timeout = timeout
  593.         self.sock = None
  594.         self._buffer = []
  595.         self._HTTPConnection__response = None
  596.         self._HTTPConnection__state = _CS_IDLE
  597.         self._method = None
  598.         self._set_hostport(host, port)
  599.         if strict is not None:
  600.             self.strict = strict
  601.         
  602.  
  603.     
  604.     def _set_hostport(self, host, port):
  605.         if port is None:
  606.             i = host.rfind(':')
  607.             j = host.rfind(']')
  608.             if i > j:
  609.                 
  610.                 try:
  611.                     port = int(host[i + 1:])
  612.                 except ValueError:
  613.                     raise InvalidURL("nonnumeric port: '%s'" % host[i + 1:])
  614.  
  615.                 host = host[:i]
  616.             else:
  617.                 port = self.default_port
  618.             if host and host[0] == '[' and host[-1] == ']':
  619.                 host = host[1:-1]
  620.             
  621.         
  622.         self.host = host
  623.         self.port = port
  624.  
  625.     
  626.     def set_debuglevel(self, level):
  627.         self.debuglevel = level
  628.  
  629.     
  630.     def connect(self):
  631.         '''Connect to the host and port specified in __init__.'''
  632.         self.sock = socket.create_connection((self.host, self.port), self.timeout)
  633.  
  634.     
  635.     def close(self):
  636.         '''Close the connection to the HTTP server.'''
  637.         if self.sock:
  638.             self.sock.close()
  639.             self.sock = None
  640.         
  641.         if self._HTTPConnection__response:
  642.             self._HTTPConnection__response.close()
  643.             self._HTTPConnection__response = None
  644.         
  645.         self._HTTPConnection__state = _CS_IDLE
  646.  
  647.     
  648.     def send(self, str):
  649.         """Send `str' to the server."""
  650.         if self.sock is None:
  651.             if self.auto_open:
  652.                 self.connect()
  653.             else:
  654.                 raise NotConnected()
  655.         self.auto_open
  656.         if self.debuglevel > 0:
  657.             print 'send:', repr(str)
  658.         
  659.         
  660.         try:
  661.             blocksize = 8192
  662.             if hasattr(str, 'read'):
  663.                 if self.debuglevel > 0:
  664.                     print 'sendIng a read()able'
  665.                 
  666.                 data = str.read(blocksize)
  667.                 while data:
  668.                     self.sock.sendall(data)
  669.                     data = str.read(blocksize)
  670.             else:
  671.                 self.sock.sendall(str)
  672.         except socket.error:
  673.             v = None
  674.             if v[0] == 32:
  675.                 self.close()
  676.             
  677.             raise 
  678.  
  679.  
  680.     
  681.     def _output(self, s):
  682.         '''Add a line of output to the current request buffer.
  683.  
  684.         Assumes that the line does *not* end with \\r\\n.
  685.         '''
  686.         self._buffer.append(s)
  687.  
  688.     
  689.     def _send_output(self):
  690.         '''Send the currently buffered request and clear the buffer.
  691.  
  692.         Appends an extra \\r\\n to the buffer.
  693.         '''
  694.         self._buffer.extend(('', ''))
  695.         msg = '\r\n'.join(self._buffer)
  696.         del self._buffer[:]
  697.         self.send(msg)
  698.  
  699.     
  700.     def putrequest(self, method, url, skip_host = 0, skip_accept_encoding = 0):
  701.         """Send a request to the server.
  702.  
  703.         `method' specifies an HTTP request method, e.g. 'GET'.
  704.         `url' specifies the object being requested, e.g. '/index.html'.
  705.         `skip_host' if True does not add automatically a 'Host:' header
  706.         `skip_accept_encoding' if True does not add automatically an
  707.            'Accept-Encoding:' header
  708.         """
  709.         if self._HTTPConnection__response and self._HTTPConnection__response.isclosed():
  710.             self._HTTPConnection__response = None
  711.         
  712.         if self._HTTPConnection__state == _CS_IDLE:
  713.             self._HTTPConnection__state = _CS_REQ_STARTED
  714.         else:
  715.             raise CannotSendRequest()
  716.         self._method = self._HTTPConnection__state == _CS_IDLE
  717.         if not url:
  718.             url = '/'
  719.         
  720.         str = '%s %s %s' % (method, url, self._http_vsn_str)
  721.         self._output(str)
  722.         if self._http_vsn == 11:
  723.             if not skip_host:
  724.                 netloc = ''
  725.                 if url.startswith('http'):
  726.                     (nil, netloc, nil, nil, nil) = urlsplit(url)
  727.                 
  728.                 if netloc:
  729.                     
  730.                     try:
  731.                         netloc_enc = netloc.encode('ascii')
  732.                     except UnicodeEncodeError:
  733.                         netloc_enc = netloc.encode('idna')
  734.  
  735.                     self.putheader('Host', netloc_enc)
  736.                 else:
  737.                     
  738.                     try:
  739.                         host_enc = self.host.encode('ascii')
  740.                     except UnicodeEncodeError:
  741.                         host_enc = self.host.encode('idna')
  742.  
  743.                     if self.port == self.default_port:
  744.                         self.putheader('Host', host_enc)
  745.                     else:
  746.                         self.putheader('Host', '%s:%s' % (host_enc, self.port))
  747.             
  748.             if not skip_accept_encoding:
  749.                 self.putheader('Accept-Encoding', 'identity')
  750.             
  751.         
  752.  
  753.     
  754.     def putheader(self, header, value):
  755.         """Send a request header line to the server.
  756.  
  757.         For example: h.putheader('Accept', 'text/html')
  758.         """
  759.         if self._HTTPConnection__state != _CS_REQ_STARTED:
  760.             raise CannotSendHeader()
  761.         self._HTTPConnection__state != _CS_REQ_STARTED
  762.         str = '%s: %s' % (header, value)
  763.         self._output(str)
  764.  
  765.     
  766.     def endheaders(self):
  767.         '''Indicate that the last header line has been sent to the server.'''
  768.         if self._HTTPConnection__state == _CS_REQ_STARTED:
  769.             self._HTTPConnection__state = _CS_REQ_SENT
  770.         else:
  771.             raise CannotSendHeader()
  772.         (self._HTTPConnection__state == _CS_REQ_STARTED)._send_output()
  773.  
  774.     
  775.     def request(self, method, url, body = None, headers = { }):
  776.         '''Send a complete request to the server.'''
  777.         
  778.         try:
  779.             self._send_request(method, url, body, headers)
  780.         except socket.error:
  781.             v = None
  782.             if v[0] != 32 or not (self.auto_open):
  783.                 raise 
  784.             not (self.auto_open)
  785.             self._send_request(method, url, body, headers)
  786.  
  787.  
  788.     
  789.     def _send_request(self, method, url, body, headers):
  790.         header_names = []([ k.lower() for k in headers ])
  791.         skips = { }
  792.         if 'accept-encoding' in header_names:
  793.             skips['skip_accept_encoding'] = 1
  794.         
  795.         self.putrequest(method, url, **skips)
  796.         if body and 'content-length' not in header_names:
  797.             thelen = None
  798.             
  799.             try:
  800.                 thelen = str(len(body))
  801.             except TypeError:
  802.                 te = None
  803.                 import os
  804.                 
  805.                 try:
  806.                     thelen = str(os.fstat(body.fileno()).st_size)
  807.                 except (AttributeError, OSError):
  808.                     if self.debuglevel > 0:
  809.                         print 'Cannot stat!!'
  810.                     
  811.                 except:
  812.                     self.debuglevel > 0
  813.                 
  814.  
  815.                 None<EXCEPTION MATCH>(AttributeError, OSError)
  816.  
  817.             if thelen is not None:
  818.                 self.putheader('Content-Length', thelen)
  819.             
  820.         
  821.         for hdr, value in headers.iteritems():
  822.             self.putheader(hdr, value)
  823.         
  824.         self.endheaders()
  825.         if body:
  826.             self.send(body)
  827.         
  828.  
  829.     
  830.     def getresponse(self):
  831.         '''Get the response from the server.'''
  832.         if self._HTTPConnection__response and self._HTTPConnection__response.isclosed():
  833.             self._HTTPConnection__response = None
  834.         
  835.         if self._HTTPConnection__state != _CS_REQ_SENT or self._HTTPConnection__response:
  836.             raise ResponseNotReady()
  837.         self._HTTPConnection__response
  838.         if self.debuglevel > 0:
  839.             response = self.response_class(self.sock, self.debuglevel, strict = self.strict, method = self._method)
  840.         else:
  841.             response = self.response_class(self.sock, strict = self.strict, method = self._method)
  842.         response.begin()
  843.         if not response.will_close != _UNKNOWN:
  844.             raise AssertionError
  845.         self._HTTPConnection__state = _CS_IDLE
  846.         if response.will_close:
  847.             self.close()
  848.         else:
  849.             self._HTTPConnection__response = response
  850.         return response
  851.  
  852.  
  853.  
  854. class HTTP:
  855.     '''Compatibility class with httplib.py from 1.5.'''
  856.     _http_vsn = 10
  857.     _http_vsn_str = 'HTTP/1.0'
  858.     debuglevel = 0
  859.     _connection_class = HTTPConnection
  860.     
  861.     def __init__(self, host = '', port = None, strict = None):
  862.         '''Provide a default host, since the superclass requires one.'''
  863.         if port == 0:
  864.             port = None
  865.         
  866.         self._setup(self._connection_class(host, port, strict))
  867.  
  868.     
  869.     def _setup(self, conn):
  870.         self._conn = conn
  871.         self.send = conn.send
  872.         self.putrequest = conn.putrequest
  873.         self.endheaders = conn.endheaders
  874.         self.set_debuglevel = conn.set_debuglevel
  875.         conn._http_vsn = self._http_vsn
  876.         conn._http_vsn_str = self._http_vsn_str
  877.         self.file = None
  878.  
  879.     
  880.     def connect(self, host = None, port = None):
  881.         """Accept arguments to set the host/port, since the superclass doesn't."""
  882.         if host is not None:
  883.             self._conn._set_hostport(host, port)
  884.         
  885.         self._conn.connect()
  886.  
  887.     
  888.     def getfile(self):
  889.         """Provide a getfile, since the superclass' does not use this concept."""
  890.         return self.file
  891.  
  892.     
  893.     def putheader(self, header, *values):
  894.         '''The superclass allows only one value argument.'''
  895.         self._conn.putheader(header, '\r\n\t'.join(values))
  896.  
  897.     
  898.     def getreply(self):
  899.         '''Compat definition since superclass does not define it.
  900.  
  901.         Returns a tuple consisting of:
  902.         - server status code (e.g. \'200\' if all goes well)
  903.         - server "reason" corresponding to status code
  904.         - any RFC822 headers in the response from the server
  905.         '''
  906.         
  907.         try:
  908.             response = self._conn.getresponse()
  909.         except BadStatusLine:
  910.             e = None
  911.             self.file = self._conn.sock.makefile('rb', 0)
  912.             self.close()
  913.             self.headers = None
  914.             return (-1, e.line, None)
  915.  
  916.         self.headers = response.msg
  917.         self.file = response.fp
  918.         return (response.status, response.reason, response.msg)
  919.  
  920.     
  921.     def close(self):
  922.         self._conn.close()
  923.         self.file = None
  924.  
  925.  
  926.  
  927. try:
  928.     import ssl
  929. except ImportError:
  930.     warnings.catch_warnings().__exit__
  931.     warnings.catch_warnings().__exit__
  932.     warnings.catch_warnings()
  933. except:
  934.     warnings.catch_warnings().__exit__
  935.  
  936.  
  937. class HTTPSConnection(HTTPConnection):
  938.     '''This class allows communication via SSL.'''
  939.     default_port = HTTPS_PORT
  940.     
  941.     def __init__(self, host, port = None, key_file = None, cert_file = None, strict = None, timeout = socket._GLOBAL_DEFAULT_TIMEOUT):
  942.         HTTPConnection.__init__(self, host, port, strict, timeout)
  943.         self.key_file = key_file
  944.         self.cert_file = cert_file
  945.  
  946.     
  947.     def connect(self):
  948.         '''Connect to a host on a given (SSL) port.'''
  949.         sock = socket.create_connection((self.host, self.port), self.timeout)
  950.         self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
  951.  
  952.  
  953. __all__.append('HTTPSConnection')
  954.  
  955. class HTTPS(HTTP):
  956.     '''Compatibility with 1.5 httplib interface
  957.  
  958.         Python 1.5.2 did not have an HTTPS class, but it defined an
  959.         interface for sending http requests that is also useful for
  960.         https.
  961.         '''
  962.     _connection_class = HTTPSConnection
  963.     
  964.     def __init__(self, host = '', port = None, key_file = None, cert_file = None, strict = None):
  965.         if port == 0:
  966.             port = None
  967.         
  968.         self._setup(self._connection_class(host, port, key_file, cert_file, strict))
  969.         self.key_file = key_file
  970.         self.cert_file = cert_file
  971.  
  972.  
  973.  
  974. def FakeSocket(sock, sslobj):
  975.     warnings.warn("FakeSocket is deprecated, and won't be in 3.x.  " + 'Use the result of ssl.wrap_socket() directly instead.', DeprecationWarning, stacklevel = 2)
  976.     return sslobj
  977.  
  978.  
  979. class HTTPException(Exception):
  980.     pass
  981.  
  982.  
  983. class NotConnected(HTTPException):
  984.     pass
  985.  
  986.  
  987. class InvalidURL(HTTPException):
  988.     pass
  989.  
  990.  
  991. class UnknownProtocol(HTTPException):
  992.     
  993.     def __init__(self, version):
  994.         self.args = (version,)
  995.         self.version = version
  996.  
  997.  
  998.  
  999. class UnknownTransferEncoding(HTTPException):
  1000.     pass
  1001.  
  1002.  
  1003. class UnimplementedFileMode(HTTPException):
  1004.     pass
  1005.  
  1006.  
  1007. class IncompleteRead(HTTPException):
  1008.     
  1009.     def __init__(self, partial, expected = None):
  1010.         self.args = (partial,)
  1011.         self.partial = partial
  1012.         self.expected = expected
  1013.  
  1014.     
  1015.     def __repr__(self):
  1016.         if self.expected is not None:
  1017.             e = ', %i more expected' % self.expected
  1018.         else:
  1019.             e = ''
  1020.         return 'IncompleteRead(%i bytes read%s)' % (len(self.partial), e)
  1021.  
  1022.     
  1023.     def __str__(self):
  1024.         return repr(self)
  1025.  
  1026.  
  1027.  
  1028. class ImproperConnectionState(HTTPException):
  1029.     pass
  1030.  
  1031.  
  1032. class CannotSendRequest(ImproperConnectionState):
  1033.     pass
  1034.  
  1035.  
  1036. class CannotSendHeader(ImproperConnectionState):
  1037.     pass
  1038.  
  1039.  
  1040. class ResponseNotReady(ImproperConnectionState):
  1041.     pass
  1042.  
  1043.  
  1044. class BadStatusLine(HTTPException):
  1045.     
  1046.     def __init__(self, line):
  1047.         self.args = (line,)
  1048.         self.line = line
  1049.  
  1050.  
  1051. error = HTTPException
  1052.  
  1053. class LineAndFileWrapper:
  1054.     '''A limited file-like object for HTTP/0.9 responses.'''
  1055.     
  1056.     def __init__(self, line, file):
  1057.         self._line = line
  1058.         self._file = file
  1059.         self._line_consumed = 0
  1060.         self._line_offset = 0
  1061.         self._line_left = len(line)
  1062.  
  1063.     
  1064.     def __getattr__(self, attr):
  1065.         return getattr(self._file, attr)
  1066.  
  1067.     
  1068.     def _done(self):
  1069.         self._line_consumed = 1
  1070.         self.read = self._file.read
  1071.         self.readline = self._file.readline
  1072.         self.readlines = self._file.readlines
  1073.  
  1074.     
  1075.     def read(self, amt = None):
  1076.         if self._line_consumed:
  1077.             return self._file.read(amt)
  1078.         if not self._line_left:
  1079.             raise AssertionError
  1080.         if amt is None or amt > self._line_left:
  1081.             s = self._line[self._line_offset:]
  1082.             self._done()
  1083.             if amt is None:
  1084.                 return s + self._file.read()
  1085.             return s + self._file.read(amt - len(s))
  1086.         amt > self._line_left
  1087.         if not amt <= self._line_left:
  1088.             raise AssertionError
  1089.         i = self._line_offset
  1090.         j = i + amt
  1091.         s = self._line[i:j]
  1092.         self._line_offset = j
  1093.         self._line_left -= amt
  1094.         return s
  1095.  
  1096.     
  1097.     def readline(self):
  1098.         if self._line_consumed:
  1099.             return self._file.readline()
  1100.         if not self._line_left:
  1101.             raise AssertionError
  1102.         s = self._line[self._line_offset:]
  1103.         self._done()
  1104.         return s
  1105.  
  1106.     
  1107.     def readlines(self, size = None):
  1108.         if self._line_consumed:
  1109.             return self._file.readlines(size)
  1110.         if not self._line_left:
  1111.             raise AssertionError
  1112.         L = [
  1113.             self._line[self._line_offset:]]
  1114.         self._done()
  1115.         if size is None:
  1116.             return L + self._file.readlines()
  1117.         return L + self._file.readlines(size)
  1118.  
  1119.  
  1120.  
  1121. def test():
  1122.     '''Test this module.
  1123.  
  1124.     A hodge podge of tests collected here, because they have too many
  1125.     external dependencies for the regular test suite.
  1126.     '''
  1127.     import sys
  1128.     import getopt
  1129.     (opts, args) = getopt.getopt(sys.argv[1:], 'd')
  1130.     dl = 0
  1131.     for o, a in opts:
  1132.         if o == '-d':
  1133.             dl = dl + 1
  1134.             continue
  1135.     
  1136.     host = 'www.python.org'
  1137.     selector = '/'
  1138.     if args[0:]:
  1139.         host = args[0]
  1140.     
  1141.     if args[1:]:
  1142.         selector = args[1]
  1143.     
  1144.     h = HTTP()
  1145.     h.set_debuglevel(dl)
  1146.     h.connect(host)
  1147.     h.putrequest('GET', selector)
  1148.     h.endheaders()
  1149.     (status, reason, headers) = h.getreply()
  1150.     print 'status =', status
  1151.     print 'reason =', reason
  1152.     print 'read', len(h.getfile().read())
  1153.     print 
  1154.     if headers:
  1155.         for header in headers.headers:
  1156.             print header.strip()
  1157.         
  1158.     
  1159.     print 
  1160.     
  1161.     class HTTP11(HTTP):
  1162.         _http_vsn = 11
  1163.         _http_vsn_str = 'HTTP/1.1'
  1164.  
  1165.     h = HTTP11('www.python.org')
  1166.     h.putrequest('GET', 'http://www.python.org/~jeremy/')
  1167.     h.endheaders()
  1168.     h.getreply()
  1169.     h.close()
  1170.     
  1171.     try:
  1172.         import ssl
  1173.     except ImportError:
  1174.         pass
  1175.  
  1176.     for host, selector in (('sourceforge.net', '/projects/python'),):
  1177.         print 'https://%s%s' % (host, selector)
  1178.         hs = HTTPS()
  1179.         hs.set_debuglevel(dl)
  1180.         hs.connect(host)
  1181.         hs.putrequest('GET', selector)
  1182.         hs.endheaders()
  1183.         (status, reason, headers) = hs.getreply()
  1184.         print 'status =', status
  1185.         print 'reason =', reason
  1186.         print 'read', len(hs.getfile().read())
  1187.         print 
  1188.         if headers:
  1189.             for header in headers.headers:
  1190.                 print header.strip()
  1191.             
  1192.         
  1193.         print 
  1194.     
  1195.  
  1196.