Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

root/tags/cherrypy-2.1.0-rc1/cherrypy/server.py

Revision 616 (checked in by mikerobi, 3 years ago)

fixed ticket:285, made cgi.maxlen global, as recommended in ticket:90

Line 
1 """
2 Copyright (c) 2004, CherryPy Team (team@cherrypy.org)
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8     * Redistributions of source code must retain the above copyright notice,
9       this list of conditions and the following disclaimer.
10     * Redistributions in binary form must reproduce the above copyright notice,
11       this list of conditions and the following disclaimer in the documentation
12       and/or other materials provided with the distribution.
13     * Neither the name of the CherryPy Team nor the names of its contributors
14       may be used to endorse or promote products derived from this software
15       without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 """
28
29 """
30 Main CherryPy module:
31     - Creates a server
32 """
33
34 import warnings
35 import threading
36 import time
37 import sys
38
39 import cherrypy
40 from cherrypy import _cphttptools
41 from cherrypy.lib import autoreload, profiler
42
43
44 # Set some special attributes for adding hooks
45 onStartServerList = []
46 onStartThreadList = []
47 onStopServerList = []
48 onStopThreadList = []
49
50
51 def start(initOnly=False, serverClass=None):
52     defaultOn = (cherrypy.config.get("server.environment") == "development")
53     if cherrypy.config.get('autoreload.on', defaultOn):
54         # Check initOnly. If True, we're probably not starting
55         # our own webserver, and therefore could do Very Bad Things
56         # when autoreload calls sys.exit.
57         if not initOnly:
58             autoreload.main(_start, (initOnly, serverClass))
59             return
60    
61     _start(initOnly, serverClass)
62
63 def _start(initOnly=False, serverClass=None):
64     """
65         Main function. All it does is this:
66             - output config options
67             - create response and request objects
68             - starts a server
69             - initilizes built in filters
70     """
71    
72     if cherrypy.codecoverage:
73         from cherrypy.lib import covercp
74         covercp.start()
75    
76     # Use a flag to indicate the state of the cherrypy application server.
77     # 0 = Not started
78     # None = In process of starting
79     # 1 = Started, ready to receive requests
80     cherrypy._appserver_state = None
81    
82     # Output config options to log
83     if cherrypy.config.get("server.logConfigOptions", True):
84         cherrypy.config.outputConfigMap()
85    
86     # Check the config options
87     # TODO
88     # config.checkConfigOptions()
89    
90     # If sessions are stored in files and we
91     # use threading, we need a lock on the file
92     if (cherrypy.config.get('server.threadPool') > 1
93         and cherrypy.config.get('session.storageType') == 'file'):
94         cherrypy._sessionFileLock = threading.RLock()
95    
96     # set cgi.maxlen which will limit the size of POST request bodies
97     import cgi
98     cgi.maxlen = cherrypy.config.get('server.maxRequestSize')
99    
100     # Call the functions from cherrypy.server.onStartServerList
101     for func in cherrypy.server.onStartServerList:
102         func()
103    
104     # Set up the profiler if requested.
105     if cherrypy.config.get("profiling.on", False):
106         ppath = cherrypy.config.get("profiling.path", "")
107         cherrypy.profiler = profiler.Profiler(ppath)
108     else:
109         cherrypy.profiler = None
110
111     # Initilize the built in filters
112     cherrypy._cputil._cpInitDefaultFilters()
113     cherrypy._cputil._cpInitUserDefinedFilters()
114    
115     if initOnly:
116         cherrypy._appserver_state = 1
117     else:
118         run_server(serverClass)
119
120 def check_port(host, port):
121     """Raise an error if the given port is not free on the given host."""
122    
123     import socket
124     try:
125         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
126         s.connect((host, int(port)))
127         s.close()
128         raise IOError("Port %s is in use on %s; perhaps the previous "
129                       "server did not shut down properly." % (port, host))
130     except socket.error:
131         pass
132
133 def run_server(serverClass=None):
134     """Prepare the requested server and then run it."""
135    
136     if cherrypy._httpserver is not None:
137         warnings.warn("You seem to have an HTTP server still running."
138                       "Please call cherrypy.server.stop() before continuing.")
139    
140     # Instantiate the server.
141     if serverClass is None:
142         serverClass = cherrypy.config.get("server.class", None)
143     if serverClass and isinstance(serverClass, basestring):
144         serverClass = cherrypy._cputil.attributes(serverClass)
145     if serverClass is None:
146         import _cpwsgi
147         serverClass = _cpwsgi.WSGIServer
148    
149     if cherrypy.config.get('server', 'socketPort'):
150         host = cherrypy.config.get('server.socketHost')
151         port = cherrypy.config.get('server.socketPort')
152         check_port(host, port)
153         if not host:
154             host = 'localhost'
155         onWhat = "http://%s:%s/" % (host, port)
156     else:
157         onWhat = "socket file: %s" % cherrypy.config.get('server.socketFile')
158     cherrypy.log("Serving HTTP on %s" % onWhat, 'HTTP')
159    
160     # Start the http server. This must be done after check_port, above.
161     cherrypy._httpserver = serverClass()
162     try:
163         try:
164             cherrypy._appserver_state = 1
165             # This should block until the http server stops.
166             cherrypy._httpserver.start()
167         except (KeyboardInterrupt, SystemExit):
168             pass
169     finally:
170         cherrypy.log("<Ctrl-C> hit: shutting down", "HTTP")
171         stop()
172
173
174 seen_threads = {}
175
176 def request(clientAddress, remoteHost, requestLine, headers, rfile, scheme="http"):
177     """request(clientAddress, remoteHost, requestLine, headers, rfile, scheme="http")
178     
179     clientAddress: the (IP address, port) of the client
180     remoteHost: the IP address of the client
181     requestLine: "<HTTP method> <url?qs> HTTP/<version>",
182             e.g. "GET /main?abc=123 HTTP/1.1"
183     headers: a list of (key, value) tuples
184     rfile: a file-like object from which to read the HTTP request body
185     scheme: either "http" or "https"; defaults to "http"
186     """
187     if cherrypy._appserver_state == 0:
188         raise cherrypy.NotReady("No thread has called cherrypy.server.start().")
189    
190     trials = 0
191     while cherrypy._appserver_state == None:
192         # Give the server thread time to complete.
193         trials += 1
194         if trials > 10:
195             raise cherrypy.NotReady("cherrypy.server.start() encountered errors.")
196         time.sleep(1)
197    
198     threadID = threading._get_ident()
199     if threadID not in seen_threads:
200        
201         if cherrypy.codecoverage:
202             from cherrypy.lib import covercp
203             covercp.start()
204        
205         i = len(seen_threads) + 1
206         seen_threads[threadID] = i
207         # Call the functions from cherrypy.server.onStartThreadList
208         for func in cherrypy.server.onStartThreadList:
209             func(i)
210    
211     if cherrypy.profiler:
212         cherrypy.profiler.run(_cphttptools.Request, clientAddress, remoteHost,
213                               requestLine, headers, rfile, scheme)
214     else:
215         _cphttptools.Request(clientAddress, remoteHost,
216                              requestLine, headers, rfile, scheme)
217
218 def stop():
219     """Shutdown CherryPy (and any HTTP servers it started)."""
220     try:
221         httpstop = cherrypy._httpserver.stop
222     except AttributeError:
223         pass
224     else:
225         httpstop()
226    
227     # Call the functions from cherrypy.server.onStopThreadList
228     for thread_ident, i in seen_threads.iteritems():
229         for func in cherrypy.server.onStopThreadList:
230             func(i)
231     seen_threads.clear()
232    
233     # Call the functions from cherrypy.server.onStopServerList
234     for func in cherrypy.server.onStopServerList:
235         func()
236    
237     cherrypy._httpserver = None
238     cherrypy._appserver_state = 0
239
240 def restart():
241     """Stop and start CherryPy."""
242     http = getattr(cherrypy, '_httpserver', None)
243     if http:
244         stop()
245         # Give HTTP servers time to shut down their thread pools.
246         time.sleep(1)
247         # Start the server in a new thread
248         threading.Thread(target=_start, kwargs={"serverClass": http.__class__}).start
249     else:
250         stop()
251         _start(initOnly=True)
Note: See TracBrowser for help on using the browser.

Hosted by WebFaction

Log in as guest/cpguest to create tickets