diff options
-rw-r--r-- | docs/index.txt | 6 | ||||
-rw-r--r-- | routes/base.py | 20 | ||||
-rw-r--r-- | tests/test_functional/test_generation.py | 8 |
3 files changed, 31 insertions, 3 deletions
diff --git a/docs/index.txt b/docs/index.txt index 4d10130..686467f 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -22,6 +22,12 @@ Buzzword Compliance: *REST*, *DRY* News ==== +Routes trunk: + +* Cached matches for requests with different values for SCRIPT_NAME + (the application root) could return bad URLs (caching the URL from + other values of SCRIPT_NAME). Fixed. + **April 10th, 2007** Routes 1.6.3: diff --git a/routes/base.py b/routes/base.py index ac00e51..aa71703 100644 --- a/routes/base.py +++ b/routes/base.py @@ -812,10 +812,21 @@ class Mapper(object): controller = kargs.get('controller', None) action = kargs.get('action', None) + + # If the URL didn't depend on the SCRIPT_NAME, we'll cache it + # keyed by just by kargs; otherwise we need to cache it with + # both SCRIPT_NAME and kargs: + cache_key = unicode(kargs).encode('utf8') + if self.environ: + cache_key_script_name = '%s:%s' % ( + self.environ.get('SCRIPT_NAME', ''), cache_key) + else: + cache_key_script_name = cache_key # Check the url cache to see if it exists, use it if it does - if unicode(kargs) in self.urlcache: - return self.urlcache[unicode(kargs)] + for key in [cache_key, cache_key_script_name]: + if key in self.urlcache: + return self.urlcache[key] actionlist = self._gendict.get(controller) or self._gendict.get('*') if not actionlist: @@ -897,8 +908,11 @@ class Mapper(object): if self.environ and self.environ.get('SCRIPT_NAME', '') != '' \ and not route.absolute: path = self.environ['SCRIPT_NAME'] + path + key = cache_key_script_name + else: + key = cache_key if self.urlcache is not None: - self.urlcache[unicode(kargs)] = str(path) + self.urlcache[key] = str(path) return str(path) else: continue diff --git a/tests/test_functional/test_generation.py b/tests/test_functional/test_generation.py index 5ecd316..9da10ea 100644 --- a/tests/test_functional/test_generation.py +++ b/tests/test_functional/test_generation.py @@ -455,6 +455,14 @@ class TestGeneration(unittest.TestCase): assert '/blog/content' == m.generate(controller='content') assert '/blog/admin/comments' == m.generate(controller='admin/comments') + m.environ = dict(SCRIPT_NAME='/notblog') + + assert '/notblog/content/view' == m.generate(controller='content', action='view') + assert '/notblog/content' == m.generate(controller='content') + assert '/notblog/content' == m.generate(controller='content') + assert '/notblog/admin/comments' == m.generate(controller='admin/comments') + + def test_url_with_environ_and_absolute(self): m = Mapper() m.environ = dict(SCRIPT_NAME='/blog') |