Commits

Remi Delon  committed 7cc9d5c

Implemented cpg.server.stop() - ticket #4

  • Participants
  • Parent commits 751d4aa
  • Branches cherrypy

Comments (0)

Files changed (4)

File _cpdefaults.py

         logToScreen = int(cpg.parsedConfigFile.get('server', 'logToScreen'))
     except:
         logToScreen = True
-    s = nowStr + ' ' + context + ' ' + level + msg
+    s = nowStr + ' ' + context + ' ' + level + ' ' + msg
     if logToScreen:
         print s
     if cpg.configOption.logFile:

File _cphttpserver.py

 
 import cpg, sys, threading, SocketServer, _cphttptools, BaseHTTPServer, socket, Queue, _cputil
 
+def stop():
+    cpg._server.shutdown()
+
 def start():
     """ Prepare the HTTP server and then run it """
 
-    # TODO: SSL
-
     # If sessions are stored in files and we
     # use threading, we need a lock on the file
-    if (cpg.configOption.threadPool > 1 or cpg.configOption.threading) and \
+    if (cpg.configOption.threadPool > 1) and \
             cpg.configOption.sessionStorageType == 'file':
         cpg._sessionFileLock = threading.RLock()
 
 
     if cpg.configOption.socketFile:
         # AF_UNIX socket
-        if cpg.configOption.forking:
-            class MyCherryHTTPServer(SocketServer.ForkingMixIn,CherryHTTPServer): address_family = socket.AF_UNIX
-        elif cpg.configOption.threading:
-            class MyCherryHTTPServer(CherryThreadingMixIn,CherryHTTPServer): address_family = socket.AF_UNIX
-        else:
-            class MyCherryHTTPServer(CherryHTTPServer): address_family = socket.AF_UNIX
+        # TODO: Handle threading here
+        class MyCherryHTTPServer(CherryHTTPServer): address_family = socket.AF_UNIX
     else:
         # AF_INET socket
-        if cpg.configOption.forking:
-            class MyCherryHTTPServer(SocketServer.ForkingMixIn,CherryHTTPServer): pass
-        elif cpg.configOption.threading:
-            class MyCherryHTTPServer(CherryThreadingMixIn,CherryHTTPServer):pass
-        elif cpg.configOption.threadPool > 1:
+        if cpg.configOption.threadPool > 1:
             MyCherryHTTPServer = PooledThreadServer
         else:
             MyCherryHTTPServer = CherryHTTPServer
         myCherryHTTPServer = ServerClass(server_address, cpg.configOption.threadPool, HandlerClass)
     else:
         myCherryHTTPServer = ServerClass(server_address, HandlerClass)
+    cpg._server = myCherryHTTPServer
     if cpg.configOption.socketFile:
         try: os.chmod(socketFile, 0777) # So everyone can access the socket
         except: pass
     else: onWhat = "socket file: %s" % cpg.configOption.socketFile
     _cpLogMessage("Serving %s on %s" % (servingWhat, onWhat), 'HTTP')
 
-    # If configOption.processPool is more than one, create new processes
-    if cpg.configOption.processPool > 1:
-        for i in range(cpg.configOption.processPool):
-            _cpLogMessage("Forking a kid", "HTTP")
-            if not os.fork():
-                # Kid
-                # initProcess(i)
-                try: myCherryHTTPServer.serve_forever()
-                except KeyboardInterrupt:
-                    _cpLogMessage("<Ctrl-C> hit: shutting down", "HTTP")
-                    myCherryHTTPServer.shutdownCtrlC()
-    else:
-        try: myCherryHTTPServer.serve_forever()
-        except KeyboardInterrupt:
-            _cpLogMessage("<Ctrl-C> hit: shutting down", "HTTP")
-            myCherryHTTPServer.shutdownCtrlC()
+    try:
+        myCherryHTTPServer.serve_forever()
+    except KeyboardInterrupt:
+        _cpLogMessage("<Ctrl-C> hit: shutting down", "HTTP")
+        myCherryHTTPServer.shutdown()
 
 
 class CherryHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
             self.wfile
         )
 
-    def setup(self):
-        """ We have to override this to handle SSL
-            (socket object from the OpenSSL package don't
-            have the makefile method) """
-
-        if not cpg.configOption.sslKeyFile:
-            BaseHTTPServer.BaseHTTPRequestHandler.setup(self)
-
-        """ SSL sockets from the OpenSSL package don't have the "makefile"
-            method so we have to hack our way around this ... """
-
-        class CherrySSLFileObject(socket._fileobject):
-            """ This is used for implementing the "flush" methods
-                for SSL sockets """
-
-            def flush(self):
-                """ Some sockets have a "sendall" method, some don't """
-                if self._wbuf:
-                    if hasattr(self._sock, "sendall"):
-                        if type(self._wbuf)==type([]): # python2.3
-                            self._sock.sendall("".join(self._wbuf))
-                            self._wbuf=[]
-                        else:
-                            self._sock.sendall(self._wbuf)
-                            self._wbuf=""
-                    else:
-                        while self._wbuf:
-                            _sentChar=self._sock.send(self._wbuf)
-                            self._wbuf=self._wbuf[_sentChar:]
-
         self.connection = self.request
         self.rfile = CherrySSLFileObject(self.connection, 'rb', self.rbufsize)
         self.wfile = CherrySSLFileObject(self.connection, 'wb', self.wbufsize)
         #  the request socket to blocking
 
         request, client_address = self.socket.accept()
-        if hasattr(request,'setblocking'): # Jython doesn't have setblocking
-            request.setblocking(1)
+        request.setblocking(1)
         return request, client_address
 
     def handle_request(self):
             return 1
         except KeyboardInterrupt:
             print "<Ctrl-C> hit: shutting down"
-            sys.exit(0)
+            self.shutdown()
 
-    def shutdownCtrlC(self):
-        self.shutdown()
+    def serve_forever(self):
+        """Override serve_forever to handle shutdown."""
+        self.__running = 1
+        while self.__running:
+            self.handle_request()
+
+    def shutdown(self):
+        self.__running = 0
 
 _SHUTDOWNREQUEST = (0,0)
 
         """Gracefully shutdown a server that is serve_forever()ing."""
         self.__running = 0
 
-    def shutdownCtrlC(self):
-        self.server_close()
-
     def serve_forever(self):
         """Handle one request at a time until doomsday (or shutdown is called)."""
         if self._workerThreads == []:

File _cpserver.py

         _cphttpserver.start()
 
 def stop():
-    _cphttpserver.shutdown()
+    _cphttpserver.stop()
 

File test/helper.py

     return cpg, cookies
 
 def shutdownServer(pid, mode):
-    if mode=='t':
-        u=urllib.urlopen("http://127.0.0.1:8000/shutdown/thread")
-        try: u=urllib.urlopen("http://127.0.0.1:8000/shutdown/dummy")
-        except IOError: pass
-        except AttributeError: pass # Happens on Mac OS X when run with Python-2.3
-    elif mode=='tp':
-        u=urllib.urlopen("http://127.0.0.1:8000/shutdown/thread")
-        try: u=urllib.urlopen("http://127.0.0.1:8000/shutdown/dummy")
-        except IOError: pass # Happens on Windows
-    else:
-        try:
-            u=urllib.urlopen("http://127.0.0.1:8000/shutdown/regular")
-        except IOError: pass
-        except AttributeError: pass # For Python2.3
+    urllib.urlopen("http://127.0.0.1:8000/shutdown/all")
+    if mode == 'tp':
+        urllib.urlopen("http://127.0.0.1:8000/dummy")
+    return
 
 def checkResult(testName, infoMap, serverMode, cpg, rule, failedList):
     result = False
     f = open('testsite.py', 'w')
     beforeStart = '''
 class Shutdown:
-    def dummy(self):
-        return "OK"
-    dummy.exposed = True
-    def regular(self):
-        import os
-        os._exit(0)
-    regular.exposed = True
-    def thread(self):
-        import threading
-        for t in threading.enumerate(): t.setName("NOT RUNNING")
-        return "OK"
-    thread.exposed = True
+    def all(self):
+        cpg.server.stop()
+    all.exposed = True
 cpg.root.shutdown = Shutdown()
 def f(*a, **kw): return ""
 cpg.root._cpLogMessage = f