Package cherrypy :: Package wsgiserver :: Module wsgiserver2
[hide private]
[frames] | no frames]

Module wsgiserver2

source code

A high-speed, production ready, thread pooled, generic HTTP server.

Simplest example on how to use this module directly (without using CherryPy's application machinery):

   from cherrypy import wsgiserver
   
   def my_crazy_app(environ, start_response):
       status = '200 OK'
       response_headers = [('Content-type','text/plain')]
       start_response(status, response_headers)
       return ['Hello world!']
   
   server = wsgiserver.CherryPyWSGIServer(
               ('0.0.0.0', 8070), my_crazy_app,
               server_name='www.cherrypy.example')
   server.start()

The CherryPy WSGI server can serve as many WSGI applications as you want in one instance by using a WSGIPathInfoDispatcher:

   d = WSGIPathInfoDispatcher({'/': my_crazy_app, '/blog': my_blog_app})
   server = wsgiserver.CherryPyWSGIServer(('0.0.0.0', 80), d)

Want SSL support? Just set server.ssl_adapter to an SSLAdapter instance.

This won't call the CherryPy engine (application side) at all, only the HTTP server, which is independent from the rest of CherryPy. Don't let the name "CherryPyWSGIServer" throw you; the name merely reflects its origin, not its coupling.

For those of you wanting to understand internals of this module, here's the basic call flow. The server's listening thread runs a very tight loop, sticking incoming connections onto a Queue:

   server = CherryPyWSGIServer(...)
   server.start()
   while True:
       tick()
       # This blocks until a request comes in:
       child = socket.accept()
       conn = HTTPConnection(child, ...)
       server.requests.put(conn)

Worker threads are kept in a pool and poll the Queue, popping off and then handling each connection in turn. Each connection can consist of an arbitrary number of requests and their responses, so we run a nested loop:

   while True:
       conn = server.requests.get()
       conn.communicate()
       ->  while True:
               req = HTTPRequest(...)
               req.parse_request()
               ->  # Read the Request-Line, e.g. "GET /page HTTP/1.1"
                   req.rfile.readline()
                   read_headers(req.rfile, req.inheaders)
               req.respond()
               ->  response = app(...)
                   try:
                       for chunk in response:
                           if chunk:
                               req.write(chunk)
                   finally:
                       if hasattr(response, "close"):
                           response.close()
               if req.close_connection:
                   return
Classes [hide private]
  MaxSizeExceeded
  SizeCheckWrapper
Wraps a file-like object, raising MaxSizeExceeded if too large.
  KnownLengthRFile
Wraps a file-like object, returning an empty string when exhausted.
  ChunkedRFile
Wraps a file-like object, returning an empty string when exhausted.
  HTTPRequest
An HTTP Request (and response).
  NoSSLError
Exception raised when a client speaks HTTP to an HTTPS socket.
  FatalSSLAlert
Exception raised when the SSL implementation signals a fatal alert.
  CP_fileobject
Faux file object attached to a socket object.
  HTTPConnection
An HTTP connection (active socket).
  TrueyZero
An object which equals and does math like the integer '0' but evals True.
  WorkerThread
Thread which continuously polls a Queue for Connection objects.
  ThreadPool
A Request Queue for an HTTPServer which pools threads.
  SSLAdapter
Base class for SSL driver library adapters.
  HTTPServer
An HTTP server.
  Gateway
A base class to interface HTTPServer with other systems, such as WSGI.
  CherryPyWSGIServer
A subclass of HTTPServer which calls a WSGI application.
  WSGIGateway
A base class to interface HTTPServer with WSGI.
  WSGIGateway_10
A Gateway class to interface HTTPServer with WSGI 1.0.x.
  WSGIGateway_u0
A Gateway class to interface HTTPServer with WSGI u.0.
  WSGIPathInfoDispatcher
A WSGI dispatcher for dispatch based on the PATH_INFO.
Functions [hide private]
 
format_exc(limit=None)
Like print_exc() but return a string.
source code
 
ntob(n, encoding='ISO-8859-1')
Return the given native string as a byte string in the given encoding.
source code
 
plat_specific_errors(*errnames)
Return error numbers for all errors in errnames on this platform.
source code
 
read_headers(rfile, hdict=None)
Read headers from the given stream into the given header dict.
source code
 
prevent_socket_inheritance(sock)
Mark the given socket fd as non-inheritable (POSIX).
source code
 
get_ssl_adapter_class(name='pyopenssl')
Return an SSL adapter class for the given name.
source code
Variables [hide private]
  DEFAULT_BUFFER_SIZE = -1
  _fileobject_uses_str_type = False
  LF = '\n'
  CRLF = '\r\n'
  TAB = '\t'
  SPACE = ' '
  COLON = ':'
  SEMICOLON = ';'
  EMPTY = ''
  NUMBER_SIGN = '#'
  QUESTION_MARK = '?'
  ASTERISK = '*'
  FORWARD_SLASH = '/'
  quoted_slash = re.compile(r'(?i)%2F')
  socket_error_eintr = [4]
  socket_errors_to_ignore = [32, 102, 103, 104, 9, 110, 111, 112...
  socket_errors_nonblocking = [11]
  comma_separated_headers = ['Accept', 'Accept-Charset', 'Accept...
  trueyzero = TrueyZero()
  _SHUTDOWNREQUEST = None
hash(x)
  ssl_adapters = {'builtin': 'cherrypy.wsgiserver.ssl_builtin.Bu...
  wsgi_gateways = {(1, 0): <class 'cherrypy.wsgiserver.wsgiserve...
  __package__ = 'cherrypy.wsgiserver'
  h = 'WWW-Authenticate'
Function Details [hide private]

format_exc(limit=None)

source code 

Like print_exc() but return a string. Backport for Python 2.3.

plat_specific_errors(*errnames)

source code 

Return error numbers for all errors in errnames on this platform.

The 'errno' module contains different global constants depending on the specific platform (OS). This function will return the list of numeric values for a given list of potential names.

read_headers(rfile, hdict=None)

source code 

Read headers from the given stream into the given header dict.

If hdict is None, a new header dict is created. Returns the populated header dict.

Headers which are repeated are folded together using a comma if their specification so dictates.

This function raises ValueError when the read bytes violate the HTTP spec. You should probably return "400 Bad Request" if this happens.


Variables Details [hide private]

socket_errors_to_ignore

Value:
[32,
 102,
 103,
 104,
 9,
 110,
 111,
 112,
...

comma_separated_headers

Value:
['Accept',
 'Accept-Charset',
 'Accept-Encoding',
 'Accept-Language',
 'Accept-Ranges',
 'Allow',
 'Cache-Control',
 'Connection',
...

ssl_adapters

Value:
{'builtin': 'cherrypy.wsgiserver.ssl_builtin.BuiltinSSLAdapter',
 'pyopenssl': 'cherrypy.wsgiserver.ssl_pyopenssl.pyOpenSSLAdapter'}

wsgi_gateways

Value:
{(1, 0): <class 'cherrypy.wsgiserver.wsgiserver2.WSGIGateway_10'>,
 ('u', 0): <class 'cherrypy.wsgiserver.wsgiserver2.WSGIGateway_u0'>}