Ticket #584: iredir.patch
-
_cperror.py
old new 10 10 pass 11 11 12 12 class InternalRedirect(CherryPyException): 13 """Exception raised when processing should be handled by a different path.13 """Exception raised to switch to the handler for a different URL. 14 14 15 15 If you supply a query string, it will replace request.params. 16 If you omit the query string, the params from the original request will 17 remain in effect. 16 If you omit the query string (no question mark), the params from the 17 original request will remain in effect. 18 To erase any query string parameters, write url + "?" with no params. 18 19 """ 19 20 20 21 def __init__(self, path): 21 22 import cherrypy 22 23 request = cherrypy.request 23 24 25 self.query_string = "" 24 26 if "?" in path: 25 # Pop any params included in the path 26 path, pm = path.split("?", 1) 27 request.query_string = pm 28 request.params = _http.parse_query_string(pm) 27 # Separate any params included in the path 28 path, self.query_string = path.split("?", 1) 29 29 30 30 # Note that urljoin will "do the right thing" whether url is: 31 31 # 1. a URL relative to root (e.g. "/dummy") … … 37 37 # error can have access to it. 38 38 self.path = path 39 39 40 CherryPyException.__init__(self, path )40 CherryPyException.__init__(self, path, self.query_string) 41 41 42 42 43 44 43 class HTTPRedirect(CherryPyException): 45 44 """Exception raised when the request should be redirected. 46 45 -
_cprequest.py
old new 286 286 287 287 # Loop to allow for InternalRedirect. 288 288 pi = self.path_info 289 qs = self.query_string 289 290 while True: 290 291 try: 291 292 self.respond(pi) 292 293 break 293 294 except cherrypy.InternalRedirect, ir: 294 pi = ir.path 295 if pi in self.redirections and not self.recursive_redirect:295 if (ir.path in self.redirections 296 and not self.recursive_redirect): 296 297 raise RuntimeError("InternalRedirect visited the " 297 "same URL twice: %s" % repr(pi)) 298 self.redirections.append(pi) 298 "same URL twice: %s" % repr(ir.path)) 299 300 # Add the *previous* path_info + qs to self.redirections. 301 if qs: 302 qs = "?" + qs 303 self.redirections.append(pi + qs) 304 305 pi = self.path_info = ir.path 306 qs = self.query_string = ir.query_string 307 if qs: 308 self.params = http.parse_query_string(qs) 299 309 except (KeyboardInterrupt, SystemExit): 300 310 raise 301 311 except: -
test/test_core.py
old new 160 160 def index(self): 161 161 raise cherrypy.InternalRedirect("/") 162 162 163 def relative(self ):164 raise cherrypy.InternalRedirect("cousin ")163 def relative(self, a, b): 164 raise cherrypy.InternalRedirect("cousin?t=6") 165 165 166 def cousin(self): 167 return "I am a redirected page." 166 def cousin(self, t): 167 return repr(cherrypy.request.redirections + 168 [cherrypy.url(qs=cherrypy.request.query_string)]) 168 169 169 170 def petshop(self, user_id): 170 171 if user_id == "parrot": … … 175 176 cherrypy.request.params = {"user_id": "fish"} 176 177 raise cherrypy.InternalRedirect('/image/getImagesByUser') 177 178 else: 179 # This should pass the user_id through to getImagesByUser 178 180 raise cherrypy.InternalRedirect('/image/getImagesByUser') 179 181 180 182 # We support Python 2.3, but the @-deco syntax would look like this: … … 602 604 self.assertBody('Please log in') 603 605 self.assertStatus(200) 604 606 605 # Relative path in InternalRedirect 606 self.getPage("/internalredirect/relative") 607 self.assertBody('I am a redirected page.') 607 # Relative path in InternalRedirect. 608 # Also tests request.redirections 609 self.getPage("/internalredirect/relative?a=3&b=5") 610 self.assertBody("['/internalredirect/relative?a=3&b=5', " 611 "'%s/internalredirect/cousin?t=6']" % self.base()) 608 612 self.assertStatus(200) 609 613 610 614 # InternalRedirect on error

