Robert Brewer  committed 936abfe

Fix for #490 (InternalRedirect should auto-detect params). Removed the "params" arg from InternalRedirect; set cherrypy.request.params directly (before raising InternalRedirect) instead.

  • Participants
  • Parent commits 60808c9
  • Branches cherrypy

Comments (0)

Files changed (3)

 import cgi
 import sys
 import traceback
-import urllib
 import urlparse
 from cherrypy.lib import httptools
 class InternalRedirect(Exception):
     """Exception raised when processing should be handled by a different path.
-    If you supply 'params', it will be used to re-populate params.
-    If 'params' is a dict, it will be used directly.
-    If 'params' is a string, it will be converted to a dict using cgi.parse_qs.
-    If you omit 'params', the params from the original request will
-    remain in effect, including any POST parameters.
+    If you supply a query string, it will be replace request.params.
+    If you omit the query string, the params from the original request will
+    remain in effect.
-    def __init__(self, path, params=None):
+    def __init__(self, path):
         import cherrypy
         request = cherrypy.request
+        if "?" in path:
+            # Pop any params included in the path
+            path, pm = path.split("?", 1)
+            request.query_string = pm
+            request.params = httptools.parseQueryString(pm)
         # Note that urljoin will "do the right thing" whether url is:
         #  1. a URL relative to root (e.g. "/dummy")
         #  2. a URL relative to the current path
         # error can have access to it.
         self.path = path
-        if params is not None:
-            if isinstance(params, basestring):
-                request.query_string = params
-                pm = cgi.parse_qs(params, keep_blank_values=True)
-                for key, val in pm.items():
-                    if len(val) == 1:
-                        pm[key] = val[0]
-                request.params = pm
-            else:
-                request.query_string = urllib.urlencode(params)
-                request.params = params.copy()
-        Exception.__init__(self, path, params)
+        Exception.__init__(self, path)


         When run() is done, the returned object should have 3 attributes:
           status, e.g. "200 OK"
-          headers, a list of (name, value) tuples
+          header_list, a list of (name, value) tuples
           body, an iterable yielding strings
         Consumer code (HTTP servers) should then access these response

File test/

         def petshop(self, user_id):
             if user_id == "parrot":
                 # Trade it for a slug when redirecting
-                raise cherrypy.InternalRedirect('/image/getImagesByUser',
-                                               "user_id=slug")
+                raise cherrypy.InternalRedirect('/image/getImagesByUser?user_id=slug')
             elif user_id == "terrier":
                 # Trade it for a fish when redirecting
-                raise cherrypy.InternalRedirect('/image/getImagesByUser',
-                                               {"user_id": "fish"})
+                cherrypy.request.params = {"user_id": "fish"}
+                raise cherrypy.InternalRedirect('/image/getImagesByUser')
                 raise cherrypy.InternalRedirect('/image/getImagesByUser')