Commits

Robert Brewer committed 0af4695

Merged some useful updates from /branches/ooconf. Mostly speed tweaks, and removing some dead code.

Comments (0)

Files changed (15)

+
+import ConfigParser
+
 import _cputil, cperror
-import ConfigParser
 from lib import autoreload
 
 cpg = None # delayed import
+def init():
+    global cpg
+    if not cpg:
+        import cpg
+    reset()
+
+def reset(useDefaults=True):
+    configMap.clear()
+    if useDefaults:
+        configMap["global"] = defaultGlobal.copy()
+
+# This configMap dict holds the settings metadata for all cpg objects.
+# Keys are URL paths, and values are dicts.
+configMap = {}
 
 defaultGlobal = {
     'server.socketPort': 8080,
     
     'sessionFilter.new': 'sessionMap', # legacy setting
     }
-configMap = {"global": defaultGlobal.copy()}
 
 def update(updateMap=None, file=None):
     if updateMap:
 def get(key, defaultValue=None, returnSection=False, startPath = None):
     # Look, ma, no Python function calls! Uber-fast.
     # start path lest you overload the starting search path (needed by getAll)
-    global cpg
-    if not cpg:
-        import cpg
-    
     if startPath:
         path = startPath
     else:
 
 def _cpOnError():
     """ Default _cpOnError method """
-
-    import traceback, StringIO
-    bodyFile = StringIO.StringIO()
-    traceback.print_exc(file = bodyFile)
-    cpg.response.body = [bodyFile.getvalue()]
+    import sys, traceback
+    content = "".join(traceback.format_exception(*sys.exc_info()))
+    cpg.response.body = [content]
     cpg.response.headerMap['Content-Type'] = 'text/plain'
 
 def _cpSaveSessionData(sessionId, sessionData, expirationTime,
 Common Service Code for CherryPy
 """
 
-import urllib, sys, time, traceback, types, StringIO, cgi
+import urllib, sys, time, traceback, types, cgi
 import mimetypes, Cookie, urlparse
+from lib.filter import basefilter
 import cpg, _cputil, cperror, _cpdefaults
-from lib.filter import basefilter
+
+# Can't use cStringIO; doesn't support unicode strings  
+# See http://www.python.org/sf/216388  
+import StringIO
 
 from BaseHTTPServer import BaseHTTPRequestHandler
 responseCodes = BaseHTTPRequestHandler.responses
         cpg.response.headers = None
         cpg.response.body = None
         
-        year, month, day, hh, mm, ss, wd, y, z = time.gmtime(time.time())
+        year, month, day, hh, mm, ss, wd, y, z = time.gmtime()
         date = ("%s, %02d %3s %4d %02d:%02d:%02d GMT" %
                 (weekdayname[wd], day, monthname[month], year, hh, mm, ss))
         cpg.response.headerMap = {
             if name == 'Cookie':
                 cpg.request.simpleCookie.load(value)
         
-        # Set peer_certificate (in SSL mode) so the
-        # web app can examine the client certificate
-        try:
-            cpg.request.peerCertificate = self.request.get_peer_certificate()
-        except:
-            pass
         msg = "%s - %s" % (cpg.request.remoteAddr, self.requestLine[:-2])
         _cputil.getSpecialAttribute('_cpLogMessage')(msg, "HTTP")
         
 
 def main():
     """Obtain and set cpg.response.body."""
-    path = cpg.request.path
-    # Remove leading and trailing slash
-    path = path.strip("/")
-    # Replace quoted chars (eg %20) from url
-    path = urllib.unquote(path)
-    
     try:
         func, objectPathList, virtualPathList = mapPathToObject()
         
     
     if (cpg.config.get("server.protocolVersion") != "HTTP/1.1"
         and cpg.response.headerMap.get('Content-Length') == 0):
-        buf = StringIO.StringIO()
-        for chunk in cpg.response.body:
-            buf.write(chunk)
-        buf.seek(0)
-        content = buf.read()
+        content = ''.join(cpg.response.body)
         cpg.response.body = [content]
         cpg.response.headerMap['Content-Length'] = len(content)
     
         print "    objectPathList: %s" % objectPathList
     
     # Try successive objects... (and also keep the remaining object list)
-    objCache = {}
     isFirst = True
     isSecond = False
-    isDefault = False
     foundIt = False
     virtualPathList = []
     while objectPathList:
             candidate = getObjFromPath(objectPathList)
             if callable(candidate) and getattr(candidate, 'exposed', False):
                 foundIt = True
-                isDefault = True
                 break
             objectPathList.pop() # Remove "default"
         if isSecond:
         self.wfile.write("\r\n")
         self.wfile.flush()
     def terminate(self):
+        if not self.sent_headers:
+            self.sent_headers = True
+            self.send_headers()
         self.rfile.close()
         self.wfile.close()
         self.socket.close()
 # import server module
 import _cpserver as server
 import _cpconfig as config
+config.init()
 
 # decorator function for exposing methods
 def expose(func):

lib/filter/logdebuginfofilter.py

 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """
 
-import time, StringIO, pickle
+import time
+
+try:
+    import cPickle as pickle
+except ImportError:
+    import pickle
+
 from basefilter import BaseFilter
 
 class LogDebugInfoFilter(BaseFilter):
                 and cpg.config.get('session.storageType')):
                 # Pickle session data to get its size
                 try:
-                    f = StringIO.StringIO()
-                    pickle.dump(cpg.request.sessionMap, f, 1)
-                    dumpStr = f.getvalue()
-                    f.close()
+                    dumpStr = pickle.dumps(cpg.request.sessionMap, 1)
                     logList.append("Session data size: %.02fKB" %
                                    (len(dumpStr) / float(1024)))
                 except:

lib/filter/nsgmlsfilter.py

 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """
 
-import os, cgi, StringIO, traceback
+import os, cgi
 from basefilter import BaseFilter
 
 class NsgmlsFilter(BaseFilter):

lib/filter/sessionfilter/sessionfilter.py

 from cherrypy.lib.filter.basefilter import BaseFilter
 import cherrypy.cpg
 
-import os.path, time, re
+import time, re
 
 from sessionerrors import SessionNotFoundError 
 
     
     sessions = {}
     
-    path = cpg.config.get('sessionFilter.new', returnSection = True )
-    paths=os.path.split(path)
-    
     sessionNames = cpg.config.getAll('sessionFilter.new')
     for sessionPath in sessionNames:
         sessionName = sessionNames[sessionPath]
             sessionName = sessions[sessionPath]
             cookieName = cpg.config.get('%s.cookieName' % sessionName, None)
             if not cookieName:
-                cookieName = cpg.config.get('sessionFilter.cookieName') + '|' + sessionName + '|' + re.sub('/','_', sessionPath)
+                cookieName = (cpg.config.get('sessionFilter.cookieName') +
+                              '|' + sessionName +
+                              '|' + re.sub('/','_', sessionPath))
                 cpg.config.update({
                                     sessionPath : {'%s.cookieName' % sessionName : cookieName}
                                   })
             conn.endheaders()
             
             # Handle response
-            response = conn.getresponse()
+            try:
+                response = conn.getresponse()
+            except httplib.BadStatusLine:
+                # Improper response from server.
+                print
+                print "Server did not return a response."
+                print "status>", repr(cpg.response.status)
+                print "headers>", repr(cpg.response.headers)
+                print "body>", repr(cpg.response.body)
+                raise
             
             cpg.response.status = "%s %s" % (response.status, response.reason)
             
         for testmod in testList:
             # Must run each module in a separate suite,
             # because each module uses/overwrites cpg globals.
-            cpg.config.configMap.clear()
-            cpg.config.configMap["global"] = cpg.config.defaultGlobal.copy()
+            cpg.config.reset()
             cpg.config.update({'global': server_conf.copy()})
             suite = CPTestLoader.loadTestsFromName(testmod)
             CPTestRunner(verbosity=2).run(suite)

test/test_combinedfilters.py

         zfile.close()
         
         helper.request("/", headers=[("Accept-Encoding", "gzip")])
-        self.assertEqual(zbuf.getvalue()[:3] in cpg.response.body, True)
+        self.assert_(zbuf.getvalue()[:3] in cpg.response.body)
 
 
 if __name__ == '__main__':

test/test_core.py

     def __init__(cls, name, bases, dct):
         type.__init__(name, bases, dct)
         for value in dct.itervalues():
-            if type(value) == types.FunctionType:
+            if isinstance(value, types.FunctionType):
                 value.exposed = True
         setattr(cpg.root, name.lower(), cls())
 class Test(object):

test/test_decodingencoding_filter.py

 import unittest
 import helper
 
-europoundUtf8 = u'\x80\xa3'.encode('utf-8')
+europoundUtf8 = europoundUnicode.encode('utf-8')
 
 class DecodingEncodingFilterTest(unittest.TestCase):
     

test/test_tutorials.py

 
 def load_tut_module(tutorialName):
     """Import or reload tutorial module as needed."""
-    cpg.config.configMap.clear()
-    cpg.config.configMap["global"] = cpg.config.defaultGlobal.copy()
+    cpg.config.reset()
     cpg.config.update({'global': server_conf.copy()})
     
     target = "cherrypy.tutorial." + tutorialName

tutorial/tutorial.conf

 server.threadPool = 10
 server.environment = "production"
 session.storageType= "ram"
+# server.logToScreen = False