Changeset 1369
- Timestamp:
- 09/16/06 15:08:31
- Files:
-
- trunk/cherrypy/__init__.py (modified) (1 diff)
- trunk/cherrypy/_cpconfig.py (modified) (1 diff)
- trunk/cherrypy/_cprequest.py (modified) (4 diffs)
- trunk/cherrypy/_cptools.py (modified) (1 diff)
- trunk/cherrypy/lib/cptools.py (modified) (1 diff)
- trunk/cherrypy/test/test_core.py (modified) (4 diffs)
- trunk/cherrypy/test/test_objectmapping.py (modified) (1 diff)
- trunk/cherrypy/test/test_proxy.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/__init__.py
r1368 r1369 172 172 173 173 if request.app: 174 if path == "": 175 path = request.path_info 176 if not path.startswith("/"): 177 path = _urljoin(request.path_info, path) 174 if path[:1] != "/": 175 # Append/remove trailing slash from path_info as needed 176 # (this is to support mistyped URL's without redirecting; 177 # if you want to redirect, use tools.trailing_slash). 178 pi = request.path_info 179 if request.is_index is True: 180 if pi[-1:] != '/': 181 pi = pi + '/' 182 elif request.is_index is False: 183 if pi[-1:] == '/' and pi != '/': 184 pi = pi[:-1] 185 186 if path == "": 187 path = pi 188 else: 189 path = _urljoin(pi, path) 190 178 191 if script_name is None: 179 192 script_name = request.app.script_name trunk/cherrypy/_cpconfig.py
r1336 r1369 121 121 'tools.log_tracebacks.on': True, 122 122 'tools.log_headers.on': True, 123 'tools.trailing_slash.on': True, 123 124 } 124 125 trunk/cherrypy/_cprequest.py
r1362 r1369 201 201 object_trail.insert(i+1, ("default", defhandler, conf, curpath)) 202 202 request.config = set_conf() 203 request.is_index = False 203 204 return defhandler, names[i:-1] 204 205 … … 210 211 request.config = set_conf() 211 212 if i == num_candidates: 212 # We found the extra ".index". Check that path_info213 # has a trailing slash (otherwise, do a redirect).214 self.check_missing_slash()213 # We found the extra ".index". Mark request so tools 214 # can redirect if path_info has no trailing slash. 215 request.is_index = True 215 216 else: 216 # We're not at an 'index' handler. Check that path_info 217 # had NO trailing slash (if it did, do a redirect). 218 self.check_extra_slash() 217 # We're not at an 'index' handler. Mark request so tools 218 # can redirect if path_info has NO trailing slash. 219 # Note that this also includes handlers which take 220 # positional parameters (virtual paths). 221 request.is_index = False 219 222 return candidate, names[i:-1] 220 223 … … 222 225 request.config = set_conf() 223 226 return None, [] 224 225 def check_missing_slash(self):226 """Redirect if path_info has no trailing slash (if configured)."""227 request = cherrypy.request228 pi = request.path_info229 230 # Must use config here because configure probably hasn't run yet.231 if request.config.get("request.redirect_on_missing_slash",232 request.redirect_on_missing_slash):233 if pi[-1:] != '/':234 new_url = cherrypy.url(pi + '/', request.query_string)235 raise cherrypy.HTTPRedirect(new_url)236 237 def check_extra_slash(self):238 """Redirect if path_info has trailing slash (if configured)."""239 request = cherrypy.request240 pi = request.path_info241 242 # Must use config here because configure hasn't run yet.243 if request.config.get("request.redirect_on_extra_slash",244 request.redirect_on_extra_slash):245 # If pi == '/', don't redirect to ''!246 if pi[-1:] == '/' and pi != '/':247 new_url = cherrypy.url(pi[:-1], request.query_string)248 raise cherrypy.HTTPRedirect(new_url)249 227 250 228 … … 357 335 config = None 358 336 recursive_redirect = False 359 redirect_on_extra_slash = False 360 redirect_on_missing_slash = True 337 is_index = None 361 338 362 339 hookpoints = ['on_start_resource', 'before_request_body', trunk/cherrypy/_cptools.py
r1352 r1369 319 319 default_toolbox.basicauth = Tool('on_start_resource', auth.basic_auth) 320 320 default_toolbox.digestauth = Tool('on_start_resource', auth.digest_auth) 321 321 default_toolbox.trailing_slash = Tool('before_handler', cptools.trailing_slash) 322 322 323 323 del cptools, encoding, auth, static, tidy trunk/cherrypy/lib/cptools.py
r1350 r1369 308 308 else: 309 309 raise cherrypy.HTTPRedirect(url) 310 311 def trailing_slash(missing=True, extra=False): 312 """Redirect if path_info has (missing|extra) trailing slash.""" 313 request = cherrypy.request 314 pi = request.path_info 315 316 if request.is_index is True: 317 if missing: 318 if pi[-1:] != '/': 319 new_url = cherrypy.url(pi + '/', request.query_string) 320 raise cherrypy.HTTPRedirect(new_url) 321 elif request.is_index is False: 322 if extra: 323 # If pi == '/', don't redirect to ''! 324 if pi[-1:] == '/' and pi != '/': 325 new_url = cherrypy.url(pi[:-1], request.query_string) 326 raise cherrypy.HTTPRedirect(new_url) 327 trunk/cherrypy/test/test_core.py
r1368 r1369 70 70 class URL(Test): 71 71 72 _cp_config = {'tools.trailing_slash.on': False} 73 72 74 def index(self, path_info, relative=None): 73 75 return cherrypy.url(path_info, relative=bool(relative)) … … 134 136 def by_code(self, code): 135 137 raise cherrypy.HTTPRedirect("somewhere else", code) 138 by_code._cp_config = {'tools.trailing_slash.extra': True} 136 139 137 140 def nomodify(self): … … 512 515 ignore.pop() 513 516 514 def testRedirect(self): 515 self.getPage("/redirect/") 516 self.assertBody('child') 517 self.assertStatus(200) 518 517 def testSlashes(self): 519 518 # Test that requests for index methods without a trailing slash 520 519 # get redirected to the same URI path with a trailing slash. … … 532 531 self.assertInBody("<a href='%s/'>%s/</a>" % 533 532 (self.base(), self.base())) 533 534 # Test that requests for NON-index methods WITH a trailing slash 535 # get redirected to the same URI path WITHOUT a trailing slash. 536 # Make sure GET params are preserved. 537 self.getPage("/redirect/by_code/?code=307") 538 self.assertStatus(('302 Found', '303 See Other')) 539 self.assertInBody("<a href='%s/redirect/by_code?code=307'>" 540 "%s/redirect/by_code?code=307</a>" 541 % (self.base(), self.base())) 542 543 # If the trailing_slash tool is off, CP should just continue 544 # as if the slashes were correct. But it needs some help 545 # inside cherrypy.url to form correct output. 546 self.getPage('/url?path_info=page1') 547 self.assertBody('%s/url/page1' % self.base()) 548 self.getPage('/url/leaf/?path_info=page1') 549 self.assertBody('%s/url/page1' % self.base()) 550 551 def testRedirect(self): 552 self.getPage("/redirect/") 553 self.assertBody('child') 554 self.assertStatus(200) 534 555 535 556 self.getPage("/redirect/by_code?code=300") trunk/cherrypy/test/test_objectmapping.py
r1359 r1369 65 65 return "myMethod from dir1, path_info is:" + repr(cherrypy.request.path_info) 66 66 myMethod.exposed = True 67 myMethod._cp_config = {' request.redirect_on_extra_slash': True}67 myMethod._cp_config = {'tools.trailing_slash.extra': True} 68 68 69 69 def default(self, *params): trunk/cherrypy/test/test_proxy.py
r1359 r1369 19 19 raise cherrypy.HTTPRedirect('blah') 20 20 xhost.exposed = True 21 xhost._cp_config = {'tools.proxy.local': 'X-Host'} 21 xhost._cp_config = {'tools.proxy.local': 'X-Host', 22 'tools.trailing_slash.extra': True, 23 } 22 24 23 25 def base(self): … … 92 94 "%s://%s%s%s/this/new/page" 93 95 % (self.scheme, self.HOST, port, sn)) 96 97 # Test trailing slash (see http://www.cherrypy.org/ticket/562). 98 self.getPage("/xhost/", headers=[('X-Host', 'www.yetanother.com')]) 99 self.assertHeader('Location', "%s://www.yetanother.com/xhost" 100 % self.scheme) 94 101 95 102

