Changeset 301
- Timestamp:
- 06/13/05 02:45:05
- Files:
-
- branches/ooconf/cherrypy/_cpconfig.py (modified) (7 diffs)
- branches/ooconf/cherrypy/_cpdefaults.py (modified) (3 diffs)
- branches/ooconf/cherrypy/_cphttptools.py (modified) (6 diffs)
- branches/ooconf/cherrypy/_cputil.py (modified) (5 diffs)
- branches/ooconf/cherrypy/lib/filter/baseurlfilter.py (modified) (1 diff)
- branches/ooconf/cherrypy/lib/filter/staticfilter.py (deleted)
- branches/ooconf/cherrypy/lib/filter/virtualhostfilter.py (modified) (1 diff)
- branches/ooconf/cherrypy/test/test.py (modified) (2 diffs)
- branches/ooconf/cherrypy/test/test_baseurl_filter.py (modified) (1 diff)
- branches/ooconf/cherrypy/test/test_core.py (modified) (3 diffs)
- branches/ooconf/cherrypy/test/test_decodingencoding_filter.py (modified) (1 diff)
- branches/ooconf/cherrypy/test/test_gzip_filter.py (modified) (1 diff)
- branches/ooconf/cherrypy/test/test_logdebuginfo_filter.py (modified) (2 diffs)
- branches/ooconf/cherrypy/test/test_objectmapping.py (modified) (1 diff)
- branches/ooconf/cherrypy/test/test_tutorials.py (modified) (3 diffs)
- branches/ooconf/cherrypy/test/test_virtualhost_filter.py (modified) (1 diff)
- branches/ooconf/cherrypy/tutorial/tut08_sessions.py (modified) (1 diff)
- branches/ooconf/cherrypy/tutorial/tut10_sessionfilter.conf (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/ooconf/cherrypy/_cpconfig.py
r293 r301 1 import os.path 2 import ConfigParser 3 4 cpg = None # delayed import 1 5 import _cputil, cperror 2 import ConfigParser3 6 from lib import autoreload 4 7 5 cpg = None # delayed import6 8 7 9 defaultGlobal = { … … 24 26 'session.storageFileDir': '', 25 27 26 'sessionFilter.on': True,28 'sessionFilter.on': False, 27 29 'sessionFilter.timeout': 60, 28 30 'sessionFilter.cleanUpDelay': 60, … … 34 36 } 35 37 36 def reset(): 37 configMap.clear() 38 configMap["/"] = defaultGlobal.copy() 38 # This settings dict holds the settings metadata for all cpg objects. 39 # Keys are objects in the cpg.root tree, and values are dicts. 40 settings = {} 39 41 40 configMap = {}41 reset()42 42 43 43 def update(updateMap=None, file=None): 44 44 if updateMap: 45 for section, valueMap in updateMap.items(): 46 s = configMap.get(section) 47 if not s: 48 configMap[section] = valueMap 49 else: 50 s.update(valueMap) 45 _update(updateMap) 51 46 if file: 52 47 if file not in autoreload.reloadFiles: 53 48 autoreload.reloadFiles.append(file) 54 _ load(file)49 _update(config_from_file(file)) 55 50 56 def get(key, defaultValue=None, returnSection=False, startPath = None): 57 # Look, ma, no Python function calls! Uber-fast. 58 # start path lest you overload the starting search path (needed by getAll) 51 def _update(updateMap): 52 global cpg 53 if not cpg: 54 import cpg 55 import _cphttptools 59 56 57 for section, valueMap in updateMap.iteritems(): 58 if section == 'global': 59 if cpg not in settings: 60 settings[cpg] = defaultGlobal.copy() 61 settings[cpg].update(valueMap) 62 else: 63 try: 64 obj, v = _cphttptools.mapPathToObject(section) 65 except cperror.NotFound: 66 continue 67 settings.setdefault(obj, {}).update(valueMap) 68 69 70 def get(key, defaultValue=None): 60 71 global cpg 61 72 if not cpg: 62 73 import cpg 63 74 64 if startPath: 65 path = startPath 66 else: 67 try: 68 path = cpg.request.path 69 except AttributeError: 70 path = "/" 71 72 while True: 73 if path == "": 74 path = "/" 75 try: 76 result = configMap[path][key] 77 except KeyError: 78 if path != "/": 79 i = path.rfind("/") 80 if i < 0: 81 result = defaultValue 82 else: 83 path = path[:i] 84 continue 85 else: 86 result = defaultValue 87 break 88 89 if returnSection: 90 return path 91 else: 92 return result 93 94 import os.path 75 try: 76 s = cpg.request.settings 77 except AttributeError: 78 # Config is being retrieved outside of a request. 79 # Return config for cpg ("global"). 80 if cpg not in settings: 81 settings[cpg] = defaultGlobal.copy() 82 s = settings[cpg] 83 return s.get(key, defaultValue) 95 84 96 85 def getAll(key): … … 116 105 return result 117 106 107 108 def collapsedSettings(objectTrail): 109 """Collapse all 'settings' attributes in objectTrail into a single dict.""" 110 if cpg not in settings: 111 settings[cpg] = defaultGlobal.copy() 112 result = settings[cpg].copy() 113 for obj in objectTrail: 114 s = settings.setdefault(obj, {}) 115 if s: 116 result.update(s) 117 return result 118 119 118 120 class CaseSensitiveConfigParser(ConfigParser.ConfigParser): 119 121 """ Sub-class of ConfigParser that keeps the case of options and … … 134 136 fp.close() 135 137 136 def _load(configFile = None):138 def config_from_file(configFile = None): 137 139 """ Convert an INI file to a dictionary """ 138 140 _cpLogMessage = _cputil.getSpecialAttribute('_cpLogMessage') … … 148 150 149 151 # Load INI file into cpg.configMap 152 configMap = {} 150 153 for section in configParser.sections(): 151 154 if section not in configMap: … … 160 163 raise cperror.WrongConfigValue, msg 161 164 configMap[section][option] = value 165 return configMap 162 166 163 167 def outputConfigMap(): branches/ooconf/cherrypy/_cpdefaults.py
r275 r301 165 165 pass 166 166 167 167 168 _cpFilterList = [] 168 169 … … 170 171 from cherrypy.lib.filter import baseurlfilter, cachefilter, \ 171 172 decodingfilter, encodingfilter, gzipfilter, logdebuginfofilter, \ 172 staticfilter, nsgmlsfilter, tidyfilter, \ 173 virtualhostfilter, xmlrpcfilter 173 nsgmlsfilter, tidyfilter, virtualhostfilter, xmlrpcfilter 174 174 175 175 from cherrypy.lib.filter.sessionfilter import sessionfilter … … 191 191 decodingfilter.DecodingFilter(), 192 192 _sessionfilter, 193 staticfilter.StaticFilter(),194 193 _nsgmlsfilter, 195 194 _tidyfilter, branches/ooconf/cherrypy/_cphttptools.py
r294 r301 103 103 self.processRequestHeaders() 104 104 105 main, virtualPathList = self.findMain() 106 105 107 applyFilters('beforeRequestBody') 106 108 if cpg.request.processRequestBody: … … 109 111 applyFilters('beforeMain') 110 112 if cpg.response.body is None: 111 main() 113 body = main(*(virtualPathList + cpg.request.paramList), 114 **(cpg.request.paramMap)) 115 cpg.response.body = iterable(body) 112 116 113 117 applyFilters('beforeFinalize') … … 172 176 cpg.request.originalParamMap = cpg.request.paramMap 173 177 cpg.request.originalParamList = cpg.request.paramList 178 179 def findMain(self): 180 path = cpg.request.path 181 # Remove leading and trailing slash 182 path = path.strip("/") 183 # Replace quoted chars (eg %20) from url 184 path = urllib.unquote(path) 185 186 try: 187 path = cpg.request.objectPath or cpg.request.path 188 return mapPathToObject(path) 189 except cperror.IndexRedirect, inst: 190 # For an IndexRedirect, we don't go through the regular 191 # mechanism: we return the redirect immediately 192 newUrl = urlparse.urljoin(cpg.request.base, inst.args[0]) 193 cpg.response.status = '302 Found' 194 cpg.response.headerMap['Location'] = newUrl 195 cpg.response.body = [] 196 finalize() 197 raise cperror.RequestHandled 174 198 175 199 def processRequestBody(self): … … 269 293 270 294 # Response functions 271 272 def main():273 """Obtain and set cpg.response.body."""274 path = cpg.request.path275 # Remove leading and trailing slash276 path = path.strip("/")277 # Replace quoted chars (eg %20) from url278 path = urllib.unquote(path)279 280 try:281 path = cpg.request.objectPath or cpg.request.path282 func, virtualPathList = mapPathToObject(path)283 body = func(*(virtualPathList + cpg.request.paramList),284 **(cpg.request.paramMap))285 cpg.response.body = iterable(body)286 except cperror.IndexRedirect, inst:287 # For an IndexRedirect, we don't go through the regular288 # mechanism: we return the redirect immediately289 newUrl = urlparse.urljoin(cpg.request.base, inst.args[0])290 cpg.response.status = '302 Found'291 cpg.response.headerMap['Location'] = newUrl292 cpg.response.body = []293 295 294 296 def iterable(body): … … 413 415 # Also, a method has to have ".exposed = True" in order to be exposed 414 416 417 originalPath = path 415 418 # Remove leading and trailing slash 416 419 path = path.strip("/") … … 465 468 466 469 if found: 467 if rpos == 0: 468 # If the original path had no trailing slash, do a redirect 469 if cpg.request.path[-1] != '/': 470 newUrl = cpg.request.path + '/' 471 if cpg.request.queryString: 472 newUrl += cpg.request.queryString 473 raise cperror.IndexRedirect(newUrl) 474 475 # Remove "root" item and join objectPathList to get objectPath 476 cpg.request.objectPath = '/' + '/'.join(objectPathList[1:]) 470 if hasattr(cpg, "request"): 471 if rpos == 0: 472 # If the original path had no trailing slash, do a redirect 473 if originalPath[-1] != '/': 474 newUrl = originalPath + '/' 475 if cpg.request.queryString: 476 newUrl += cpg.request.queryString 477 raise cperror.IndexRedirect(newUrl) 478 479 # Remove "root" item and join objectPathList to get objectPath 480 cpg.request.objectPath = '/' + '/'.join(objectPathList[1:]) 481 482 # Form the settings map for this thread/request 483 cpg.request.settings = cpg.config.collapsedSettings(objectTrail) 484 else: 485 # We are probably being called from _cpconfig.update. 486 if rpos == 0: 487 # The method found was an index method. We don't want that; 488 # we want to return the containing object. 489 candidate = objectTrail[-2] 490 477 491 return candidate, virtualPathList 478 492 else: branches/ooconf/cherrypy/_cputil.py
r277 r301 33 33 34 34 import time, thread, cpg, _cpdefaults, cperror 35 import os, sys, mimetypes 35 36 36 37 try: import zlib 37 38 except ImportError: pass 39 38 40 39 41 class EmptyClass: … … 41 43 pass 42 44 45 46 class StaticContent(object): 47 48 def default(self, *path): 49 filename = cpg.config.get('staticfile') 50 if not filename: 51 staticDir = cpg.config.get('staticdir') 52 filename = os.path.join(staticDir, *path) 53 54 # If filename is relative, make absolute using cpg.root's module. 55 if not os.path.isabs(filename): 56 root = os.path.dirname(sys.modules[cpg.root.__module__].__file__) 57 filename = os.path.join(root, filename) 58 59 # Serve filename 60 try: 61 stat = os.stat(filename) 62 except OSError: 63 raise cperror.NotFound(cpg.request.path) 64 65 modifTime = stat.st_mtime 66 strModifTime = time.strftime("%a, %d %b %Y %H:%M:%S GMT", 67 time.gmtime(modifTime)) 68 if cpg.request.headerMap.has_key('If-Modified-Since'): 69 # Check if if-modified-since date is the same as strModifTime 70 if cpg.request.headerMap['If-Modified-Since'] == strModifTime: 71 cpg.response.status = "304 Not Modified" 72 return 73 cpg.response.headerMap['Last-Modified'] = strModifTime 74 75 # Set Content-Length and use an iterable (file object) 76 # this way CP won't load the whole file in memory 77 cpg.response.headerMap['Content-Length'] = stat[6] 78 body = open(filename, 'rb') 79 80 # Set content-type based on filename extension 81 i = filename.rfind('.') 82 if i != -1: 83 ext = filename[i:] 84 else: 85 ext = "" 86 contentType = mimetypes.types_map.get(ext, "text/plain") 87 cpg.response.headerMap['Content-Type'] = contentType 88 return body 89 90 43 91 def getSpecialAttribute(name): 44 """ Return the special function"""45 92 """ Return the special attribute """ 93 46 94 # First, we look in the right-most object if this special function is implemented. 47 95 # If not, then we try the previous object and so on until we reach cpg.root … … 49 97 # "_cpdefaults.py" module 50 98 51 52 99 moduleList = [_cpdefaults] 53 100 root = getattr(cpg, 'root', None) … … 61 108 if path: 62 109 pathList = path.split('/')[1:] 63 110 64 111 obj = cpg.root 65 112 previousObj = None … … 72 119 except AttributeError: 73 120 break 74 121 75 122 moduleList.reverse() 76 123 for module in moduleList: branches/ooconf/cherrypy/lib/filter/baseurlfilter.py
r230 r301 49 49 50 50 if newBaseUrl.find("://") == -1: 51 # add http:// or https:// if needed 51 # add http:// or https:// if needed 52 52 newBaseUrl = cpg.request.base[:cpg.request.base.find("://") + 3] + newBaseUrl 53 53 branches/ooconf/cherrypy/lib/filter/virtualhostfilter.py
r293 r301 46 46 47 47 prefix = cpg.config.get('virtualHostFilter.prefix', '/') 48 49 # mapPath will set cpg.request.objectPath 50 _cphttptools.mapPathToObject(prefix + cpg.request.path) 51 52 #raise basefilter.InternalRedirect 48 cpg.request.path = prefix + cpg.request.path branches/ooconf/cherrypy/test/test.py
r293 r301 163 163 'server.logToScreen': False, 164 164 'server.environment': "production", 165 ##'profiling.on': True,165 'profiling.on': True, 166 166 } 167 167 … … 173 173 print "Running tests:", name 174 174 175 cpg.config.update({' /': server_conf.copy()})175 cpg.config.update({'global': server_conf.copy()}) 176 176 helper.startServer(server) 177 177 for testmod in testList: 178 178 # Must run each module in a separate suite, 179 179 # because each module uses/overwrites cpg globals. 180 cpg.config.reset() 181 cpg.config.update({'/': server_conf.copy()}) 180 cpg.config.update({'global': server_conf.copy()}) 182 181 suite = CPTestLoader.loadTestsFromName(testmod) 183 182 CPTestRunner(verbosity=2).run(suite) branches/ooconf/cherrypy/test/test_baseurl_filter.py
r267 r301 37 37 cpg.root = Root() 38 38 cpg.config.update({ 39 'global': { 40 'server.environment': 'production', 41 'server.logToScreen': False, 42 }, 39 43 '/': { 40 'server.environment': 'production',41 44 'baseUrlFilter.on': True, 42 45 'baseUrlFilter.baseUrl': 'http://www.mydomain.com' branches/ooconf/cherrypy/test/test_core.py
r267 r301 121 121 122 122 123 def dummy(): return 124 125 cpg.root.foo = dummy 126 cpg.root.foo.exposed = True 127 cpg.root.foo.bar = lambda: [] 128 cpg.root.foo.bar.exposed = True 129 123 130 cpg.config.update({ 124 ' /': {131 'global': { 125 132 'server.logToScreen': False, 126 133 'server.environment': 'production', 134 }, 135 '/': { 127 136 'foo': 'this', 128 137 'bar': 'that', … … 145 154 146 155 def testConfig(self): 147 from cherrypy import _cpconfig148 156 tests = [ 149 157 ('/', 'nex', None ), … … 158 166 ] 159 167 for path, key, expected in tests: 160 cpg.request.path = path161 result = _cpconfig.get(key, None)168 helper.request(path) 169 result = cpg.config.get(key, None) 162 170 self.assertEqual(result, expected) 163 171 branches/ooconf/cherrypy/test/test_decodingencoding_filter.py
r267 r301 38 38 cpg.root = Root() 39 39 cpg.config.update({ 40 ' /': {40 'global': { 41 41 'server.logToScreen': False, 42 42 'server.environment': 'production', 43 }, 44 '/': { 43 45 'encodingFilter.on': True, 44 46 'decodingFilter.on': True branches/ooconf/cherrypy/test/test_gzip_filter.py
r267 r301 37 37 cpg.root = Root() 38 38 cpg.config.update({ 39 ' /': {39 'global': { 40 40 'server.logToScreen': False, 41 41 'server.environment': 'production', 42 }, 43 '/': { 42 44 'gzipFilter.on': True, 43 45 } branches/ooconf/cherrypy/test/test_logdebuginfo_filter.py
r299 r301 36 36 cpg.root = Root() 37 37 cpg.config.update({ 38 ' /': {38 'global': { 39 39 'session.storageType': 'ram', 40 40 'session.timeout': 60, … … 45 45 'server.logToScreen': False, 46 46 'server.environment': 'production', 47 }, 48 '/': { 47 49 'logDebugInfoFilter.on': True, 48 50 } branches/ooconf/cherrypy/test/test_objectmapping.py
r293 r301 94 94 cpg.root.dir1.dir2.dir3.dir4 = Dir4() 95 95 cpg.config.update({ 96 'global': { 97 'server.logToScreen': False, 98 }, 96 99 '/': { 97 'server.logToScreen': False,98 100 'logDebugInfoFilter.on': False, 99 101 } branches/ooconf/cherrypy/test/test_tutorials.py
r293 r301 42 42 def load_tut_module(tutorialName): 43 43 """Import or reload tutorial module as needed.""" 44 cpg.config. reset()44 cpg.config.settings.clear() 45 45 cpg.config.update({'/': server_conf.copy()}) 46 46 … … 144 144 def test08Sessions(self): 145 145 load_tut_module("tut08_sessions") 146 cpg.config.update({"/": {"sessionFilter.on": True}}) 146 147 147 148 helper.request('/') … … 168 169 def test10SessionFilter(self): 169 170 load_tut_module("tut10_sessionfilter") 171 cpg.config.update({"/": {"sessionFilter.on": True}}) 170 172 171 173 helper.request('/') branches/ooconf/cherrypy/test/test_virtualhost_filter.py
r267 r301 36 36 cpg.root = Root() 37 37 cpg.config.update({ 38 ' /': {38 'global': { 39 39 'server.logToScreen': False, 40 40 'server.environment': 'production', 41 }, 42 '/': { 41 43 'virtualHostFilter.on': True, 42 44 'virtualHostFilter.prefix': '/index2', branches/ooconf/cherrypy/tutorial/tut08_sessions.py
r267 r301 29 29 30 30 cpg.root = HitCounter() 31 31 cpg.config.update({'/': {'sessionFilter.on': True}}) 32 32 33 33 if __name__ == '__main__': branches/ooconf/cherrypy/tutorial/tut10_sessionfilter.conf
r299 r301 4 4 server.environment = "production" 5 5 6 sessionFilter.on=True 6 7 # by default we get 7 # sessionFilter.on=True8 8 # sessionFilter.new='sessionMap' 9 9 # sessionMap.storageType='ram'

