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

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import base64
  5. import os
  6. import Queue
  7. import re
  8. quoted_slash = re.compile('(?i)%2F')
  9. import rfc822
  10. import socket
  11.  
  12. try:
  13.     import cStringIO as StringIO
  14. except ImportError:
  15.     import StringIO
  16.  
  17. _fileobject_uses_str_type = isinstance(socket._fileobject(None)._rbuf, basestring)
  18. import sys
  19. import threading
  20. import time
  21. import traceback
  22. from urllib import unquote
  23. from urlparse import urlparse
  24. import warnings
  25.  
  26. try:
  27.     from OpenSSL import SSL
  28.     from OpenSSL import crypto
  29. except ImportError:
  30.     SSL = None
  31.  
  32. import errno
  33.  
  34. def plat_specific_errors(*errnames):
  35.     errno_names = dir(errno)
  36.     nums = _[1]
  37.     return dict.fromkeys(nums).keys()
  38.  
  39. socket_error_eintr = plat_specific_errors('EINTR', 'WSAEINTR')
  40. socket_errors_to_ignore = plat_specific_errors('EPIPE', 'EBADF', 'WSAEBADF', 'ENOTSOCK', 'WSAENOTSOCK', 'ETIMEDOUT', 'WSAETIMEDOUT', 'ECONNREFUSED', 'WSAECONNREFUSED', 'ECONNRESET', 'WSAECONNRESET', 'ECONNABORTED', 'WSAECONNABORTED', 'ENETRESET', 'WSAENETRESET', 'EHOSTDOWN', 'EHOSTUNREACH')
  41. socket_errors_to_ignore.append('timed out')
  42. socket_errors_nonblocking = plat_specific_errors('EAGAIN', 'EWOULDBLOCK', 'WSAEWOULDBLOCK')
  43. comma_separated_headers = [
  44.     'ACCEPT',
  45.     'ACCEPT-CHARSET',
  46.     'ACCEPT-ENCODING',
  47.     'ACCEPT-LANGUAGE',
  48.     'ACCEPT-RANGES',
  49.     'ALLOW',
  50.     'CACHE-CONTROL',
  51.     'CONNECTION',
  52.     'CONTENT-ENCODING',
  53.     'CONTENT-LANGUAGE',
  54.     'EXPECT',
  55.     'IF-MATCH',
  56.     'IF-NONE-MATCH',
  57.     'PRAGMA',
  58.     'PROXY-AUTHENTICATE',
  59.     'TE',
  60.     'TRAILER',
  61.     'TRANSFER-ENCODING',
  62.     'UPGRADE',
  63.     'VARY',
  64.     'VIA',
  65.     'WARNING',
  66.     'WWW-AUTHENTICATE']
  67.  
  68. class WSGIPathInfoDispatcher(object):
  69.     
  70.     def __init__(self, apps):
  71.         
  72.         try:
  73.             apps = apps.items()
  74.         except AttributeError:
  75.             pass
  76.  
  77.         apps.sort()
  78.         apps.reverse()
  79.         self.apps = [ (p.rstrip('/'), a) for p, a in apps ]
  80.  
  81.     
  82.     def __call__(self, environ, start_response):
  83.         if not environ['PATH_INFO']:
  84.             pass
  85.         path = '/'
  86.         for p, app in self.apps:
  87.             if path.startswith(p + '/') or path == p:
  88.                 environ = environ.copy()
  89.                 environ['SCRIPT_NAME'] = environ['SCRIPT_NAME'] + p
  90.                 environ['PATH_INFO'] = path[len(p):]
  91.                 return app(environ, start_response)
  92.         
  93.         start_response('404 Not Found', [
  94.             ('Content-Type', 'text/plain'),
  95.             ('Content-Length', '0')])
  96.         return [
  97.             '']
  98.  
  99.  
  100.  
  101. class MaxSizeExceeded(Exception):
  102.     pass
  103.  
  104.  
  105. class SizeCheckWrapper(object):
  106.     
  107.     def __init__(self, rfile, maxlen):
  108.         self.rfile = rfile
  109.         self.maxlen = maxlen
  110.         self.bytes_read = 0
  111.  
  112.     
  113.     def _check_length(self):
  114.         if self.maxlen and self.bytes_read > self.maxlen:
  115.             raise MaxSizeExceeded()
  116.         self.bytes_read > self.maxlen
  117.  
  118.     
  119.     def read(self, size = None):
  120.         data = self.rfile.read(size)
  121.         self.bytes_read += len(data)
  122.         self._check_length()
  123.         return data
  124.  
  125.     
  126.     def readline(self, size = None):
  127.         if size is not None:
  128.             data = self.rfile.readline(size)
  129.             self.bytes_read += len(data)
  130.             self._check_length()
  131.             return data
  132.         res = []
  133.         while True:
  134.             data = self.rfile.readline(256)
  135.             self.bytes_read += len(data)
  136.             self._check_length()
  137.             res.append(data)
  138.             if len(data) < 256 or data[-1:] == '\n':
  139.                 return ''.join(res)
  140.             continue
  141.             data[-1:] == '\n'
  142.  
  143.     
  144.     def readlines(self, sizehint = 0):
  145.         total = 0
  146.         lines = []
  147.         line = self.readline()
  148.         while line:
  149.             lines.append(line)
  150.             total += len(line)
  151.             if sizehint < sizehint:
  152.                 pass
  153.             elif sizehint <= total:
  154.                 break
  155.             
  156.             line = self.readline()
  157.             continue
  158.             0
  159.         return lines
  160.  
  161.     
  162.     def close(self):
  163.         self.rfile.close()
  164.  
  165.     
  166.     def __iter__(self):
  167.         return self
  168.  
  169.     
  170.     def next(self):
  171.         data = self.rfile.next()
  172.         self.bytes_read += len(data)
  173.         self._check_length()
  174.         return data
  175.  
  176.  
  177.  
  178. class HTTPRequest(object):
  179.     max_request_header_size = 0
  180.     max_request_body_size = 0
  181.     
  182.     def __init__(self, wfile, environ, wsgi_app):
  183.         self.rfile = environ['wsgi.input']
  184.         self.wfile = wfile
  185.         self.environ = environ.copy()
  186.         self.wsgi_app = wsgi_app
  187.         self.ready = False
  188.         self.started_response = False
  189.         self.status = ''
  190.         self.outheaders = []
  191.         self.sent_headers = False
  192.         self.close_connection = False
  193.         self.chunked_write = False
  194.  
  195.     
  196.     def parse_request(self):
  197.         self.rfile.maxlen = self.max_request_header_size
  198.         self.rfile.bytes_read = 0
  199.         
  200.         try:
  201.             self._parse_request()
  202.         except MaxSizeExceeded:
  203.             self.simple_response('413 Request Entity Too Large')
  204.             return None
  205.  
  206.  
  207.     
  208.     def _parse_request(self):
  209.         request_line = self.rfile.readline()
  210.         if not request_line:
  211.             self.ready = False
  212.             return None
  213.         environ = self.environ
  214.         
  215.         try:
  216.             (method, path, req_protocol) = request_line.strip().split(' ', 2)
  217.         except ValueError:
  218.             None if request_line == '\r\n' else request_line
  219.             None if request_line == '\r\n' else request_line
  220.             self.simple_response(400, 'Malformed Request-Line')
  221.             return None
  222.  
  223.         environ['REQUEST_METHOD'] = method
  224.         (scheme, location, path, params, qs, frag) = urlparse(path)
  225.         if frag:
  226.             self.simple_response('400 Bad Request', 'Illegal #fragment in Request-URI.')
  227.             return None
  228.         if params:
  229.             path = path + ';' + params
  230.         
  231.         environ['SCRIPT_NAME'] = ''
  232.         atoms = [ unquote(x) for x in quoted_slash.split(path) ]
  233.         path = '%2F'.join(atoms)
  234.         environ['PATH_INFO'] = path
  235.         environ['QUERY_STRING'] = qs
  236.         rp = (int(req_protocol[5]), int(req_protocol[7]))
  237.         server_protocol = environ['ACTUAL_SERVER_PROTOCOL']
  238.         sp = (int(server_protocol[5]), int(server_protocol[7]))
  239.         if sp[0] != rp[0]:
  240.             self.simple_response('505 HTTP Version Not Supported')
  241.             return None
  242.         environ['SERVER_PROTOCOL'] = req_protocol
  243.         self.response_protocol = 'HTTP/%s.%s' % min(rp, sp)
  244.         
  245.         try:
  246.             self.read_headers()
  247.         except ValueError:
  248.             [] if location else []
  249.             ex = [] if location else []
  250.             self.simple_response('400 Bad Request', repr(ex.args))
  251.             return None
  252.  
  253.         mrbs = self.max_request_body_size
  254.         if mrbs and int(environ.get('CONTENT_LENGTH', 0)) > mrbs:
  255.             self.simple_response('413 Request Entity Too Large')
  256.             return None
  257.         if self.response_protocol == 'HTTP/1.1':
  258.             if environ.get('HTTP_CONNECTION', '') == 'close':
  259.                 self.close_connection = True
  260.             
  261.         elif environ.get('HTTP_CONNECTION', '') != 'Keep-Alive':
  262.             self.close_connection = True
  263.         
  264.         te = None
  265.         if self.response_protocol == 'HTTP/1.1':
  266.             te = environ.get('HTTP_TRANSFER_ENCODING')
  267.             if te:
  268.                 te = _[2]
  269.             
  270.         
  271.         self.chunked_read = False
  272.         if te:
  273.             for enc in te:
  274.                 if enc == 'chunked':
  275.                     self.chunked_read = True
  276.                     continue
  277.                 self.simple_response('501 Unimplemented')
  278.                 self.close_connection = True
  279.                 return None
  280.             
  281.         
  282.         if environ.get('HTTP_EXPECT', '') == '100-continue':
  283.             self.simple_response(100)
  284.         
  285.         self.ready = True
  286.  
  287.     
  288.     def read_headers(self):
  289.         environ = self.environ
  290.         while True:
  291.             line = self.rfile.readline()
  292.             if not line:
  293.                 raise ValueError('Illegal end of headers.')
  294.             line
  295.             if line == '\r\n':
  296.                 break
  297.             
  298.             if line[0] in ' \t':
  299.                 v = line.strip()
  300.             else:
  301.                 (k, v) = line.split(':', 1)
  302.                 k = k.strip().upper()
  303.                 v = v.strip()
  304.                 envname = 'HTTP_' + k.replace('-', '_')
  305.             if k in comma_separated_headers:
  306.                 existing = environ.get(envname)
  307.                 if existing:
  308.                     v = ', '.join((existing, v))
  309.                 
  310.             
  311.             environ[envname] = v
  312.         ct = environ.pop('HTTP_CONTENT_TYPE', None)
  313.         if ct is not None:
  314.             environ['CONTENT_TYPE'] = ct
  315.         
  316.         cl = environ.pop('HTTP_CONTENT_LENGTH', None)
  317.         if cl is not None:
  318.             environ['CONTENT_LENGTH'] = cl
  319.         
  320.  
  321.     
  322.     def decode_chunked(self):
  323.         cl = 0
  324.         data = StringIO.StringIO()
  325.         while True:
  326.             line = self.rfile.readline().strip().split(';', 1)
  327.             chunk_size = int(line.pop(0), 16)
  328.             if chunk_size <= 0:
  329.                 break
  330.             
  331.             cl += chunk_size
  332.             data.write(self.rfile.read(chunk_size))
  333.             crlf = self.rfile.read(2)
  334.             if crlf != '\r\n':
  335.                 self.simple_response('400 Bad Request', "Bad chunked transfer coding (expected '\\r\\n', got %r)" % crlf)
  336.                 return None
  337.             continue
  338.             crlf != '\r\n'
  339.         self.read_headers()
  340.         data.seek(0)
  341.         self.environ['wsgi.input'] = data
  342.         if not str(cl):
  343.             pass
  344.         self.environ['CONTENT_LENGTH'] = ''
  345.         return True
  346.  
  347.     
  348.     def respond(self):
  349.         if self.chunked_read:
  350.             self.rfile.maxlen = self.max_request_body_size
  351.         else:
  352.             cl = int(self.environ.get('CONTENT_LENGTH', 0))
  353.             if self.max_request_body_size:
  354.                 self.rfile.maxlen = min(cl, self.max_request_body_size)
  355.             else:
  356.                 self.rfile.maxlen = cl
  357.         self.rfile.bytes_read = 0
  358.         
  359.         try:
  360.             self._respond()
  361.         except MaxSizeExceeded:
  362.             if not self.sent_headers:
  363.                 self.simple_response('413 Request Entity Too Large')
  364.             
  365.             return None
  366.  
  367.  
  368.     
  369.     def _respond(self):
  370.         if self.chunked_read:
  371.             if not self.decode_chunked():
  372.                 self.close_connection = True
  373.                 return None
  374.         
  375.         response = self.wsgi_app(self.environ, self.start_response)
  376.         
  377.         try:
  378.             for chunk in response:
  379.                 if chunk:
  380.                     self.write(chunk)
  381.                     continue
  382.         finally:
  383.             if hasattr(response, 'close'):
  384.                 response.close()
  385.             
  386.  
  387.         if self.ready and not (self.sent_headers):
  388.             self.sent_headers = True
  389.             self.send_headers()
  390.         
  391.         if self.chunked_write:
  392.             self.wfile.sendall('0\r\n\r\n')
  393.         
  394.  
  395.     
  396.     def simple_response(self, status, msg = ''):
  397.         status = str(status)
  398.         buf = [
  399.             '%s %s\r\n' % (self.environ['ACTUAL_SERVER_PROTOCOL'], status),
  400.             'Content-Length: %s\r\n' % len(msg),
  401.             'Content-Type: text/plain\r\n']
  402.         if status[:3] == '413' and self.response_protocol == 'HTTP/1.1':
  403.             self.close_connection = True
  404.             buf.append('Connection: close\r\n')
  405.         
  406.         buf.append('\r\n')
  407.         if msg:
  408.             buf.append(msg)
  409.         
  410.         
  411.         try:
  412.             self.wfile.sendall(''.join(buf))
  413.         except socket.error:
  414.             x = None
  415.             if x.args[0] not in socket_errors_to_ignore:
  416.                 raise 
  417.             x.args[0] not in socket_errors_to_ignore
  418.  
  419.  
  420.     
  421.     def start_response(self, status, headers, exc_info = None):
  422.         if self.started_response and not exc_info:
  423.             raise AssertionError('WSGI start_response called a second time with no exc_info.')
  424.         not exc_info
  425.         if self.sent_headers:
  426.             
  427.             try:
  428.                 raise exc_info[0], exc_info[1], exc_info[2]
  429.             finally:
  430.                 exc_info = None
  431.  
  432.         
  433.         self.started_response = True
  434.         self.status = status
  435.         self.outheaders.extend(headers)
  436.         return self.write
  437.  
  438.     
  439.     def write(self, chunk):
  440.         if not self.started_response:
  441.             raise AssertionError('WSGI write called before start_response.')
  442.         self.started_response
  443.         if not self.sent_headers:
  444.             self.sent_headers = True
  445.             self.send_headers()
  446.         
  447.         if self.chunked_write and chunk:
  448.             buf = [
  449.                 hex(len(chunk))[2:],
  450.                 '\r\n',
  451.                 chunk,
  452.                 '\r\n']
  453.             self.wfile.sendall(''.join(buf))
  454.         else:
  455.             self.wfile.sendall(chunk)
  456.  
  457.     
  458.     def send_headers(self):
  459.         hkeys = [ key.lower() for key, value in self.outheaders ]
  460.         status = int(self.status[:3])
  461.         if status == 413:
  462.             self.close_connection = True
  463.         elif 'content-length' not in hkeys:
  464.             if status < 200 or status in (204, 205, 304):
  465.                 pass
  466.             elif self.response_protocol == 'HTTP/1.1' and self.environ['REQUEST_METHOD'] != 'HEAD':
  467.                 self.chunked_write = True
  468.                 self.outheaders.append(('Transfer-Encoding', 'chunked'))
  469.             else:
  470.                 self.close_connection = True
  471.         
  472.         if 'connection' not in hkeys:
  473.             if self.response_protocol == 'HTTP/1.1':
  474.                 if self.close_connection:
  475.                     self.outheaders.append(('Connection', 'close'))
  476.                 
  477.             elif not self.close_connection:
  478.                 self.outheaders.append(('Connection', 'Keep-Alive'))
  479.             
  480.         
  481.         if not (self.close_connection) and not (self.chunked_read):
  482.             size = self.rfile.maxlen - self.rfile.bytes_read
  483.             if size > 0:
  484.                 self.rfile.read(size)
  485.             
  486.         
  487.         if 'date' not in hkeys:
  488.             self.outheaders.append(('Date', rfc822.formatdate()))
  489.         
  490.         if 'server' not in hkeys:
  491.             self.outheaders.append(('Server', self.environ['SERVER_SOFTWARE']))
  492.         
  493.         buf = [
  494.             self.environ['ACTUAL_SERVER_PROTOCOL'],
  495.             ' ',
  496.             self.status,
  497.             '\r\n']
  498.         
  499.         try:
  500.             [] += [ k + ': ' + v + '\r\n' for k, v in self.outheaders ]
  501.         except TypeError:
  502.             if not isinstance(k, str):
  503.                 raise TypeError('WSGI response header key %r is not a string.')
  504.             isinstance(k, str)
  505.             if not isinstance(v, str):
  506.                 raise TypeError('WSGI response header value %r is not a string.')
  507.             isinstance(v, str)
  508.             raise 
  509.  
  510.         buf.append('\r\n')
  511.         self.wfile.sendall(''.join(buf))
  512.  
  513.  
  514.  
  515. class NoSSLError(Exception):
  516.     pass
  517.  
  518.  
  519. class FatalSSLAlert(Exception):
  520.     pass
  521.  
  522. if not _fileobject_uses_str_type:
  523.     
  524.     class CP_fileobject(socket._fileobject):
  525.         
  526.         def sendall(self, data):
  527.             while data:
  528.                 
  529.                 try:
  530.                     bytes_sent = self.send(data)
  531.                     data = data[bytes_sent:]
  532.                 continue
  533.                 except socket.error:
  534.                     e = None
  535.                     if e.args[0] not in socket_errors_nonblocking:
  536.                         raise 
  537.                     e.args[0] not in socket_errors_nonblocking
  538.                     continue
  539.                 
  540.  
  541.                 None<EXCEPTION MATCH>socket.error
  542.  
  543.         
  544.         def send(self, data):
  545.             return self._sock.send(data)
  546.  
  547.         
  548.         def flush(self):
  549.             if self._wbuf:
  550.                 buffer = ''.join(self._wbuf)
  551.                 self._wbuf = []
  552.                 self.sendall(buffer)
  553.             
  554.  
  555.         
  556.         def recv(self, size):
  557.             while True:
  558.                 
  559.                 try:
  560.                     return self._sock.recv(size)
  561.                 continue
  562.                 except socket.error:
  563.                     e = None
  564.                     if e.args[0] not in socket_errors_nonblocking and e.args[0] not in socket_error_eintr:
  565.                         raise 
  566.                     e.args[0] not in socket_error_eintr
  567.                     continue
  568.                 
  569.  
  570.                 None<EXCEPTION MATCH>socket.error
  571.  
  572.         
  573.         def read(self, size = -1):
  574.             rbufsize = max(self._rbufsize, self.default_bufsize)
  575.             buf = self._rbuf
  576.             buf.seek(0, 2)
  577.             if size < 0:
  578.                 self._rbuf = StringIO.StringIO()
  579.                 while True:
  580.                     data = self.recv(rbufsize)
  581.                     if not data:
  582.                         break
  583.                     
  584.                     buf.write(data)
  585.                 return buf.getvalue()
  586.             buf_len = buf.tell()
  587.             if buf_len >= size:
  588.                 buf.seek(0)
  589.                 rv = buf.read(size)
  590.                 self._rbuf = StringIO.StringIO()
  591.                 self._rbuf.write(buf.read())
  592.                 return rv
  593.             self._rbuf = StringIO.StringIO()
  594.             while True:
  595.                 left = size - buf_len
  596.                 data = self.recv(left)
  597.                 n = len(data)
  598.                 if n == size and not buf_len:
  599.                     return data
  600.                 buf.write(data)
  601.                 buf_len += n
  602.                 del data
  603.                 continue
  604.                 None if n == left else None if not data else size < 0
  605.             return buf.getvalue()
  606.  
  607.         
  608.         def readline(self, size = -1):
  609.             buf = self._rbuf
  610.             buf.seek(0, 2)
  611.             if buf.tell() > 0:
  612.                 buf.seek(0)
  613.                 bline = buf.readline(size)
  614.                 if bline.endswith('\n') or len(bline) == size:
  615.                     self._rbuf = StringIO.StringIO()
  616.                     self._rbuf.write(buf.read())
  617.                     return bline
  618.                 del bline
  619.             
  620.             if size < 0:
  621.                 if self._rbufsize <= 1:
  622.                     buf.seek(0)
  623.                     buffers = [
  624.                         buf.read()]
  625.                     self._rbuf = StringIO.StringIO()
  626.                     data = None
  627.                     recv = self.recv
  628.                     while data != '\n':
  629.                         data = recv(1)
  630.                         if not data:
  631.                             break
  632.                         
  633.                         buffers.append(data)
  634.                     return ''.join(buffers)
  635.                 buf.seek(0, 2)
  636.                 self._rbuf = StringIO.StringIO()
  637.                 while True:
  638.                     data = self.recv(self._rbufsize)
  639.                     if not data:
  640.                         break
  641.                     
  642.                     nl = data.find('\n')
  643.                     if nl >= 0:
  644.                         nl += 1
  645.                         buf.write(data[:nl])
  646.                         self._rbuf.write(data[nl:])
  647.                         del data
  648.                         break
  649.                     
  650.                     buf.write(data)
  651.                 return buf.getvalue()
  652.             buf.seek(0, 2)
  653.             buf_len = buf.tell()
  654.             if buf_len >= size:
  655.                 buf.seek(0)
  656.                 rv = buf.read(size)
  657.                 self._rbuf = StringIO.StringIO()
  658.                 self._rbuf.write(buf.read())
  659.                 return rv
  660.             self._rbuf = StringIO.StringIO()
  661.             while True:
  662.                 data = self.recv(self._rbufsize)
  663.                 left = size - buf_len
  664.                 nl = data.find('\n', 0, left)
  665.                 if nl >= 0:
  666.                     nl += 1
  667.                     self._rbuf.write(data[nl:])
  668.                     if buf_len:
  669.                         buf.write(data[:nl])
  670.                         break
  671.                     else:
  672.                         return data[:nl]
  673.                 buf_len
  674.                 n = len(data)
  675.                 if n == size and not buf_len:
  676.                     return data
  677.                 buf.write(data)
  678.                 buf_len += n
  679.                 continue
  680.                 None if n >= left else None if not data else size < 0
  681.             return buf.getvalue()
  682.  
  683.  
  684. else:
  685.     
  686.     class CP_fileobject(socket._fileobject):
  687.         
  688.         def sendall(self, data):
  689.             while data:
  690.                 
  691.                 try:
  692.                     bytes_sent = self.send(data)
  693.                     data = data[bytes_sent:]
  694.                 continue
  695.                 except socket.error:
  696.                     e = None
  697.                     if e.args[0] not in socket_errors_nonblocking:
  698.                         raise 
  699.                     e.args[0] not in socket_errors_nonblocking
  700.                     continue
  701.                 
  702.  
  703.                 None<EXCEPTION MATCH>socket.error
  704.  
  705.         
  706.         def send(self, data):
  707.             return self._sock.send(data)
  708.  
  709.         
  710.         def flush(self):
  711.             if self._wbuf:
  712.                 buffer = ''.join(self._wbuf)
  713.                 self._wbuf = []
  714.                 self.sendall(buffer)
  715.             
  716.  
  717.         
  718.         def recv(self, size):
  719.             while True:
  720.                 
  721.                 try:
  722.                     return self._sock.recv(size)
  723.                 continue
  724.                 except socket.error:
  725.                     e = None
  726.                     if e.args[0] not in socket_errors_nonblocking and e.args[0] not in socket_error_eintr:
  727.                         raise 
  728.                     e.args[0] not in socket_error_eintr
  729.                     continue
  730.                 
  731.  
  732.                 None<EXCEPTION MATCH>socket.error
  733.  
  734.         
  735.         def read(self, size = -1):
  736.             if size < 0:
  737.                 buffers = [
  738.                     self._rbuf]
  739.                 self._rbuf = ''
  740.                 if self._rbufsize <= 1:
  741.                     recv_size = self.default_bufsize
  742.                 else:
  743.                     recv_size = self._rbufsize
  744.                 while True:
  745.                     data = self.recv(recv_size)
  746.                     if not data:
  747.                         break
  748.                     
  749.                     buffers.append(data)
  750.                 return ''.join(buffers)
  751.             data = self._rbuf
  752.             buf_len = len(data)
  753.             if buf_len >= size:
  754.                 self._rbuf = data[size:]
  755.                 return data[:size]
  756.             buffers = []
  757.             self._rbuf = ''
  758.             while True:
  759.                 left = size - buf_len
  760.                 recv_size = max(self._rbufsize, left)
  761.                 data = self.recv(recv_size)
  762.                 if not data:
  763.                     break
  764.                 
  765.                 buffers.append(data)
  766.                 n = len(data)
  767.                 if n >= left:
  768.                     self._rbuf = data[left:]
  769.                     buffers[-1] = data[:left]
  770.                     break
  771.                 
  772.                 buf_len += n
  773.             return ''.join(buffers)
  774.  
  775.         
  776.         def readline(self, size = -1):
  777.             data = self._rbuf
  778.             if size < 0:
  779.                 if self._rbufsize <= 1:
  780.                     buffers = []
  781.                     while data != '\n':
  782.                         data = self.recv(1)
  783.                         if not data:
  784.                             break
  785.                         
  786.                         buffers.append(data)
  787.                     return ''.join(buffers)
  788.                 nl = data.find('\n')
  789.                 if nl >= 0:
  790.                     nl += 1
  791.                     self._rbuf = data[nl:]
  792.                     return data[:nl]
  793.                 buffers = []
  794.                 self._rbuf = ''
  795.                 while True:
  796.                     data = self.recv(self._rbufsize)
  797.                     if not data:
  798.                         break
  799.                     
  800.                     buffers.append(data)
  801.                     nl = data.find('\n')
  802.                     if nl >= 0:
  803.                         nl += 1
  804.                         self._rbuf = data[nl:]
  805.                         buffers[-1] = data[:nl]
  806.                         break
  807.                         continue
  808.                 return ''.join(buffers)
  809.             nl = data.find('\n', 0, size)
  810.             if nl >= 0:
  811.                 nl += 1
  812.                 self._rbuf = data[nl:]
  813.                 return data[:nl]
  814.             buf_len = len(data)
  815.             if buf_len >= size:
  816.                 self._rbuf = data[size:]
  817.                 return data[:size]
  818.             buffers = []
  819.             self._rbuf = ''
  820.             while True:
  821.                 data = self.recv(self._rbufsize)
  822.                 if not data:
  823.                     break
  824.                 
  825.                 buffers.append(data)
  826.                 left = size - buf_len
  827.                 nl = data.find('\n', 0, left)
  828.                 if nl >= 0:
  829.                     nl += 1
  830.                     self._rbuf = data[nl:]
  831.                     buffers[-1] = data[:nl]
  832.                     break
  833.                 
  834.                 n = len(data)
  835.                 if n >= left:
  836.                     self._rbuf = data[left:]
  837.                     buffers[-1] = data[:left]
  838.                     break
  839.                 
  840.                 buf_len += n
  841.             return ''.join(buffers)
  842.  
  843.  
  844.  
  845. class SSL_fileobject(CP_fileobject):
  846.     ssl_timeout = 3
  847.     ssl_retry = 0.01
  848.     
  849.     def _safe_call(self, is_reader, call, *args, **kwargs):
  850.         start = time.time()
  851.         while True:
  852.             
  853.             try:
  854.                 return call(*args, **kwargs)
  855.             except SSL.WantReadError:
  856.                 time.sleep(self.ssl_retry)
  857.             except SSL.WantWriteError:
  858.                 time.sleep(self.ssl_retry)
  859.             except SSL.SysCallError:
  860.                 e = None
  861.                 if is_reader and e.args == (-1, 'Unexpected EOF'):
  862.                     return ''
  863.                 errnum = e.args[0]
  864.                 if is_reader and errnum in socket_errors_to_ignore:
  865.                     return ''
  866.                 raise socket.error(errnum)
  867.             except SSL.Error:
  868.                 e.args == (-1, 'Unexpected EOF')
  869.                 e = e.args == (-1, 'Unexpected EOF')
  870.                 if is_reader and e.args == (-1, 'Unexpected EOF'):
  871.                     return ''
  872.                 thirdarg = None
  873.                 
  874.                 try:
  875.                     thirdarg = e.args[0][0][2]
  876.                 except IndexError:
  877.                     e.args == (-1, 'Unexpected EOF')
  878.                     e.args == (-1, 'Unexpected EOF')
  879.                 except:
  880.                     e.args == (-1, 'Unexpected EOF')
  881.  
  882.                 if thirdarg == 'http request':
  883.                     raise NoSSLError()
  884.                 thirdarg == 'http request'
  885.                 raise FatalSSLAlert(*e.args)
  886.             except:
  887.                 e.args == (-1, 'Unexpected EOF')
  888.                 raise 
  889.  
  890.             if time.time() - start > self.ssl_timeout:
  891.                 raise socket.timeout('timed out')
  892.             time.time() - start > self.ssl_timeout
  893.             continue
  894.             e.args == (-1, 'Unexpected EOF')
  895.  
  896.     
  897.     def recv(self, *args, **kwargs):
  898.         buf = []
  899.         r = super(SSL_fileobject, self).recv
  900.         while True:
  901.             data = self._safe_call(True, r, *args, **kwargs)
  902.             buf.append(data)
  903.             p = self._sock.pending()
  904.             if not p:
  905.                 return ''.join(buf)
  906.             continue
  907.             p
  908.  
  909.     
  910.     def sendall(self, *args, **kwargs):
  911.         return self._safe_call(False, super(SSL_fileobject, self).sendall, *args, **kwargs)
  912.  
  913.     
  914.     def send(self, *args, **kwargs):
  915.         return self._safe_call(False, super(SSL_fileobject, self).send, *args, **kwargs)
  916.  
  917.  
  918.  
  919. class HTTPConnection(object):
  920.     rbufsize = -1
  921.     RequestHandlerClass = HTTPRequest
  922.     environ = {
  923.         'wsgi.version': (1, 0),
  924.         'wsgi.url_scheme': 'http',
  925.         'wsgi.multithread': True,
  926.         'wsgi.multiprocess': False,
  927.         'wsgi.run_once': False,
  928.         'wsgi.errors': sys.stderr }
  929.     
  930.     def __init__(self, sock, wsgi_app, environ):
  931.         self.socket = sock
  932.         self.wsgi_app = wsgi_app
  933.         self.environ = self.environ.copy()
  934.         self.environ.update(environ)
  935.         if SSL and isinstance(sock, SSL.ConnectionType):
  936.             timeout = sock.gettimeout()
  937.             self.rfile = SSL_fileobject(sock, 'rb', self.rbufsize)
  938.             self.rfile.ssl_timeout = timeout
  939.             self.wfile = SSL_fileobject(sock, 'wb', -1)
  940.             self.wfile.ssl_timeout = timeout
  941.         else:
  942.             self.rfile = CP_fileobject(sock, 'rb', self.rbufsize)
  943.             self.wfile = CP_fileobject(sock, 'wb', -1)
  944.         self.environ['wsgi.input'] = SizeCheckWrapper(self.rfile, 0)
  945.  
  946.     
  947.     def communicate(self):
  948.         
  949.         try:
  950.             while True:
  951.                 req = None
  952.                 req = self.RequestHandlerClass(self.wfile, self.environ, self.wsgi_app)
  953.                 req.parse_request()
  954.                 if not req.ready:
  955.                     return None
  956.                 req.respond()
  957.                 if req.close_connection:
  958.                     return None
  959.                 continue
  960.                 req.close_connection
  961.         except socket.error:
  962.             e = None
  963.             errnum = e.args[0]
  964.             if errnum == 'timed out':
  965.                 if req and not (req.sent_headers):
  966.                     req.simple_response('408 Request Timeout')
  967.                 
  968.             elif errnum not in socket_errors_to_ignore:
  969.                 if req and not (req.sent_headers):
  970.                     req.simple_response('500 Internal Server Error', format_exc())
  971.                 
  972.             
  973.             return None
  974.             except (KeyboardInterrupt, SystemExit):
  975.                 raise 
  976.             except FatalSSLAlert:
  977.                 e = None
  978.                 return None
  979.                 except NoSSLError:
  980.                     if req and not (req.sent_headers):
  981.                         req.wfile = CP_fileobject(self.socket._sock, 'wb', -1)
  982.                         req.simple_response('400 Bad Request', 'The client sent a plain HTTP request, but this server only speaks HTTPS on this port.')
  983.                         self.linger = True
  984.                     
  985.                 except Exception:
  986.                     e = None
  987.                     if req and not (req.sent_headers):
  988.                         req.simple_response('500 Internal Server Error', format_exc())
  989.                     
  990.                 except:
  991.                     not (req.sent_headers)
  992.                 
  993.  
  994.  
  995.     linger = False
  996.     
  997.     def close(self):
  998.         self.rfile.close()
  999.         if not self.linger:
  1000.             self.socket._sock.close()
  1001.             self.socket.close()
  1002.         
  1003.  
  1004.  
  1005.  
  1006. def format_exc(limit = None):
  1007.     
  1008.     try:
  1009.         (etype, value, tb) = sys.exc_info()
  1010.         return ''.join(traceback.format_exception(etype, value, tb, limit))
  1011.     finally:
  1012.         etype = None
  1013.         value = None
  1014.         tb = None
  1015.  
  1016.  
  1017. _SHUTDOWNREQUEST = None
  1018.  
  1019. class WorkerThread(threading.Thread):
  1020.     conn = None
  1021.     
  1022.     def __init__(self, server):
  1023.         self.ready = False
  1024.         self.server = server
  1025.         threading.Thread.__init__(self)
  1026.  
  1027.     
  1028.     def run(self):
  1029.         
  1030.         try:
  1031.             self.ready = True
  1032.             while True:
  1033.                 conn = self.server.requests.get()
  1034.                 if conn is _SHUTDOWNREQUEST:
  1035.                     return None
  1036.                 self.conn = conn
  1037.                 
  1038.                 try:
  1039.                     conn.communicate()
  1040.                 finally:
  1041.                     conn.close()
  1042.                     self.conn = None
  1043.  
  1044.                 continue
  1045.                 conn is _SHUTDOWNREQUEST
  1046.         except (KeyboardInterrupt, SystemExit):
  1047.             exc = None
  1048.             self.server.interrupt = exc
  1049.  
  1050.  
  1051.  
  1052.  
  1053. class ThreadPool(object):
  1054.     
  1055.     def __init__(self, server, min = 10, max = -1):
  1056.         self.server = server
  1057.         self.min = min
  1058.         self.max = max
  1059.         self._threads = []
  1060.         self._queue = Queue.Queue()
  1061.         self.get = self._queue.get
  1062.  
  1063.     
  1064.     def start(self):
  1065.         for i in xrange(self.min):
  1066.             self._threads.append(WorkerThread(self.server))
  1067.         
  1068.         for worker in self._threads:
  1069.             worker.setName('CP WSGIServer ' + worker.getName())
  1070.             worker.start()
  1071.         
  1072.         for worker in self._threads:
  1073.             while not worker.ready:
  1074.                 time.sleep(0.1)
  1075.         
  1076.  
  1077.     
  1078.     def _get_idle(self):
  1079.         return [](_[1])
  1080.  
  1081.     idle = property(_get_idle, doc = _get_idle.__doc__)
  1082.     
  1083.     def put(self, obj):
  1084.         self._queue.put(obj)
  1085.         if obj is _SHUTDOWNREQUEST:
  1086.             return None
  1087.  
  1088.     
  1089.     def grow(self, amount):
  1090.         for i in xrange(amount):
  1091.             if self.max > 0 and len(self._threads) >= self.max:
  1092.                 break
  1093.             
  1094.             worker = WorkerThread(self.server)
  1095.             worker.setName('CP WSGIServer ' + worker.getName())
  1096.             self._threads.append(worker)
  1097.             worker.start()
  1098.         
  1099.  
  1100.     
  1101.     def shrink(self, amount):
  1102.         for t in self._threads:
  1103.             if not t.isAlive():
  1104.                 self._threads.remove(t)
  1105.                 amount -= 1
  1106.                 continue
  1107.         
  1108.         if amount > 0:
  1109.             for i in xrange(min(amount, len(self._threads) - self.min)):
  1110.                 self._queue.put(_SHUTDOWNREQUEST)
  1111.             
  1112.         
  1113.  
  1114.     
  1115.     def stop(self, timeout = 5):
  1116.         for worker in self._threads:
  1117.             self._queue.put(_SHUTDOWNREQUEST)
  1118.         
  1119.         current = threading.currentThread()
  1120.         while self._threads:
  1121.             worker = self._threads.pop()
  1122.             if worker is not current and worker.isAlive():
  1123.                 
  1124.                 try:
  1125.                     if timeout is None or timeout < 0:
  1126.                         worker.join()
  1127.                     else:
  1128.                         worker.join(timeout)
  1129.                         if worker.isAlive():
  1130.                             c = worker.conn
  1131.                             if c and not (c.rfile.closed):
  1132.                                 if SSL and isinstance(c.socket, SSL.ConnectionType):
  1133.                                     c.socket.shutdown()
  1134.                                 else:
  1135.                                     c.socket.shutdown(socket.SHUT_RD)
  1136.                             
  1137.                             worker.join()
  1138.                 except (AssertionError, KeyboardInterrupt):
  1139.                     timeout < 0
  1140.                     exc1 = timeout < 0
  1141.                 except:
  1142.                     timeout < 0<EXCEPTION MATCH>(AssertionError, KeyboardInterrupt)
  1143.                 
  1144.  
  1145.             timeout < 0<EXCEPTION MATCH>(AssertionError, KeyboardInterrupt)
  1146.             continue
  1147.             timeout < 0
  1148.  
  1149.  
  1150.  
  1151. class SSLConnection:
  1152.     
  1153.     def __init__(self, *args):
  1154.         self._ssl_conn = SSL.Connection(*args)
  1155.         self._lock = threading.RLock()
  1156.  
  1157.     for f in ('get_context', 'pending', 'send', 'write', 'recv', 'read', 'renegotiate', 'bind', 'listen', 'connect', 'accept', 'setblocking', 'fileno', 'shutdown', 'close', 'get_cipher_list', 'getpeername', 'getsockname', 'getsockopt', 'setsockopt', 'makefile', 'get_app_data', 'set_app_data', 'state_string', 'sock_shutdown', 'get_peer_certificate', 'want_read', 'want_write', 'set_connect_state', 'set_accept_state', 'connect_ex', 'sendall', 'settimeout'):
  1158.         exec 'def %s(self, *args):\n        self._lock.acquire()\n        try:\n            return self._ssl_conn.%s(*args)\n        finally:\n            self._lock.release()\n' % (f, f)
  1159.     
  1160.  
  1161.  
  1162. try:
  1163.     import fcntl
  1164. except ImportError:
  1165.     
  1166.     try:
  1167.         from ctypes import windll, WinError
  1168.     except ImportError:
  1169.         
  1170.         def prevent_socket_inheritance(sock):
  1171.             pass
  1172.  
  1173.  
  1174.     
  1175.     def prevent_socket_inheritance(sock):
  1176.         if not windll.kernel32.SetHandleInformation(sock.fileno(), 1, 0):
  1177.             raise WinError()
  1178.         windll.kernel32.SetHandleInformation(sock.fileno(), 1, 0)
  1179.  
  1180.  
  1181.  
  1182. def prevent_socket_inheritance(sock):
  1183.     fd = sock.fileno()
  1184.     old_flags = fcntl.fcntl(fd, fcntl.F_GETFD)
  1185.     fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC)
  1186.  
  1187.  
  1188. class CherryPyWSGIServer(object):
  1189.     protocol = 'HTTP/1.1'
  1190.     _bind_addr = '127.0.0.1'
  1191.     version = 'CherryPy/3.1.2'
  1192.     ready = False
  1193.     _interrupt = None
  1194.     nodelay = True
  1195.     ConnectionClass = HTTPConnection
  1196.     environ = { }
  1197.     ssl_certificate = None
  1198.     ssl_private_key = None
  1199.     
  1200.     def __init__(self, bind_addr, wsgi_app, numthreads = 10, server_name = None, max = -1, request_queue_size = 5, timeout = 10, shutdown_timeout = 5):
  1201.         if not numthreads:
  1202.             pass
  1203.         self.requests = ThreadPool(self, min = 1, max = max)
  1204.         if callable(wsgi_app):
  1205.             self.wsgi_app = wsgi_app
  1206.         else:
  1207.             warnings.warn('The ability to pass multiple apps is deprecated and will be removed in 3.2. You should explicitly include a WSGIPathInfoDispatcher instead.', DeprecationWarning)
  1208.             self.wsgi_app = WSGIPathInfoDispatcher(wsgi_app)
  1209.         self.bind_addr = bind_addr
  1210.         if not server_name:
  1211.             server_name = socket.gethostname()
  1212.         
  1213.         self.server_name = server_name
  1214.         self.request_queue_size = request_queue_size
  1215.         self.timeout = timeout
  1216.         self.shutdown_timeout = shutdown_timeout
  1217.  
  1218.     
  1219.     def _get_numthreads(self):
  1220.         return self.requests.min
  1221.  
  1222.     
  1223.     def _set_numthreads(self, value):
  1224.         self.requests.min = value
  1225.  
  1226.     numthreads = property(_get_numthreads, _set_numthreads)
  1227.     
  1228.     def __str__(self):
  1229.         return '%s.%s(%r)' % (self.__module__, self.__class__.__name__, self.bind_addr)
  1230.  
  1231.     
  1232.     def _get_bind_addr(self):
  1233.         return self._bind_addr
  1234.  
  1235.     
  1236.     def _set_bind_addr(self, value):
  1237.         if isinstance(value, tuple) and value[0] in ('', None):
  1238.             raise ValueError("Host values of '' or None are not allowed. Use '0.0.0.0' (IPv4) or '::' (IPv6) instead to listen on all active interfaces.")
  1239.         value[0] in ('', None)
  1240.         self._bind_addr = value
  1241.  
  1242.     bind_addr = property(_get_bind_addr, _set_bind_addr, doc = 'The interface on which to listen for connections.\n        \n        For TCP sockets, a (host, port) tuple. Host values may be any IPv4\n        or IPv6 address, or any valid hostname. The string \'localhost\' is a\n        synonym for \'127.0.0.1\' (or \'::1\', if your hosts file prefers IPv6).\n        The string \'0.0.0.0\' is a special IPv4 entry meaning "any active\n        interface" (INADDR_ANY), and \'::\' is the similar IN6ADDR_ANY for\n        IPv6. The empty string or None are not allowed.\n        \n        For UNIX sockets, supply the filename as a string.')
  1243.     
  1244.     def start(self):
  1245.         self._interrupt = None
  1246.         if isinstance(self.bind_addr, basestring):
  1247.             
  1248.             try:
  1249.                 os.unlink(self.bind_addr)
  1250.             except:
  1251.                 pass
  1252.  
  1253.             
  1254.             try:
  1255.                 os.chmod(self.bind_addr, 511)
  1256.             except:
  1257.                 pass
  1258.  
  1259.             info = [
  1260.                 (socket.AF_UNIX, socket.SOCK_STREAM, 0, '', self.bind_addr)]
  1261.         else:
  1262.             (host, port) = self.bind_addr
  1263.             
  1264.             try:
  1265.                 info = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE)
  1266.             except socket.gaierror:
  1267.                 info = [
  1268.                     (socket.AF_INET, socket.SOCK_STREAM, 0, '', self.bind_addr)]
  1269.  
  1270.         self.socket = None
  1271.         msg = 'No socket could be created'
  1272.         for res in info:
  1273.             (af, socktype, proto, canonname, sa) = res
  1274.             
  1275.             try:
  1276.                 self.bind(af, socktype, proto)
  1277.             except socket.error:
  1278.                 msg = None
  1279.                 if self.socket:
  1280.                     self.socket.close()
  1281.                 
  1282.                 self.socket = None
  1283.                 continue
  1284.  
  1285.         
  1286.         if not self.socket:
  1287.             raise socket.error, msg
  1288.         self.socket
  1289.         self.socket.settimeout(1)
  1290.         self.socket.listen(self.request_queue_size)
  1291.         self.requests.start()
  1292.         self.ready = True
  1293.         while self.ready:
  1294.             self.tick()
  1295.             if self.interrupt:
  1296.                 while self.interrupt is True:
  1297.                     time.sleep(0.1)
  1298.                 if self.interrupt:
  1299.                     raise self.interrupt
  1300.                 self.interrupt
  1301.                 continue
  1302.  
  1303.     
  1304.     def bind(self, family, type, proto = 0):
  1305.         self.socket = socket.socket(family, type, proto)
  1306.         prevent_socket_inheritance(self.socket)
  1307.         self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  1308.         if self.nodelay:
  1309.             self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
  1310.         
  1311.         if self.ssl_certificate and self.ssl_private_key:
  1312.             if SSL is None:
  1313.                 raise ImportError('You must install pyOpenSSL to use HTTPS.')
  1314.             SSL is None
  1315.             ctx = SSL.Context(SSL.SSLv23_METHOD)
  1316.             ctx.use_privatekey_file(self.ssl_private_key)
  1317.             ctx.use_certificate_file(self.ssl_certificate)
  1318.             self.socket = SSLConnection(ctx, self.socket)
  1319.             self.populate_ssl_environ()
  1320.             if not isinstance(self.bind_addr, basestring) and self.bind_addr[0] == '::' and family == socket.AF_INET6:
  1321.                 
  1322.                 try:
  1323.                     self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
  1324.                 except (AttributeError, socket.error):
  1325.                     pass
  1326.                 except:
  1327.                     None<EXCEPTION MATCH>(AttributeError, socket.error)
  1328.                 
  1329.  
  1330.             None<EXCEPTION MATCH>(AttributeError, socket.error)
  1331.         
  1332.         self.socket.bind(self.bind_addr)
  1333.  
  1334.     
  1335.     def tick(self):
  1336.         
  1337.         try:
  1338.             (s, addr) = self.socket.accept()
  1339.             prevent_socket_inheritance(s)
  1340.             if not self.ready:
  1341.                 return None
  1342.             if hasattr(s, 'settimeout'):
  1343.                 s.settimeout(self.timeout)
  1344.             
  1345.             environ = self.environ.copy()
  1346.             if environ.get('SERVER_SOFTWARE') is None:
  1347.                 environ['SERVER_SOFTWARE'] = '%s WSGI Server' % self.version
  1348.             
  1349.             environ['ACTUAL_SERVER_PROTOCOL'] = self.protocol
  1350.             environ['SERVER_NAME'] = self.server_name
  1351.             if isinstance(self.bind_addr, basestring):
  1352.                 environ['SERVER_PORT'] = ''
  1353.             else:
  1354.                 environ['SERVER_PORT'] = str(self.bind_addr[1])
  1355.                 environ['REMOTE_ADDR'] = addr[0]
  1356.                 environ['REMOTE_PORT'] = str(addr[1])
  1357.             conn = self.ConnectionClass(s, self.wsgi_app, environ)
  1358.             self.requests.put(conn)
  1359.         except socket.timeout:
  1360.             return None
  1361.             except socket.error:
  1362.                 x = None
  1363.                 if x.args[0] in socket_error_eintr:
  1364.                     return None
  1365.                 if x.args[0] in socket_errors_nonblocking:
  1366.                     return None
  1367.                 if x.args[0] in socket_errors_to_ignore:
  1368.                     return None
  1369.                 raise 
  1370.             except:
  1371.                 x.args[0] in socket_errors_to_ignore
  1372.             
  1373.  
  1374.  
  1375.     
  1376.     def _get_interrupt(self):
  1377.         return self._interrupt
  1378.  
  1379.     
  1380.     def _set_interrupt(self, interrupt):
  1381.         self._interrupt = True
  1382.         self.stop()
  1383.         self._interrupt = interrupt
  1384.  
  1385.     interrupt = property(_get_interrupt, _set_interrupt, doc = 'Set this to an Exception instance to interrupt the server.')
  1386.     
  1387.     def stop(self):
  1388.         self.ready = False
  1389.         sock = getattr(self, 'socket', None)
  1390.         if sock:
  1391.             if not isinstance(self.bind_addr, basestring):
  1392.                 
  1393.                 try:
  1394.                     (host, port) = sock.getsockname()[:2]
  1395.                 except socket.error:
  1396.                     x = None
  1397.                     if x.args[0] not in socket_errors_to_ignore:
  1398.                         raise 
  1399.                     x.args[0] not in socket_errors_to_ignore
  1400.  
  1401.                 for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM):
  1402.                     (af, socktype, proto, canonname, sa) = res
  1403.                     s = None
  1404.                     
  1405.                     try:
  1406.                         s = socket.socket(af, socktype, proto)
  1407.                         s.settimeout(1)
  1408.                         s.connect((host, port))
  1409.                         s.close()
  1410.                     continue
  1411.                     except socket.error:
  1412.                         if s:
  1413.                             s.close()
  1414.                         
  1415.                         s
  1416.                     
  1417.  
  1418.                 
  1419.             
  1420.             if hasattr(sock, 'close'):
  1421.                 sock.close()
  1422.             
  1423.             self.socket = None
  1424.         
  1425.         self.requests.stop(self.shutdown_timeout)
  1426.  
  1427.     
  1428.     def populate_ssl_environ(self):
  1429.         cert = open(self.ssl_certificate, 'rb').read()
  1430.         cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
  1431.         ssl_environ = {
  1432.             'wsgi.url_scheme': 'https',
  1433.             'HTTPS': 'on' }
  1434.         ssl_environ.update({
  1435.             'SSL_SERVER_M_VERSION': cert.get_version(),
  1436.             'SSL_SERVER_M_SERIAL': cert.get_serial_number() })
  1437.         for prefix, dn in [
  1438.             ('I', cert.get_issuer()),
  1439.             ('S', cert.get_subject())]:
  1440.             dnstr = str(dn)[18:-2]
  1441.             wsgikey = 'SSL_SERVER_%s_DN' % prefix
  1442.             ssl_environ[wsgikey] = dnstr
  1443.             while dnstr:
  1444.                 pos = dnstr.rfind('=')
  1445.                 dnstr = dnstr[:pos]
  1446.                 value = dnstr[pos + 1:]
  1447.                 pos = dnstr.rfind('/')
  1448.                 dnstr = dnstr[:pos]
  1449.                 key = dnstr[pos + 1:]
  1450.                 if key and value:
  1451.                     wsgikey = 'SSL_SERVER_%s_DN_%s' % (prefix, key)
  1452.                     ssl_environ[wsgikey] = value
  1453.                     continue
  1454.         
  1455.         self.environ.update(ssl_environ)
  1456.  
  1457.  
  1458.