home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 October / maximum-cd-2011-10.iso / DiscContents / digsby_setup.exe / lib / httplib.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-06-22  |  25.4 KB  |  1,027 lines

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