1 """Manage HTTP servers with CherryPy."""
2
3 import warnings
4
5 import cherrypy
6 from cherrypy.lib import attributes
7 from cherrypy._cpcompat import basestring, py3k
8
9
10
11 from cherrypy.process.servers import *
12
13
15
16 """An adapter for an HTTP server.
17
18 You can set attributes (like socket_host and socket_port)
19 on *this* object (which is probably cherrypy.server), and call
20 quickstart. For example::
21
22 cherrypy.server.socket_port = 80
23 cherrypy.quickstart()
24 """
25
26 socket_port = 8080
27 """The TCP port on which to listen for connections."""
28
29 _socket_host = '127.0.0.1'
30
33
35 if value == '':
36 raise ValueError("The empty string ('') is not an allowed value. "
37 "Use '0.0.0.0' instead to listen on all active "
38 "interfaces (INADDR_ANY).")
39 self._socket_host = value
40 socket_host = property(
41 _get_socket_host,
42 _set_socket_host,
43 doc="""The hostname or IP address on which to listen for connections.
44
45 Host values may be any IPv4 or IPv6 address, or any valid hostname.
46 The string 'localhost' is a synonym for '127.0.0.1' (or '::1', if
47 your hosts file prefers IPv6). The string '0.0.0.0' is a special
48 IPv4 entry meaning "any active interface" (INADDR_ANY), and '::'
49 is the similar IN6ADDR_ANY for IPv6. The empty string or None are
50 not allowed.""")
51
52 socket_file = None
53 """If given, the name of the UNIX socket to use instead of TCP/IP.
54
55 When this option is not None, the `socket_host` and `socket_port` options
56 are ignored."""
57
58 socket_queue_size = 5
59 """The 'backlog' argument to socket.listen(); specifies the maximum number
60 of queued connections (default 5)."""
61
62 socket_timeout = 10
63 """The timeout in seconds for accepted connections (default 10)."""
64
65 shutdown_timeout = 5
66 """The time to wait for HTTP worker threads to clean up."""
67
68 protocol_version = 'HTTP/1.1'
69 """The version string to write in the Status-Line of all HTTP responses,
70 for example, "HTTP/1.1" (the default). Depending on the HTTP server used,
71 this should also limit the supported features used in the response."""
72
73 thread_pool = 10
74 """The number of worker threads to start up in the pool."""
75
76 thread_pool_max = -1
77 """The maximum size of the worker-thread pool. Use -1 to indicate no limit.
78 """
79
80 max_request_header_size = 500 * 1024
81 """The maximum number of bytes allowable in the request headers.
82 If exceeded, the HTTP server should return "413 Request Entity Too Large".
83 """
84
85 max_request_body_size = 100 * 1024 * 1024
86 """The maximum number of bytes allowable in the request body. If exceeded,
87 the HTTP server should return "413 Request Entity Too Large"."""
88
89 instance = None
90 """If not None, this should be an HTTP server instance (such as
91 CPWSGIServer) which cherrypy.server will control. Use this when you need
92 more control over object instantiation than is available in the various
93 configuration options."""
94
95 ssl_context = None
96 """When using PyOpenSSL, an instance of SSL.Context."""
97
98 ssl_certificate = None
99 """The filename of the SSL certificate to use."""
100
101 ssl_certificate_chain = None
102 """When using PyOpenSSL, the certificate chain to pass to
103 Context.load_verify_locations."""
104
105 ssl_private_key = None
106 """The filename of the private key to use with SSL."""
107
108 if py3k:
109 ssl_module = 'builtin'
110 """The name of a registered SSL adaptation module to use with
111 the builtin WSGI server. Builtin options are: 'builtin' (to
112 use the SSL library built into recent versions of Python).
113 You may also register your own classes in the
114 wsgiserver.ssl_adapters dict."""
115 else:
116 ssl_module = 'pyopenssl'
117 """The name of a registered SSL adaptation module to use with the
118 builtin WSGI server. Builtin options are 'builtin' (to use the SSL
119 library built into recent versions of Python) and 'pyopenssl' (to
120 use the PyOpenSSL project, which you must install separately). You
121 may also register your own classes in the wsgiserver.ssl_adapters
122 dict."""
123
124 statistics = False
125 """Turns statistics-gathering on or off for aware HTTP servers."""
126
127 nodelay = True
128 """If True (the default since 3.1), sets the TCP_NODELAY socket option."""
129
130 wsgi_version = (1, 0)
131 """The WSGI version tuple to use with the builtin WSGI server.
132 The provided options are (1, 0) [which includes support for PEP 3333,
133 which declares it covers WSGI version 1.0.1 but still mandates the
134 wsgi.version (1, 0)] and ('u', 0), an experimental unicode version.
135 You may create and register your own experimental versions of the WSGI
136 protocol by adding custom classes to the wsgiserver.wsgi_gateways dict."""
137
143
145 """Return a (httpserver, bind_addr) pair based on self attributes."""
146 if httpserver is None:
147 httpserver = self.instance
148 if httpserver is None:
149 from cherrypy import _cpwsgi_server
150 httpserver = _cpwsgi_server.CPWSGIServer(self)
151 if isinstance(httpserver, basestring):
152
153 httpserver = attributes(httpserver)(self)
154 return httpserver, self.bind_addr
155
161 start.priority = 75
162
169
171 if value is None:
172 self.socket_file = None
173 self.socket_host = None
174 self.socket_port = None
175 elif isinstance(value, basestring):
176 self.socket_file = value
177 self.socket_host = None
178 self.socket_port = None
179 else:
180 try:
181 self.socket_host, self.socket_port = value
182 self.socket_file = None
183 except ValueError:
184 raise ValueError("bind_addr must be a (host, port) tuple "
185 "(for TCP sockets) or a string (for Unix "
186 "domain sockets), not %r" % value)
187 bind_addr = property(
188 _get_bind_addr,
189 _set_bind_addr,
190 doc='A (host, port) tuple for TCP sockets or '
191 'a str for Unix domain sockets.')
192
194 """Return the base (scheme://host[:port] or sock file) for this server.
195 """
196 if self.socket_file:
197 return self.socket_file
198
199 host = self.socket_host
200 if host in ('0.0.0.0', '::'):
201
202
203
204 import socket
205 host = socket.gethostname()
206
207 port = self.socket_port
208
209 if self.ssl_certificate:
210 scheme = "https"
211 if port != 443:
212 host += ":%s" % port
213 else:
214 scheme = "http"
215 if port != 80:
216 host += ":%s" % port
217
218 return "%s://%s" % (scheme, host)
219