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

Changeset 638

Show
Ignore:
Timestamp:
09/13/05 17:13:33
Author:
fumanchu
Message:

1. Extracted core filter-handling into _cpfilter.py
2. Removed old input/output structures.
3. Cleaned up the test suite.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/filterorder/cherrypy/_cphttptools.py

    r636 r638  
    4646import cherrypy 
    4747from cherrypy import _cpcgifs, _cperror, _cpwsgiserver 
    48 from cherrypy._cputil import getSpecialAttribute, _cpFilterList, formatExc 
     48from cherrypy._cputil import getSpecialAttribute, formatExc 
     49from cherrypy._cpfilter import applyFilters 
    4950from cherrypy.lib import cptools 
    5051 
     
    377378        try: 
    378379            forms = _cpcgifs.FieldStorage(fp=request.rfile, 
    379                                       headers=lowerHeaderMap, 
    380                                       environ=methenv, 
    381                                       keep_blank_values=1) 
     380                                          headers=lowerHeaderMap, 
     381                                          environ=methenv, 
     382                                          keep_blank_values=1) 
    382383        except _cpwsgiserver.MaxSizeExceeded: 
    383384            # Post data is too big 
     
    637638            name, value = line.split(": ", 1) 
    638639            cherrypy.response.headers.append((name, value)) 
    639  
    640  
    641 def applyFilters(methodName): 
    642     """Execute the given method for all registered filters.""" 
    643      
    644     methods = [] 
    645     for f in (_cpFilterList + getSpecialAttribute('_cpFilterList')): 
    646         m = getattr(f, methodName, None) 
    647         if m: 
    648             methods.append((getattr(m, "priority", 50), m)) 
    649      
    650     methods.sort() 
    651     for priority, m in methods: 
    652         m() 
    653640 
    654641def flattener(input): 
  • branches/filterorder/cherrypy/_cputil.py

    r636 r638  
    3434import traceback 
    3535import time 
    36 import os 
    37 #import os.path 
    3836 
    3937import cherrypy 
     
    7573    _cpFilterList.""" 
    7674     
    77     # First, we look in the right-most object if this special attribute is implemented. 
    78     # If not, then we try the previous object and so on until we reach cherrypy.root 
     75    # First, we look in the right-most object if this special attribute 
     76    # is implemented. If not, then we try the previous object and so on 
     77    # until we reach cherrypy.root. 
    7978    # If it's still not there, we use the implementation from this module. 
    8079     
     
    8887                return attr 
    8988     
     89    if name == "_cpFilterList": 
     90        # Don't use the default; all consumers of _cpFilterList 
     91        # already access it directly. 
     92        return [] 
     93     
    9094    try: 
    9195        return globals()[name] 
    9296    except KeyError: 
    93         raise cherrypy.InternalError("Special attribute %s could not be found" 
    94                                      % repr(name)
     97        msg = "Special attribute %s could not be found" % repr(name) 
     98        raise cherrypy.InternalError(msg
    9599 
    96100def getSpecialAttributePath(name): 
     
    145149     
    146150    fname = cherrypy.config.get('server.logFile', '') 
    147     #logdir = os.path.dirname(fname) 
    148     #if logdir and not os.path.exists(logdir): 
    149     #    os.makedirs(logdir) 
    150151    if fname: 
    151152        f = open(fname, 'ab') 
     
    204205 
    205206 
    206 # Filter methods may optionally possess an .order attribute, a number. 
    207 # Order numbers should be between -100 and 100; 0 is the default. 
    208 # Builtin filters all have appropriate order numbers in this range. 
    209 # Note that the range of order numbers is open-ended; there's nothing 
    210 # to stop user-defined filters from using an .order of sys.maxint. 
    211 #  
    212 # Here's a loose semantic for the order numbers: 
    213 #  
    214 # -100  Must run first because it deals with "meta-information" like 
    215 #       timing, tracing, etc. 
    216 #           LogDebugInfoFilter.beforeMain 
    217 #  -80  Must run early because it rewrites the request path 
    218 #           VirtualHostFilter.onStartResource 
    219 #           BaseUrlFilter.beforeRequestBody 
    220 #           CacheFilter.beforeMain 
    221 #  -60  Must run early because it decodes the request 
    222 #           DecodingFilter.beforeMain 
    223 #  -40  Must run early because it parses/interprets the request 
    224 #  -20  Must run early because it redirects the request 
    225 #           SessionAuthenticateFilter.beforeMain 
    226 #           StaticFilter.beforeMain 
    227 #    0  Order is not important; this is the default when undefined 
    228 #           SessionFilter.beforeRequestBody 
    229 #           SessionFilter.beforeFinalize 
    230 #           SessionFilter.afterErrorResponse 
    231 #           XmlRpcFilter.onStartResource 
    232 #           XmlRpcFilter.beforeRequestBody 
    233 #           XmlRpcFilter.beforeFinalize 
    234 #           XmlRpcFilter.beforeErrorResponse 
    235 #   20  Must run late because it modifies the response 
    236 #   40  Must run late because it wraps the response body 
    237 #           LogDebugInfoFilter.beforeFinalize 
    238 #           NsgmlsFilter.beforeFinalize 
    239 #           TidyFilter.beforeFinalize 
    240 #   60  Must run late because it encodes the response 
    241 #           EncodingFilter.beforeFinalize 
    242 #   80  Must run late because it replaces/caches the response 
    243 #           GzipFilter.beforeFinalize 
    244 #           CacheFilter.onEndResource 
    245 #  100  Must run last because it deals with "meta-information" like timing, 
    246 #       tracing, etc. 
    247  
    248 _cpFilterList = [] 
    249  
    250 # Filters that are always included 
    251 from cherrypy.lib.filter import baseurlfilter, cachefilter, \ 
    252     decodingfilter, encodingfilter, gzipfilter, logdebuginfofilter, \ 
    253     staticfilter, nsgmlsfilter, tidyfilter, \ 
    254     virtualhostfilter, xmlrpcfilter, sessionauthenticatefilter, \ 
    255     sessionfilter 
    256  
    257 # this contains the classes for each filter type 
    258 # we do not store the instances here because the test 
    259 # suite must reinitialize the filters without restarting 
    260 # the server 
    261 _cpDefaultFilterClasses = { 
    262     'BaseUrlFilter'      : baseurlfilter.BaseUrlFilter, 
    263     'CacheFilter'        : cachefilter.CacheFilter, 
    264     'DecodingFilter'     : decodingfilter.DecodingFilter, 
    265     'EncodingFilter'     : encodingfilter.EncodingFilter, 
    266     'GzipFilter'         : gzipfilter.GzipFilter, 
    267     'LogDebugInfoFilter' : logdebuginfofilter.LogDebugInfoFilter, 
    268     'NsgmlsFilter'       : nsgmlsfilter.NsgmlsFilter, 
    269     'SessionAuthenticateFilter': 
    270                            sessionauthenticatefilter.SessionAuthenticateFilter, 
    271     'SessionFilter'      : sessionfilter.SessionFilter, 
    272     'StaticFilter'       : staticfilter.StaticFilter, 
    273     'TidyFilter'         : tidyfilter.TidyFilter, 
    274     'VirtualHostFilter'  : virtualhostfilter.VirtualHostFilter, 
    275     'XmlRpcFilter'       : xmlrpcfilter.XmlRpcFilter, 
    276 } 
    277  
    278 # this is where the actual filter instances are first stored 
    279 _cpDefaultFilterInstances = {} 
    280  
    281 # These are in order for a reason! 
    282 # They must be strings matching keys in _cpDefaultFilterClasses 
    283 __cpDefaultInputFilters = [ 
    284     'CacheFilter', 
    285     'LogDebugInfoFilter', 
    286     'VirtualHostFilter', 
    287     'BaseUrlFilter', 
    288     'DecodingFilter', 
    289     'SessionFilter', 
    290     'SessionAuthenticateFilter', 
    291     'StaticFilter', 
    292     'NsgmlsFilter', 
    293     'TidyFilter', 
    294     'XmlRpcFilter', 
    295 ] 
    296  
    297 __cpDefaultOutputFilters = [ 
    298     'XmlRpcFilter', 
    299     'EncodingFilter', 
    300     'TidyFilter', 
    301     'NsgmlsFilter', 
    302     'LogDebugInfoFilter', 
    303     'GzipFilter', 
    304     'SessionFilter', 
    305     'CacheFilter', 
    306 ] 
    307  
    308 # initilize the default filters 
    309 def _cpInitDefaultFilters(): 
    310     global _cpDefaultInputFilterList, _cpDefaultOutputFilterList 
    311     global _cpDefaultFilterInstances 
    312     _cpDefaultInputFilterList  = [] 
    313     _cpDefaultOutputFilterList = [] 
    314     _cpDefaultFilterInstances = {} 
    315      
    316     for filterName in __cpDefaultInputFilters: 
    317         filterClass = _cpDefaultFilterClasses[filterName] 
    318         filterInstance = _cpDefaultFilterInstances[filterName] = filterClass() 
    319         _cpDefaultInputFilterList.append(filterInstance) 
    320      
    321     for filterName in __cpDefaultOutputFilters: 
    322         filterClass = _cpDefaultFilterClasses[filterName] 
    323         filterInstance = _cpDefaultFilterInstances.setdefault(filterName, filterClass()) 
    324         _cpDefaultOutputFilterList.append(filterInstance) 
    325  
    326 def _cpInitUserDefinedFilters(): 
    327     filtersRoot = cherrypy.config.get('server.filtersRoot', []) 
    328     inputFiltersDict = cherrypy.config.get('server.inputFiltersDict', {}) 
    329     outputFiltersDict = cherrypy.config.get('server.outputFiltersDict', {}) 
    330      
    331     if len(filtersRoot) == 0: 
    332         return 
    333  
    334     sys.path.extend(filtersRoot) 
    335          
    336     for filterName, filterClassname in inputFiltersDict.items(): 
    337         filterModule = __import__(filterName, globals(),  locals(), []) 
    338         filterClass = getattr(filterModule, filterClassname, None) 
    339         filterInstance = filterClass() 
    340         _cpDefaultInputFilterList.append(filterInstance) 
    341  
    342     for filterName, filterClassname in outputFiltersDict.items(): 
    343         filterModule = __import__(filterName, globals(),  locals(), []) 
    344         filterClass = getattr(filterModule, filterClassname, None) 
    345         filterInstance = filterClass() 
    346         _cpDefaultOutputFilterList.append(filterInstance) 
    347  
    348     # Avoid pollution of the system path 
    349     for path in filtersRoot: 
    350         sys.path.remove(path) 
    351  
    352  
    353207# public domain "unrepr" implementation, found on the web and then improved. 
    354208import compiler 
     
    361215 
    362216class UnknownType(Exception): 
    363      
    364     # initialize the built-in filters  
    365     for n in xrange(len(_cpDefaultInputFilterList)): 
    366         try: 
    367             _cpDefaultInputFilterList[n] = _cpDefaultInputFilterList[n]() 
    368         except: 
    369             pass 
    370      
    371     for n in xrange(len(_cpDefaultOutputFilterList)): 
    372         try: 
    373             _cpDefaultOutputFilterList[n] = _cpDefaultOutputFilterList[n]() 
    374         except: 
    375             pass 
     217    pass 
    376218 
    377219 
  • branches/filterorder/cherrypy/server.py

    r616 r638  
    3838 
    3939import cherrypy 
    40 from cherrypy import _cphttptools 
     40from cherrypy import _cphttptools, _cpfilter 
    4141from cherrypy.lib import autoreload, profiler 
    4242 
     
    6767            - create response and request objects 
    6868            - starts a server 
    69             - initilizes built in filters 
     69            - initializes built in filters 
    7070    """ 
    7171     
     
    109109        cherrypy.profiler = None 
    110110 
    111     # Initilize the built in filters 
    112     cherrypy._cputil._cpInitDefaultFilters() 
    113     cherrypy._cputil._cpInitUserDefinedFilters() 
     111    # Initialize the built in filters 
     112    _cpfilter._cpInitBuiltinFilters() 
     113    _cpfilter._cpInitUserDefinedFilters() 
    114114     
    115115    if initOnly: 
  • branches/filterorder/cherrypy/test/helper.py

    r587 r638  
    3535 
    3636import cherrypy 
     37from cherrypy import _cpfilter 
     38 
    3739import webtest 
    3840import types 
     
    152154        else: 
    153155            cherrypy.config.update(conf.copy()) 
    154         cherrypy._cputil._cpInitDefaultFilters() 
     156        _cpfilter._cpInitBuiltinFilters() 
    155157         
    156158        suite = CPTestLoader.loadTestsFromName(testmod) 
     
    171173    startServer(server) 
    172174    try: 
    173         cherrypy._cputil._cpInitDefaultFilters() 
     175        _cpfilter._cpInitBuiltinFilters() 
    174176        webtest.main() 
    175177    finally: 
  • branches/filterorder/cherrypy/test/test_core.py

    r626 r638  
    642642        self.getPage("/maxrequestsize/index") 
    643643        self.assertBody("OK") 
    644         cherrypy.config.update({'server.maxRequestHeaderSize': 10}) 
    645         self.getPage("/maxrequestsize/index") 
    646         self.assertStatus("413 Request Entity Too Large") 
    647         self.assertBody("Request Entity Too Large") 
    648         cherrypy.config.update({'server.maxRequestHeaderSize': 0}) 
    649  
     644         
     645        if cherrypy._httpserver.__class__.__name__ == "WSGIServer": 
     646            cherrypy.config.update({'server.maxRequestHeaderSize': 10}) 
     647            self.getPage("/maxrequestsize/index") 
     648            self.assertStatus("413 Request Entity Too Large") 
     649            self.assertBody("Request Entity Too Large") 
     650            cherrypy.config.update({'server.maxRequestHeaderSize': 0}) 
     651         
    650652        # Test upload 
    651653        h = [("Content-type", "multipart/form-data; boundary=x"), 
     
    660662        self.getPage('/maxrequestsize/upload', h, "POST", b) 
    661663        self.assertBody('Size: 5') 
    662         cherrypy.config.update({ 
    663             '/maxrequestsize': {'server.maxRequestBodySize': 3}}) 
    664         self.getPage('/maxrequestsize/upload', h, "POST", b) 
    665         self.assertStatus("413 Request Entity Too Large") 
    666         self.assertInBody("Request Entity Too Large") 
     664         
     665        if cherrypy._httpserver.__class__.__name__ == "WSGIServer": 
     666            cherrypy.config.update({ 
     667                '/maxrequestsize': {'server.maxRequestBodySize': 3}}) 
     668            self.getPage('/maxrequestsize/upload', h, "POST", b) 
     669            self.assertStatus("413 Request Entity Too Large") 
     670            self.assertInBody("Request Entity Too Large") 
    667671 
    668672if __name__ == '__main__': 

Hosted by WebFaction

Log in as guest/cpguest to create tickets