Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/cherrypy/_cpserver.py
diff options
context:
space:
mode:
Diffstat (limited to 'cherrypy/_cpserver.py')
-rwxr-xr-xcherrypy/_cpserver.py195
1 files changed, 195 insertions, 0 deletions
diff --git a/cherrypy/_cpserver.py b/cherrypy/_cpserver.py
new file mode 100755
index 0000000..c1695a6
--- /dev/null
+++ b/cherrypy/_cpserver.py
@@ -0,0 +1,195 @@
+"""Manage HTTP servers with CherryPy."""
+
+import warnings
+
+import cherrypy
+from cherrypy.lib import attributes
+from cherrypy._cpcompat import basestring
+
+# We import * because we want to export check_port
+# et al as attributes of this module.
+from cherrypy.process.servers import *
+
+
+class Server(ServerAdapter):
+ """An adapter for an HTTP server.
+
+ You can set attributes (like socket_host and socket_port)
+ on *this* object (which is probably cherrypy.server), and call
+ quickstart. For example::
+
+ cherrypy.server.socket_port = 80
+ cherrypy.quickstart()
+ """
+
+ socket_port = 8080
+ """The TCP port on which to listen for connections."""
+
+ _socket_host = '127.0.0.1'
+ def _get_socket_host(self):
+ return self._socket_host
+ def _set_socket_host(self, value):
+ if value == '':
+ raise ValueError("The empty string ('') is not an allowed value. "
+ "Use '0.0.0.0' instead to listen on all active "
+ "interfaces (INADDR_ANY).")
+ self._socket_host = value
+ socket_host = property(_get_socket_host, _set_socket_host,
+ doc="""The hostname or IP address on which to listen for connections.
+
+ Host values may be any IPv4 or IPv6 address, or any valid hostname.
+ The string 'localhost' is a synonym for '127.0.0.1' (or '::1', if
+ your hosts file prefers IPv6). The string '0.0.0.0' is a special
+ IPv4 entry meaning "any active interface" (INADDR_ANY), and '::'
+ is the similar IN6ADDR_ANY for IPv6. The empty string or None are
+ not allowed.""")
+
+ socket_file = None
+ """If given, the name of the UNIX socket to use instead of TCP/IP.
+
+ When this option is not None, the `socket_host` and `socket_port` options
+ are ignored."""
+
+ socket_queue_size = 5
+ """The 'backlog' argument to socket.listen(); specifies the maximum number
+ of queued connections (default 5)."""
+
+ socket_timeout = 10
+ """The timeout in seconds for accepted connections (default 10)."""
+
+ shutdown_timeout = 5
+ """The time to wait for HTTP worker threads to clean up."""
+
+ protocol_version = 'HTTP/1.1'
+ """The version string to write in the Status-Line of all HTTP responses,
+ for example, "HTTP/1.1" (the default). Depending on the HTTP server used,
+ this should also limit the supported features used in the response."""
+
+ thread_pool = 10
+ """The number of worker threads to start up in the pool."""
+
+ thread_pool_max = -1
+ """The maximum size of the worker-thread pool. Use -1 to indicate no limit."""
+
+ max_request_header_size = 500 * 1024
+ """The maximum number of bytes allowable in the request headers. If exceeded,
+ the HTTP server should return "413 Request Entity Too Large"."""
+
+ max_request_body_size = 100 * 1024 * 1024
+ """The maximum number of bytes allowable in the request body. If exceeded,
+ the HTTP server should return "413 Request Entity Too Large"."""
+
+ instance = None
+ """If not None, this should be an HTTP server instance (such as
+ CPWSGIServer) which cherrypy.server will control. Use this when you need
+ more control over object instantiation than is available in the various
+ configuration options."""
+
+ ssl_context = None
+ """When using PyOpenSSL, an instance of SSL.Context."""
+
+ ssl_certificate = None
+ """The filename of the SSL certificate to use."""
+
+ ssl_certificate_chain = None
+ """When using PyOpenSSL, the certificate chain to pass to
+ Context.load_verify_locations."""
+
+ ssl_private_key = None
+ """The filename of the private key to use with SSL."""
+
+ ssl_module = 'pyopenssl'
+ """The name of a registered SSL adaptation module to use with the builtin
+ WSGI server. Builtin options are 'builtin' (to use the SSL library built
+ into recent versions of Python) and 'pyopenssl' (to use the PyOpenSSL
+ project, which you must install separately). You may also register your
+ own classes in the wsgiserver.ssl_adapters dict."""
+
+ nodelay = True
+ """If True (the default since 3.1), sets the TCP_NODELAY socket option."""
+
+ wsgi_version = (1, 0)
+ """The WSGI version tuple to use with the builtin WSGI server.
+ The provided options are (1, 0) [which includes support for PEP 3333,
+ which declares it covers WSGI version 1.0.1 but still mandates the
+ wsgi.version (1, 0)] and ('u', 0), an experimental unicode version.
+ You may create and register your own experimental versions of the WSGI
+ protocol by adding custom classes to the wsgiserver.wsgi_gateways dict."""
+
+ def __init__(self):
+ self.bus = cherrypy.engine
+ self.httpserver = None
+ self.interrupt = None
+ self.running = False
+
+ def httpserver_from_self(self, httpserver=None):
+ """Return a (httpserver, bind_addr) pair based on self attributes."""
+ if httpserver is None:
+ httpserver = self.instance
+ if httpserver is None:
+ from cherrypy import _cpwsgi_server
+ httpserver = _cpwsgi_server.CPWSGIServer(self)
+ if isinstance(httpserver, basestring):
+ # Is anyone using this? Can I add an arg?
+ httpserver = attributes(httpserver)(self)
+ return httpserver, self.bind_addr
+
+ def start(self):
+ """Start the HTTP server."""
+ if not self.httpserver:
+ self.httpserver, self.bind_addr = self.httpserver_from_self()
+ ServerAdapter.start(self)
+ start.priority = 75
+
+ def _get_bind_addr(self):
+ if self.socket_file:
+ return self.socket_file
+ if self.socket_host is None and self.socket_port is None:
+ return None
+ return (self.socket_host, self.socket_port)
+ def _set_bind_addr(self, value):
+ if value is None:
+ self.socket_file = None
+ self.socket_host = None
+ self.socket_port = None
+ elif isinstance(value, basestring):
+ self.socket_file = value
+ self.socket_host = None
+ self.socket_port = None
+ else:
+ try:
+ self.socket_host, self.socket_port = value
+ self.socket_file = None
+ except ValueError:
+ raise ValueError("bind_addr must be a (host, port) tuple "
+ "(for TCP sockets) or a string (for Unix "
+ "domain sockets), not %r" % value)
+ bind_addr = property(_get_bind_addr, _set_bind_addr,
+ doc='A (host, port) tuple for TCP sockets or a str for Unix domain sockets.')
+
+ def base(self):
+ """Return the base (scheme://host[:port] or sock file) for this server."""
+ if self.socket_file:
+ return self.socket_file
+
+ host = self.socket_host
+ if host in ('0.0.0.0', '::'):
+ # 0.0.0.0 is INADDR_ANY and :: is IN6ADDR_ANY.
+ # Look up the host name, which should be the
+ # safest thing to spit out in a URL.
+ import socket
+ host = socket.gethostname()
+
+ port = self.socket_port
+
+ if self.ssl_certificate:
+ scheme = "https"
+ if port != 443:
+ host += ":%s" % port
+ else:
+ scheme = "http"
+ if port != 80:
+ host += ":%s" % port
+
+ return "%s://%s" % (scheme, host)
+