home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_599 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  26.3 KB  |  1,058 lines

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