home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / Calibre / calibre-0.8.18.msi / file_262 / httplib.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-09-09  |  26.5 KB  |  1,021 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.7)
  3.  
  4. from array import array
  5. import os
  6. import socket
  7. from sys import py3kwarning
  8. from urlparse import urlsplit
  9. import warnings
  10. with warnings.catch_warnings():
  11.     if py3kwarning:
  12.         warnings.filterwarnings('ignore', '.*mimetools has been removed', DeprecationWarning)
  13.     import mimetools
  14.  
  15. try:
  16.     from cStringIO import StringIO
  17. except ImportError:
  18.     from StringIO import StringIO
  19.  
  20. __all__ = [
  21.     'HTTP',
  22.     'HTTPResponse',
  23.     'HTTPConnection',
  24.     'HTTPException',
  25.     'NotConnected',
  26.     'UnknownProtocol',
  27.     'UnknownTransferEncoding',
  28.     'UnimplementedFileMode',
  29.     'IncompleteRead',
  30.     'InvalidURL',
  31.     'ImproperConnectionState',
  32.     'CannotSendRequest',
  33.     'CannotSendHeader',
  34.     'ResponseNotReady',
  35.     'BadStatusLine',
  36.     'error',
  37.     'responses']
  38. HTTP_PORT = 80
  39. HTTPS_PORT = 443
  40. _UNKNOWN = 'UNKNOWN'
  41. _CS_IDLE = 'Idle'
  42. _CS_REQ_STARTED = 'Request-started'
  43. _CS_REQ_SENT = 'Request-sent'
  44. CONTINUE = 100
  45. SWITCHING_PROTOCOLS = 101
  46. PROCESSING = 102
  47. OK = 200
  48. CREATED = 201
  49. ACCEPTED = 202
  50. NON_AUTHORITATIVE_INFORMATION = 203
  51. NO_CONTENT = 204
  52. RESET_CONTENT = 205
  53. PARTIAL_CONTENT = 206
  54. MULTI_STATUS = 207
  55. IM_USED = 226
  56. MULTIPLE_CHOICES = 300
  57. MOVED_PERMANENTLY = 301
  58. FOUND = 302
  59. SEE_OTHER = 303
  60. NOT_MODIFIED = 304
  61. USE_PROXY = 305
  62. TEMPORARY_REDIRECT = 307
  63. BAD_REQUEST = 400
  64. UNAUTHORIZED = 401
  65. PAYMENT_REQUIRED = 402
  66. FORBIDDEN = 403
  67. NOT_FOUND = 404
  68. METHOD_NOT_ALLOWED = 405
  69. NOT_ACCEPTABLE = 406
  70. PROXY_AUTHENTICATION_REQUIRED = 407
  71. REQUEST_TIMEOUT = 408
  72. CONFLICT = 409
  73. GONE = 410
  74. LENGTH_REQUIRED = 411
  75. PRECONDITION_FAILED = 412
  76. REQUEST_ENTITY_TOO_LARGE = 413
  77. REQUEST_URI_TOO_LONG = 414
  78. UNSUPPORTED_MEDIA_TYPE = 415
  79. REQUESTED_RANGE_NOT_SATISFIABLE = 416
  80. EXPECTATION_FAILED = 417
  81. UNPROCESSABLE_ENTITY = 422
  82. LOCKED = 423
  83. FAILED_DEPENDENCY = 424
  84. UPGRADE_REQUIRED = 426
  85. INTERNAL_SERVER_ERROR = 500
  86. NOT_IMPLEMENTED = 501
  87. BAD_GATEWAY = 502
  88. SERVICE_UNAVAILABLE = 503
  89. GATEWAY_TIMEOUT = 504
  90. HTTP_VERSION_NOT_SUPPORTED = 505
  91. INSUFFICIENT_STORAGE = 507
  92. NOT_EXTENDED = 510
  93. responses = {
  94.     100: 'Continue',
  95.     101: 'Switching Protocols',
  96.     200: 'OK',
  97.     201: 'Created',
  98.     202: 'Accepted',
  99.     203: 'Non-Authoritative Information',
  100.     204: 'No Content',
  101.     205: 'Reset Content',
  102.     206: 'Partial Content',
  103.     300: 'Multiple Choices',
  104.     301: 'Moved Permanently',
  105.     302: 'Found',
  106.     303: 'See Other',
  107.     304: 'Not Modified',
  108.     305: 'Use Proxy',
  109.     306: '(Unused)',
  110.     307: 'Temporary Redirect',
  111.     400: 'Bad Request',
  112.     401: 'Unauthorized',
  113.     402: 'Payment Required',
  114.     403: 'Forbidden',
  115.     404: 'Not Found',
  116.     405: 'Method Not Allowed',
  117.     406: 'Not Acceptable',
  118.     407: 'Proxy Authentication Required',
  119.     408: 'Request Timeout',
  120.     409: 'Conflict',
  121.     410: 'Gone',
  122.     411: 'Length Required',
  123.     412: 'Precondition Failed',
  124.     413: 'Request Entity Too Large',
  125.     414: 'Request-URI Too Long',
  126.     415: 'Unsupported Media Type',
  127.     416: 'Requested Range Not Satisfiable',
  128.     417: 'Expectation Failed',
  129.     500: 'Internal Server Error',
  130.     501: 'Not Implemented',
  131.     502: 'Bad Gateway',
  132.     503: 'Service Unavailable',
  133.     504: 'Gateway Timeout',
  134.     505: 'HTTP Version Not Supported' }
  135. MAXAMOUNT = 1048576
  136.  
  137. class HTTPMessage(mimetools.Message):
  138.     
  139.     def addheader(self, key, value):
  140.         prev = self.dict.get(key)
  141.         if prev is None:
  142.             self.dict[key] = value
  143.         else:
  144.             combined = ', '.join((prev, value))
  145.             self.dict[key] = combined
  146.  
  147.     
  148.     def addcontinue(self, key, more):
  149.         prev = self.dict[key]
  150.         self.dict[key] = prev + '\n ' + more
  151.  
  152.     
  153.     def readheaders(self):
  154.         self.dict = { }
  155.         self.unixfrom = ''
  156.         self.headers = hlist = []
  157.         self.status = ''
  158.         headerseen = ''
  159.         firstline = 1
  160.         startofline = None
  161.         unread = None
  162.         tell = None
  163.         if hasattr(self.fp, 'unread'):
  164.             unread = self.fp.unread
  165.         elif self.seekable:
  166.             tell = self.fp.tell
  167.         while True:
  168.             if tell:
  169.                 
  170.                 try:
  171.                     startofline = tell()
  172.                 except IOError:
  173.                     startofline = None
  174.                     tell = None
  175.                     self.seekable = 0
  176.                 
  177.  
  178.             line = self.fp.readline()
  179.             if not line:
  180.                 self.status = 'EOF in headers'
  181.                 break
  182.             if firstline and line.startswith('From '):
  183.                 self.unixfrom = self.unixfrom + line
  184.                 continue
  185.             firstline = 0
  186.             if headerseen and line[0] in ' \t':
  187.                 hlist.append(line)
  188.                 self.addcontinue(headerseen, line.strip())
  189.                 continue
  190.             elif self.iscomment(line):
  191.                 continue
  192.             elif self.islast(line):
  193.                 break
  194.             headerseen = self.isheader(line)
  195.             if headerseen:
  196.                 hlist.append(line)
  197.                 self.addheader(headerseen, line[len(headerseen) + 1:].strip())
  198.                 continue
  199.                 continue
  200.             if not self.dict:
  201.                 self.status = 'No headers'
  202.             else:
  203.                 self.status = 'Non-header line where header expected'
  204.             if unread:
  205.                 unread(line)
  206.             elif tell:
  207.                 self.fp.seek(startofline)
  208.             else:
  209.                 self.status = self.status + '; bad seek'
  210.             break
  211.  
  212.  
  213.  
  214. class HTTPResponse:
  215.     
  216.     def __init__(self, sock, debuglevel = 0, strict = 0, method = None, buffering = False):
  217.         if buffering:
  218.             self.fp = sock.makefile('rb')
  219.         else:
  220.             self.fp = sock.makefile('rb', 0)
  221.         self.debuglevel = debuglevel
  222.         self.strict = strict
  223.         self._method = method
  224.         self.msg = None
  225.         self.version = _UNKNOWN
  226.         self.status = _UNKNOWN
  227.         self.reason = _UNKNOWN
  228.         self.chunked = _UNKNOWN
  229.         self.chunk_left = _UNKNOWN
  230.         self.length = _UNKNOWN
  231.         self.will_close = _UNKNOWN
  232.  
  233.     
  234.     def _read_status(self):
  235.         line = self.fp.readline()
  236.         if self.debuglevel > 0:
  237.             print 'reply:', repr(line)
  238.         if not line:
  239.             raise BadStatusLine(line)
  240.         
  241.         try:
  242.             (version, status, reason) = line.split(None, 2)
  243.         except ValueError:
  244.             
  245.             try:
  246.                 (version, status) = line.split(None, 1)
  247.                 reason = ''
  248.             except ValueError:
  249.                 version = ''
  250.             
  251.  
  252.  
  253.         if not version.startswith('HTTP/'):
  254.             if self.strict:
  255.                 self.close()
  256.                 raise BadStatusLine(line)
  257.             self.fp = LineAndFileWrapper(line, self.fp)
  258.             return ('HTTP/0.9', 200, '')
  259.         
  260.         try:
  261.             status = int(status)
  262.             if status < 100 or status > 999:
  263.                 raise BadStatusLine(line)
  264.         except ValueError:
  265.             raise BadStatusLine(line)
  266.  
  267.         return (version, status, reason)
  268.  
  269.     
  270.     def begin(self):
  271.         if self.msg is not None:
  272.             return None
  273.         if True:
  274.             (version, status, reason) = self._read_status()
  275.             if status != CONTINUE:
  276.                 break
  277.             while True:
  278.                 skip = self.fp.readline().strip()
  279.                 if not skip:
  280.                     break
  281.                 if self.debuglevel > 0:
  282.                     print 'header:', skip
  283.                     continue
  284.             self.status = status
  285.             self.reason = reason.strip()
  286.             if version == 'HTTP/1.0':
  287.                 self.version = 10
  288.             elif version.startswith('HTTP/1.'):
  289.                 self.version = 11
  290.             elif version == 'HTTP/0.9':
  291.                 self.version = 9
  292.             else:
  293.                 raise UnknownProtocol(version)
  294.             if None.version == 9:
  295.                 self.length = None
  296.                 self.chunked = 0
  297.                 self.will_close = 1
  298.                 self.msg = HTTPMessage(StringIO())
  299.                 return None
  300.             self.msg = None(self.fp, 0)
  301.             if self.debuglevel > 0:
  302.                 for hdr in self.msg.headers:
  303.                     print 'header:', hdr,
  304.                 
  305.             self.msg.fp = None
  306.             tr_enc = self.msg.getheader('transfer-encoding')
  307.             if tr_enc and tr_enc.lower() == 'chunked':
  308.                 self.chunked = 1
  309.                 self.chunk_left = None
  310.             else:
  311.                 self.chunked = 0
  312.         self.will_close = self._check_close()
  313.         length = self.msg.getheader('content-length')
  314.         if length and not (self.chunked):
  315.             
  316.             try:
  317.                 self.length = int(length)
  318.             except ValueError:
  319.                 self.length = None
  320.  
  321.             if self.length < 0:
  322.                 self.length = None
  323.             
  324.         else:
  325.             self.length = None
  326.         if not status == NO_CONTENT and status == NOT_MODIFIED:
  327.             if status <= status:
  328.                 pass
  329.             elif status < 200 or self._method == 'HEAD':
  330.                 self.length = 0
  331.             if not (self.will_close) and not (self.chunked) and self.length is None:
  332.                 self.will_close = 1
  333.             return None
  334.  
  335.     
  336.     def _check_close(self):
  337.         conn = self.msg.getheader('connection')
  338.         if self.version == 11:
  339.             conn = self.msg.getheader('connection')
  340.             if conn and 'close' in conn.lower():
  341.                 return True
  342.             return None
  343.         if None.msg.getheader('keep-alive'):
  344.             return False
  345.         if None and 'keep-alive' in conn.lower():
  346.             return False
  347.         pconn = None.msg.getheader('proxy-connection')
  348.         if pconn and 'keep-alive' in pconn.lower():
  349.             return False
  350.  
  351.     
  352.     def close(self):
  353.         if self.fp:
  354.             self.fp.close()
  355.             self.fp = None
  356.  
  357.     
  358.     def isclosed(self):
  359.         return self.fp is None
  360.  
  361.     
  362.     def read(self, amt = None):
  363.         if self.fp is None:
  364.             return ''
  365.         if None._method == 'HEAD':
  366.             self.close()
  367.             return ''
  368.         if None.chunked:
  369.             return self._read_chunked(amt)
  370.         if None is None:
  371.             if self.length is None:
  372.                 s = self.fp.read()
  373.             else:
  374.                 s = self._safe_read(self.length)
  375.                 self.length = 0
  376.             self.close()
  377.             return s
  378.         if None.length is not None and amt > self.length:
  379.             amt = self.length
  380.         
  381.         s = self.fp.read(amt)
  382.         if self.length is not None:
  383.             self.length -= len(s)
  384.             if not self.length:
  385.                 self.close()
  386.             
  387.         return s
  388.  
  389.     
  390.     def _read_chunked(self, amt):
  391.         chunk_left = self.chunk_left
  392.         value = []
  393.         while True:
  394.             if chunk_left is None:
  395.                 line = self.fp.readline()
  396.                 i = line.find(';')
  397.                 if i >= 0:
  398.                     line = line[:i]
  399.                 
  400.                 try:
  401.                     chunk_left = int(line, 16)
  402.                 except ValueError:
  403.                     self.close()
  404.                     raise IncompleteRead(''.join(value))
  405.  
  406.                 if chunk_left == 0:
  407.                     break
  408.                 
  409.             if amt is None:
  410.                 value.append(self._safe_read(chunk_left))
  411.             elif amt < chunk_left:
  412.                 value.append(self._safe_read(amt))
  413.                 self.chunk_left = chunk_left - amt
  414.                 return ''.join(value)
  415.             if amt == chunk_left:
  416.                 value.append(self._safe_read(amt))
  417.                 self._safe_read(2)
  418.                 self.chunk_left = None
  419.                 return ''.join(value)
  420.             None.append(self._safe_read(chunk_left))
  421.             amt -= chunk_left
  422.             self._safe_read(2)
  423.             chunk_left = None
  424.         while True:
  425.             line = self.fp.readline()
  426.             if not line:
  427.                 break
  428.             if line == '\r\n':
  429.                 break
  430.                 continue
  431.             self.close()
  432.             return ''.join(value)
  433.  
  434.     
  435.     def _safe_read(self, amt):
  436.         s = []
  437.         while amt > 0:
  438.             chunk = self.fp.read(min(amt, MAXAMOUNT))
  439.             if not chunk:
  440.                 raise IncompleteRead(''.join(s), amt)
  441.             s.append(chunk)
  442.             amt -= len(chunk)
  443.         return ''.join(s)
  444.  
  445.     
  446.     def fileno(self):
  447.         return self.fp.fileno()
  448.  
  449.     
  450.     def getheader(self, name, default = None):
  451.         if self.msg is None:
  452.             raise ResponseNotReady()
  453.         return self.msg.getheader(name, default)
  454.  
  455.     
  456.     def getheaders(self):
  457.         if self.msg is None:
  458.             raise ResponseNotReady()
  459.         return self.msg.items()
  460.  
  461.  
  462.  
  463. class HTTPConnection:
  464.     _http_vsn = 11
  465.     _http_vsn_str = 'HTTP/1.1'
  466.     response_class = HTTPResponse
  467.     default_port = HTTP_PORT
  468.     auto_open = 1
  469.     debuglevel = 0
  470.     strict = 0
  471.     
  472.     def __init__(self, host, port = None, strict = None, timeout = socket._GLOBAL_DEFAULT_TIMEOUT, source_address = None):
  473.         self.timeout = timeout
  474.         self.source_address = source_address
  475.         self.sock = None
  476.         self._buffer = []
  477.         self._HTTPConnection__response = None
  478.         self._HTTPConnection__state = _CS_IDLE
  479.         self._method = None
  480.         self._tunnel_host = None
  481.         self._tunnel_port = None
  482.         self._tunnel_headers = { }
  483.         self._set_hostport(host, port)
  484.         if strict is not None:
  485.             self.strict = strict
  486.  
  487.     
  488.     def set_tunnel(self, host, port = None, headers = None):
  489.         self._tunnel_host = host
  490.         self._tunnel_port = port
  491.         if headers:
  492.             self._tunnel_headers = headers
  493.         else:
  494.             self._tunnel_headers.clear()
  495.  
  496.     
  497.     def _set_hostport(self, host, port):
  498.         if port is None:
  499.             i = host.rfind(':')
  500.             j = host.rfind(']')
  501.             if i > j:
  502.                 
  503.                 try:
  504.                     port = int(host[i + 1:])
  505.                 except ValueError:
  506.                     raise InvalidURL("nonnumeric port: '%s'" % host[i + 1:])
  507.  
  508.                 host = host[:i]
  509.             else:
  510.                 port = self.default_port
  511.             if host and host[0] == '[' and host[-1] == ']':
  512.                 host = host[1:-1]
  513.             
  514.         self.host = host
  515.         self.port = port
  516.  
  517.     
  518.     def set_debuglevel(self, level):
  519.         self.debuglevel = level
  520.  
  521.     
  522.     def _tunnel(self):
  523.         self._set_hostport(self._tunnel_host, self._tunnel_port)
  524.         self.send('CONNECT %s:%d HTTP/1.0\r\n' % (self.host, self.port))
  525.         for header, value in self._tunnel_headers.iteritems():
  526.             self.send('%s: %s\r\n' % (header, value))
  527.         
  528.         self.send('\r\n')
  529.         response = self.response_class(self.sock, strict = self.strict, method = self._method)
  530.         (version, code, message) = response._read_status()
  531.         if code != 200:
  532.             self.close()
  533.             raise socket.error('Tunnel connection failed: %d %s' % (code, message.strip()))
  534.         while True:
  535.             line = response.fp.readline()
  536.             if line == '\r\n':
  537.                 break
  538.                 continue
  539.             return None
  540.  
  541.     
  542.     def connect(self):
  543.         self.sock = socket.create_connection((self.host, self.port), self.timeout, self.source_address)
  544.         if self._tunnel_host:
  545.             self._tunnel()
  546.  
  547.     
  548.     def close(self):
  549.         if self.sock:
  550.             self.sock.close()
  551.             self.sock = None
  552.         if self._HTTPConnection__response:
  553.             self._HTTPConnection__response.close()
  554.             self._HTTPConnection__response = None
  555.         self._HTTPConnection__state = _CS_IDLE
  556.  
  557.     
  558.     def send(self, data):
  559.         if self.sock is None:
  560.             if self.auto_open:
  561.                 self.connect()
  562.             else:
  563.                 raise NotConnected()
  564.         if self.debuglevel > 0:
  565.             print 'send:', repr(data)
  566.         blocksize = 8192
  567.         if hasattr(data, 'read') and not isinstance(data, array):
  568.             if self.debuglevel > 0:
  569.                 print 'sendIng a read()able'
  570.             datablock = data.read(blocksize)
  571.             while datablock:
  572.                 self.sock.sendall(datablock)
  573.                 datablock = data.read(blocksize)
  574.         else:
  575.             self.sock.sendall(data)
  576.  
  577.     
  578.     def _output(self, s):
  579.         self._buffer.append(s)
  580.  
  581.     
  582.     def _send_output(self, message_body = None):
  583.         self._buffer.extend(('', ''))
  584.         msg = '\r\n'.join(self._buffer)
  585.         del self._buffer[:]
  586.         if isinstance(message_body, str):
  587.             msg += message_body
  588.             message_body = None
  589.         self.send(msg)
  590.         if message_body is not None:
  591.             self.send(message_body)
  592.  
  593.     
  594.     def putrequest(self, method, url, skip_host = 0, skip_accept_encoding = 0):
  595.         if self._HTTPConnection__response and self._HTTPConnection__response.isclosed():
  596.             self._HTTPConnection__response = None
  597.         if self._HTTPConnection__state == _CS_IDLE:
  598.             self._HTTPConnection__state = _CS_REQ_STARTED
  599.         else:
  600.             raise CannotSendRequest()
  601.         self._method = None
  602.         if not url:
  603.             url = '/'
  604.         hdr = '%s %s %s' % (method, url, self._http_vsn_str)
  605.         self._output(hdr)
  606.         if self._http_vsn == 11:
  607.             if not skip_host:
  608.                 netloc = ''
  609.                 if url.startswith('http'):
  610.                     (nil, netloc, nil, nil, nil) = urlsplit(url)
  611.                 if netloc:
  612.                     
  613.                     try:
  614.                         netloc_enc = netloc.encode('ascii')
  615.                     except UnicodeEncodeError:
  616.                         netloc_enc = netloc.encode('idna')
  617.  
  618.                     self.putheader('Host', netloc_enc)
  619.                 else:
  620.                     
  621.                     try:
  622.                         host_enc = self.host.encode('ascii')
  623.                     except UnicodeEncodeError:
  624.                         host_enc = self.host.encode('idna')
  625.  
  626.                     if host_enc.find(':') >= 0:
  627.                         host_enc = '[' + host_enc + ']'
  628.                     if self.port == self.default_port:
  629.                         self.putheader('Host', host_enc)
  630.                     else:
  631.                         self.putheader('Host', '%s:%s' % (host_enc, self.port))
  632.             if not skip_accept_encoding:
  633.                 self.putheader('Accept-Encoding', 'identity')
  634.             
  635.  
  636.     
  637.     def putheader(self, header, *values):
  638.         if self._HTTPConnection__state != _CS_REQ_STARTED:
  639.             raise CannotSendHeader()
  640.         hdr = '%s: %s' % (header, '\r\n\t'.join([ str(v) for v in values ]))
  641.         self._output(hdr)
  642.  
  643.     
  644.     def endheaders(self, message_body = None):
  645.         if self._HTTPConnection__state == _CS_REQ_STARTED:
  646.             self._HTTPConnection__state = _CS_REQ_SENT
  647.         else:
  648.             raise CannotSendHeader()
  649.         None._send_output(message_body)
  650.  
  651.     
  652.     def request(self, method, url, body = None, headers = { }):
  653.         self._send_request(method, url, body, headers)
  654.  
  655.     
  656.     def _set_content_length(self, body):
  657.         thelen = None
  658.         
  659.         try:
  660.             thelen = str(len(body))
  661.         except TypeError:
  662.             te = None
  663.             
  664.             try:
  665.                 thelen = str(os.fstat(body.fileno()).st_size)
  666.             except (AttributeError, OSError):
  667.                 if self.debuglevel > 0:
  668.                     print 'Cannot stat!!'
  669.                 
  670.             
  671.  
  672.  
  673.         if thelen is not None:
  674.             self.putheader('Content-Length', thelen)
  675.  
  676.     
  677.     def _send_request(self, method, url, body, headers):
  678.         header_names = dict.fromkeys([ k.lower() for k in headers ])
  679.         skips = { }
  680.         if 'host' in header_names:
  681.             skips['skip_host'] = 1
  682.         if 'accept-encoding' in header_names:
  683.             skips['skip_accept_encoding'] = 1
  684.         self.putrequest(method, url, **skips)
  685.         if body and 'content-length' not in header_names:
  686.             self._set_content_length(body)
  687.         for hdr, value in headers.iteritems():
  688.             self.putheader(hdr, value)
  689.         
  690.         self.endheaders(body)
  691.  
  692.     
  693.     def getresponse(self, buffering = False):
  694.         if self._HTTPConnection__response and self._HTTPConnection__response.isclosed():
  695.             self._HTTPConnection__response = None
  696.         if self._HTTPConnection__state != _CS_REQ_SENT or self._HTTPConnection__response:
  697.             raise ResponseNotReady()
  698.         args = (self.sock,)
  699.         kwds = {
  700.             'strict': self.strict,
  701.             'method': self._method }
  702.         if self.debuglevel > 0:
  703.             args += (self.debuglevel,)
  704.         if buffering:
  705.             kwds['buffering'] = True
  706.         response = self.response_class(*args, **kwds)
  707.         response.begin()
  708.         self._HTTPConnection__state = _CS_IDLE
  709.         if response.will_close:
  710.             self.close()
  711.         else:
  712.             self._HTTPConnection__response = response
  713.         return response
  714.  
  715.  
  716.  
  717. class HTTP:
  718.     _http_vsn = 10
  719.     _http_vsn_str = 'HTTP/1.0'
  720.     debuglevel = 0
  721.     _connection_class = HTTPConnection
  722.     
  723.     def __init__(self, host = '', port = None, strict = None):
  724.         if port == 0:
  725.             port = None
  726.         self._setup(self._connection_class(host, port, strict))
  727.  
  728.     
  729.     def _setup(self, conn):
  730.         self._conn = conn
  731.         self.send = conn.send
  732.         self.putrequest = conn.putrequest
  733.         self.putheader = conn.putheader
  734.         self.endheaders = conn.endheaders
  735.         self.set_debuglevel = conn.set_debuglevel
  736.         conn._http_vsn = self._http_vsn
  737.         conn._http_vsn_str = self._http_vsn_str
  738.         self.file = None
  739.  
  740.     
  741.     def connect(self, host = None, port = None):
  742.         if host is not None:
  743.             self._conn._set_hostport(host, port)
  744.         self._conn.connect()
  745.  
  746.     
  747.     def getfile(self):
  748.         return self.file
  749.  
  750.     
  751.     def getreply(self, buffering = False):
  752.         
  753.         try:
  754.             if not buffering:
  755.                 response = self._conn.getresponse()
  756.             else:
  757.                 response = self._conn.getresponse(buffering)
  758.         except BadStatusLine:
  759.             e = None
  760.             self.file = self._conn.sock.makefile('rb', 0)
  761.             self.close()
  762.             self.headers = None
  763.             return (-1, e.line, None)
  764.  
  765.         self.headers = response.msg
  766.         self.file = response.fp
  767.         return (response.status, response.reason, response.msg)
  768.  
  769.     
  770.     def close(self):
  771.         self._conn.close()
  772.         self.file = None
  773.  
  774.  
  775.  
  776. try:
  777.     import ssl
  778. except ImportError:
  779.     pass
  780.  
  781.  
  782. class HTTPSConnection(HTTPConnection):
  783.     default_port = HTTPS_PORT
  784.     
  785.     def __init__(self, host, port = None, key_file = None, cert_file = None, strict = None, timeout = socket._GLOBAL_DEFAULT_TIMEOUT, source_address = None):
  786.         HTTPConnection.__init__(self, host, port, strict, timeout, source_address)
  787.         self.key_file = key_file
  788.         self.cert_file = cert_file
  789.  
  790.     
  791.     def connect(self):
  792.         sock = socket.create_connection((self.host, self.port), self.timeout, self.source_address)
  793.         if self._tunnel_host:
  794.             self.sock = sock
  795.             self._tunnel()
  796.         self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
  797.  
  798.  
  799. __all__.append('HTTPSConnection')
  800.  
  801. class HTTPS(HTTP):
  802.     _connection_class = HTTPSConnection
  803.     
  804.     def __init__(self, host = '', port = None, key_file = None, cert_file = None, strict = None):
  805.         if port == 0:
  806.             port = None
  807.         self._setup(self._connection_class(host, port, key_file, cert_file, strict))
  808.         self.key_file = key_file
  809.         self.cert_file = cert_file
  810.  
  811.  
  812.  
  813. def FakeSocket(sock, sslobj):
  814.     warnings.warn("FakeSocket is deprecated, and won't be in 3.x.  " + 'Use the result of ssl.wrap_socket() directly instead.', DeprecationWarning, stacklevel = 2)
  815.     return sslobj
  816.  
  817.  
  818. class HTTPException(Exception):
  819.     pass
  820.  
  821.  
  822. class NotConnected(HTTPException):
  823.     pass
  824.  
  825.  
  826. class InvalidURL(HTTPException):
  827.     pass
  828.  
  829.  
  830. class UnknownProtocol(HTTPException):
  831.     
  832.     def __init__(self, version):
  833.         self.args = (version,)
  834.         self.version = version
  835.  
  836.  
  837.  
  838. class UnknownTransferEncoding(HTTPException):
  839.     pass
  840.  
  841.  
  842. class UnimplementedFileMode(HTTPException):
  843.     pass
  844.  
  845.  
  846. class IncompleteRead(HTTPException):
  847.     
  848.     def __init__(self, partial, expected = None):
  849.         self.args = (partial,)
  850.         self.partial = partial
  851.         self.expected = expected
  852.  
  853.     
  854.     def __repr__(self):
  855.         if self.expected is not None:
  856.             e = ', %i more expected' % self.expected
  857.         else:
  858.             e = ''
  859.         return 'IncompleteRead(%i bytes read%s)' % (len(self.partial), e)
  860.  
  861.     
  862.     def __str__(self):
  863.         return repr(self)
  864.  
  865.  
  866.  
  867. class ImproperConnectionState(HTTPException):
  868.     pass
  869.  
  870.  
  871. class CannotSendRequest(ImproperConnectionState):
  872.     pass
  873.  
  874.  
  875. class CannotSendHeader(ImproperConnectionState):
  876.     pass
  877.  
  878.  
  879. class ResponseNotReady(ImproperConnectionState):
  880.     pass
  881.  
  882.  
  883. class BadStatusLine(HTTPException):
  884.     
  885.     def __init__(self, line):
  886.         if not line:
  887.             line = repr(line)
  888.         self.args = (line,)
  889.         self.line = line
  890.  
  891.  
  892. error = HTTPException
  893.  
  894. class LineAndFileWrapper:
  895.     
  896.     def __init__(self, line, file):
  897.         self._line = line
  898.         self._file = file
  899.         self._line_consumed = 0
  900.         self._line_offset = 0
  901.         self._line_left = len(line)
  902.  
  903.     
  904.     def __getattr__(self, attr):
  905.         return getattr(self._file, attr)
  906.  
  907.     
  908.     def _done(self):
  909.         self._line_consumed = 1
  910.         self.read = self._file.read
  911.         self.readline = self._file.readline
  912.         self.readlines = self._file.readlines
  913.  
  914.     
  915.     def read(self, amt = None):
  916.         if self._line_consumed:
  917.             return self._file.read(amt)
  918.         if None is None or amt > self._line_left:
  919.             s = self._line[self._line_offset:]
  920.             self._done()
  921.             if amt is None:
  922.                 return s + self._file.read()
  923.             return None + self._file.read(amt - len(s))
  924.         i = self._line_offset
  925.         j = i + amt
  926.         s = self._line[i:j]
  927.         self._line_offset = j
  928.         self._line_left -= amt
  929.         if self._line_left == 0:
  930.             self._done()
  931.         return s
  932.  
  933.     
  934.     def readline(self):
  935.         if self._line_consumed:
  936.             return self._file.readline()
  937.         s = None._line[self._line_offset:]
  938.         self._done()
  939.         return s
  940.  
  941.     
  942.     def readlines(self, size = None):
  943.         if self._line_consumed:
  944.             return self._file.readlines(size)
  945.         L = [
  946.             None._line[self._line_offset:]]
  947.         self._done()
  948.         if size is None:
  949.             return L + self._file.readlines()
  950.         return None + self._file.readlines(size)
  951.  
  952.  
  953.  
  954. def test():
  955.     import sys
  956.     import getopt
  957.     (opts, args) = getopt.getopt(sys.argv[1:], 'd')
  958.     dl = 0
  959.     for o, a in opts:
  960.         if o == '-d':
  961.             dl = dl + 1
  962.             continue
  963.     host = 'www.python.org'
  964.     selector = '/'
  965.     if args[0:]:
  966.         host = args[0]
  967.     if args[1:]:
  968.         selector = args[1]
  969.     h = HTTP()
  970.     h.set_debuglevel(dl)
  971.     h.connect(host)
  972.     h.putrequest('GET', selector)
  973.     h.endheaders()
  974.     (status, reason, headers) = h.getreply()
  975.     print 'status =', status
  976.     print 'reason =', reason
  977.     print 'read', len(h.getfile().read())
  978.     print 
  979.     if headers:
  980.         for header in headers.headers:
  981.             print header.strip()
  982.         
  983.     print 
  984.     
  985.     class HTTP11(HTTP):
  986.         _http_vsn = 11
  987.         _http_vsn_str = 'HTTP/1.1'
  988.  
  989.     h = HTTP11('www.python.org')
  990.     h.putrequest('GET', 'http://www.python.org/~jeremy/')
  991.     h.endheaders()
  992.     h.getreply()
  993.     h.close()
  994.     
  995.     try:
  996.         import ssl
  997.     except ImportError:
  998.         pass
  999.  
  1000.     for host, selector in (('sourceforge.net', '/projects/python'),):
  1001.         print 'https://%s%s' % (host, selector)
  1002.         hs = HTTPS()
  1003.         hs.set_debuglevel(dl)
  1004.         hs.connect(host)
  1005.         hs.putrequest('GET', selector)
  1006.         hs.endheaders()
  1007.         (status, reason, headers) = hs.getreply()
  1008.         print 'status =', status
  1009.         print 'reason =', reason
  1010.         print 'read', len(hs.getfile().read())
  1011.         print 
  1012.         if headers:
  1013.             for header in headers.headers:
  1014.                 print header.strip()
  1015.             
  1016.         print 
  1017.     
  1018.  
  1019. if __name__ == '__main__':
  1020.     test()
  1021.