Changeset 1217
- Timestamp:
- 08/05/06 17:14:46
- Files:
-
- trunk/cherrypy/_cpserver.py (modified) (5 diffs)
- trunk/cherrypy/lib/wsgiapp.py (modified) (1 diff)
- trunk/cherrypy/test/helper.py (modified) (1 diff)
- trunk/cherrypy/test/test_states.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/_cpserver.py
r1204 r1217 1 1 """Manage an HTTP server with CherryPy.""" 2 2 3 import socket 3 4 import threading 4 5 import time … … 9 10 10 11 class Server(object): 11 """Manager for a n HTTP server."""12 """Manager for a set of HTTP servers.""" 12 13 13 14 def __init__(self): 14 self.httpserver = None15 self.httpservers = {} 15 16 self.interrupt = None 16 17 … … 18 19 """Main function. MUST be called from the main thread.""" 19 20 self.interrupt = None 20 21 httpserver, bind_addr = self.httpserver_from_config(server) 22 self.httpservers[httpserver] = bind_addr 23 self._start_http(httpserver) 24 25 def httpserver_from_config(self, httpserver=None): 26 """Return a (httpserver, bind_addr) pair based on config settings.""" 21 27 conf = cherrypy.config.get 22 if server is None:23 server = conf('server.instance', None)24 if server is None:28 if httpserver is None: 29 httpserver = conf('server.instance', None) 30 if httpserver is None: 25 31 import _cpwsgi 26 server = _cpwsgi.WSGIServer() 27 if isinstance(server, basestring): 28 server = attributes(server)() 29 self.httpserver = server 32 httpserver = _cpwsgi.WSGIServer() 33 if isinstance(httpserver, basestring): 34 httpserver = attributes(httpserver)() 30 35 31 36 if conf('server.socket_port'): 32 37 host = conf('server.socket_host') 33 38 port = conf('server.socket_port') 34 wait_for_free_port(host, port)35 39 if not host: 36 40 host = 'localhost' 37 on_what = "http://%s:%s/" %(host, port)41 return httpserver, (host, port) 38 42 else: 39 on_what = "socket file: %s" % conf('server.socket_file') 43 return httpserver, conf('server.socket_file') 44 45 def start_all(self): 46 """Start all registered HTTP servers.""" 47 for httpserver in self.httpservers: 48 self._start_http(httpserver) 49 50 def _start_http(self, httpserver): 51 """Start the given httpserver in a new thread.""" 52 bind_addr = self.httpservers[httpserver] 53 if isinstance(bind_addr, tuple): 54 wait_for_free_port(*bind_addr) 55 on_what = "http://%s:%s/" % bind_addr 56 else: 57 on_what = "socket file: %s" % bind_addr 40 58 41 # HTTP servers MUST be started in a new thread, so that the 42 # main thread persists to receive KeyboardInterrupt's. If an 43 # exception is raised in the http server's thread then it's 44 # trapped here, and the http server and engine are shut down. 45 def _start_http(): 46 try: 47 self.httpserver.start() 48 except KeyboardInterrupt, exc: 49 cherrypy.log("<Ctrl-C> hit: shutting down HTTP server", "SERVER") 50 self.interrupt = exc 51 self.stop() 52 cherrypy.engine.stop() 53 except SystemExit, exc: 54 cherrypy.log("SystemExit raised: shutting down HTTP server", "SERVER") 55 self.interrupt = exc 56 self.stop() 57 cherrypy.engine.stop() 58 raise 59 t = threading.Thread(target=_start_http) 59 t = threading.Thread(target=self._start_http_thread, args=(httpserver,)) 60 60 t.setName("CPHTTPServer " + t.getName()) 61 61 t.start() 62 62 63 self.wait( )63 self.wait(httpserver) 64 64 cherrypy.log("Serving HTTP on %s" % on_what, 'HTTP') 65 65 66 def wait(self): 67 """Wait until the HTTP server is ready to receive requests.""" 68 while (not getattr(self.httpserver, "ready", False) 69 and not self.interrupt): 70 time.sleep(.1) 71 if self.interrupt: 72 raise self.interrupt 66 def _start_http_thread(self, httpserver): 67 """HTTP servers MUST be started in new threads, so that the 68 main thread persists to receive KeyboardInterrupt's. If an 69 exception is raised in the httpserver's thread then it's 70 trapped here, and the httpserver(s) and engine are shut down. 71 """ 72 try: 73 httpserver.start() 74 except KeyboardInterrupt, exc: 75 cherrypy.log("<Ctrl-C> hit: shutting down HTTP servers", "SERVER") 76 self.interrupt = exc 77 self.stop() 78 cherrypy.engine.stop() 79 except SystemExit, exc: 80 cherrypy.log("SystemExit raised: shutting down HTTP servers", "SERVER") 81 self.interrupt = exc 82 self.stop() 83 cherrypy.engine.stop() 84 raise 85 86 def wait(self, httpserver=None): 87 """Wait until the HTTP server is ready to receive requests. 73 88 74 # Wait for port to be occupied 75 if cherrypy.config.get('server.socket_port'): 76 host = cherrypy.config.get('server.socket_host') 77 port = cherrypy.config.get('server.socket_port') 78 wait_for_occupied_port(host, port) 89 If no httpserver is specified, wait for all registered httpservers. 90 """ 91 if httpserver is None: 92 httpservers = self.httpservers.items() 93 else: 94 httpservers = [(httpserver, self.httpservers[httpserver])] 95 96 for httpserver, bind_addr in httpservers: 97 while not (getattr(httpserver, "ready", False) or self.interrupt): 98 time.sleep(.1) 99 if self.interrupt: 100 raise self.interrupt 101 102 # Wait for port to be occupied 103 if isinstance(bind_addr, tuple): 104 wait_for_occupied_port(*bind_addr) 79 105 80 106 def stop(self): 81 """Stop the HTTP server.""" 82 try: 83 httpstop = self.httpserver.stop 84 except AttributeError: 85 pass 86 else: 87 # httpstop() MUST block until the server is *truly* stopped. 88 httpstop() 89 conf = cherrypy.config.get 90 if conf('server.socket_port'): 91 host = conf('server.socket_host') 92 port = conf('server.socket_port') 93 wait_for_free_port(host, port) 94 cherrypy.log("HTTP Server shut down", "HTTP") 107 """Stop all HTTP server(s).""" 108 for httpserver, bind_addr in self.httpservers.items(): 109 try: 110 httpstop = httpserver.stop 111 except AttributeError: 112 pass 113 else: 114 # httpstop() MUST block until the server is *truly* stopped. 115 httpstop() 116 if isinstance(bind_addr, tuple): 117 wait_for_free_port(*bind_addr) 118 cherrypy.log("HTTP Server shut down", "HTTP") 95 119 96 120 def restart(self): … … 98 122 self.stop() 99 123 self.interrupt = None 100 self.start ()124 self.start_all() 101 125 102 126 103 127 def check_port(host, port): 104 128 """Raise an error if the given port is not free on the given host.""" 105 sock_file = cherrypy.config.get('server.socket_file')106 if sock_file:107 return108 109 129 if not host: 110 130 host = 'localhost' 111 131 port = int(port) 112 113 import socket114 132 115 133 # AF_INET or AF_INET6 socket … … 127 145 s.close() 128 146 raise IOError("Port %s is in use on %s; perhaps the previous " 129 " server did not shut down properly." %147 "httpserver did not shut down properly." % 130 148 (repr(port), repr(host))) 131 149 except socket.error: trunk/cherrypy/lib/wsgiapp.py
r1137 r1217 32 32 environ["QUERY_STRING"] = cherrypy.request.query_string 33 33 environ["SERVER_PROTOCOL"] = cherrypy.request.protocol 34 server_name = getattr(cherrypy.server.httpserver, 'server_name', "None") 35 environ["SERVER_NAME"] = server_name 36 environ["SERVER_PORT"] = cherrypy.config.get('server.socket_port') 34 environ["SERVER_NAME"] = cherrypy.request.wsgi_environ['SERVER_NAME'] 35 environ["SERVER_PORT"] = cherrypy.request.wsgi_environ['SERVER_PORT'] 37 36 environ["REMOTE_HOST"] = cherrypy.request.remote_host 38 37 environ["REMOTE_ADDR"] = cherrypy.request.remote_addr trunk/cherrypy/test/helper.py
r1194 r1217 131 131 apps.sort() 132 132 apps.reverse() 133 cherrypy.server.httpserver.mount_points = apps 133 for s in cherrypy.server.httpservers: 134 s.mount_points = apps 134 135 135 136 suite = CPTestLoader.loadTestsFromName(testmod) trunk/cherrypy/test/test_states.py
r1204 r1217 154 154 cherrypy.engine.start(blocking=False) 155 155 cherrypy.server.start(self.server_class) 156 cherrypy.server.httpserver .interrupt = KeyboardInterrupt156 cherrypy.server.httpservers.values()[0].interrupt = KeyboardInterrupt 157 157 while cherrypy.engine.state != 0: 158 158 time.sleep(0.1) … … 243 243 tr.out.close() 244 244 finally: 245 if cherrypy.server.httpserver.ready: 246 cherrypy.server.stop() 245 cherrypy.server.stop() 247 246 cherrypy.engine.stop() 248 247

