1. cherrypy
  2. CherryPy

Commits

Robert Brewer  committed 7b8ea0f

Improved tree.url() to include base. Also replaced request.browser_url with request.url().

  • Participants
  • Parent commits 8af1b30
  • Branches default

Comments (0)

Files changed (7)

File cherrypy/_cperror.py

View file
  • Ignore whitespace
         # 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
-        # Note that any querystring will be discarded.
+        # Note that any query string will be discarded.
         path = _urljoin(cherrypy.request.path_info, path)
         
         # Set a 'path' member attribute so that code which traps this
     
     def __init__(self, urls, status=None):
         import cherrypy
+        request = cherrypy.request
         
         if isinstance(urls, basestring):
             urls = [urls]
             #  1. a complete URL with host (e.g. "http://www.dummy.biz/test")
             #  2. a URL relative to root (e.g. "/dummy")
             #  3. a URL relative to the current path
-            # Note that any querystring in browser_url will be discarded.
-            url = _urljoin(cherrypy.request.browser_url, url)
+            # Note that any query string in cherrypy.request is discarded.
+            url = _urljoin(request.url(), url)
             abs_urls.append(url)
         self.urls = abs_urls
         

File cherrypy/_cprequest.py

View file
  • Ignore whitespace
         if request.config.get("request.redirect_on_missing_slash",
                               request.redirect_on_missing_slash):
             if pi[-1:] != '/':
-                atoms = request.browser_url.split("?", 1)
-                new_url = atoms.pop(0) + '/'
-                if atoms:
-                    new_url += "?" + atoms[0]
+                new_url = request.url(pi + '/', request.query_string)
                 raise cherrypy.HTTPRedirect(new_url)
     
     def check_extra_slash(self):
                               request.redirect_on_extra_slash):
             # If pi == '/', don't redirect to ''!
             if pi[-1:] == '/' and pi != '/':
-                atoms = request.browser_url.split("?", 1)
-                new_url = atoms.pop(0)[:-1]
-                if atoms:
-                    new_url += "?" + atoms[0]
+                new_url = request.url(pi[:-1], request.query_string)
                 raise cherrypy.HTTPRedirect(new_url)
 
 
                 tool = getattr(tools, toolname)
                 tool._setup()
     
-    def _get_browser_url(self):
-        url = self.base + self.path
-        if self.query_string:
-            url += '?' + self.query_string
-        return url
-    browser_url = property(_get_browser_url,
-                           doc="The URL as entered in a browser (read-only).")
+    def url(self, path_info="", qs=""):
+        """Create an absolute URL for the given path_info.
+        
+        If 'path_info' starts with a slash ('/'), this will return
+            (self.base + self.script_name + path_info + qs).
+        If it does not start with a slash, this returns
+            (self.base + self.script_name + self.path_info + path_info + qs).
+        """
+        if path_info == "":
+            path_info = self.path_info
+        if not path_info.startswith("/"):
+            path_info = self.path_info + "/" + path_info
+        
+        if qs:
+            qs = '?' + qs
+        return self.base + self.script_name + path_info + qs
     
     def process_body(self):
         """Convert request.rfile into request.params (or request.body)."""

File cherrypy/_cptree.py

View file
  • Ignore whitespace
 """CherryPy Application and Tree objects."""
 
+import os
 import sys
 import cherrypy
-from cherrypy import _cpconfig, _cplogging
+from cherrypy import _cpconfig, _cplogging, tools
 from cherrypy._cperror import format_exc, bare_error
 from cherrypy.lib import http
 
     def _get_script_name(self):
         if self._script_name is None:
             # None signals that the script name should be pulled from WSGI environ.
-            import cherrypy
             return cherrypy.request.wsgi_environ['SCRIPT_NAME']
         return self._script_name
     def _set_script_name(self, value):
             
             # If mounted at "", add favicon.ico
             if script_name == "" and root and not hasattr(root, "favicon_ico"):
-                import os
-                from cherrypy import tools
                 favicon = os.path.join(os.getcwd(), os.path.dirname(__file__),
                                        "favicon.ico")
                 root.favicon_ico = tools.staticfile.handler(favicon)
         
         if path is None:
             try:
-                import cherrypy
                 path = cherrypy.request.path
             except AttributeError:
                 return None
             # Move one node up the tree and try again.
             path = path[:path.rfind("/")]
     
-    def url(self, path, script_name=None):
-        """Return 'path', prefixed with script_name.
+    def url(self, path, script_name=None, base=None):
+        """Return 'path', prefixed with script_name and base.
         
         If script_name is None, cherrypy.request.path will be used
         to find a script_name.
+        
+        If base is None, cherrypy.request.base will be used. Note that
+        you can use cherrypy.tools.proxy to change this.
         """
         
         if script_name is None:
             if script_name is None:
                 return path
         
-        from cherrypy.lib import http
-        return http.urljoin(script_name, path)
+        if base is None:
+            base = cherrypy.request.base
+        
+        return base + http.urljoin(script_name, path)
     
     def __call__(self, environ, start_response):
         # If you're calling this, then you're probably setting SCRIPT_NAME

File cherrypy/lib/caching.py

View file
  • Ignore whitespace
         self.cursize = 0
     
     def _key(self):
-        return cherrypy.request.config.get("tools.caching.key",
-                                           cherrypy.request.browser_url)
+        request = cherrypy.request
+        return request.config.get("tools.caching.key", request.url(qs=request.query_string))
     key = property(_key)
     
     def expire_cache(self):

File cherrypy/lib/cptools.py

View file
  • Ignore whitespace
         if not username:
             sess[self.session_key] = username = self.anonymous()
         if not username:
-            cherrypy.response.body = self.login_screen(request.browser_url)
+            cherrypy.response.body = self.login_screen(request.url(qs=request.query_string))
             return True
         
         self.on_check(username)

File cherrypy/test/test_objectmapping.py

View file
  • Ignore whitespace
             self.getPage("/dir1/dir2/script_name")
             self.assertBody(url)
             self.getPage("/dir1/dir2/tree_url")
-            self.assertBody(prefix + "/extra")
+            self.assertBody("http://%s:%s%s/extra" %
+                            (self.HOST, self.PORT, prefix))
             
             # Test that configs don't overwrite each other from diferent apps
             self.getPage("/confvalue")

File cherrypy/test/test_proxy.py

View file
  • Ignore whitespace
 
 import cherrypy
 
+script_names = ["", "/path/to/myapp"]
 
 def setup_server():
     class Root:
             raise cherrypy.HTTPRedirect('blah')
         xhost.exposed = True
         xhost._cp_config = {'tools.proxy.local': 'X-Host'}
+        
+        def newurl(self):
+            return ("Browse to <a href='%s'>this page</a>."
+                    % cherrypy.tree.url("/this/new/page"))
+        newurl.exposed = True
     
-    cherrypy.tree.mount(Root())
+    for sn in script_names:
+        cherrypy.tree.mount(Root(), sn)
+    
     cherrypy.config.update({
         'environment': 'test_suite',
         'tools.proxy.on': True,
         # Test X-Host (lighttpd; see https://trac.lighttpd.net/trac/ticket/418)
         self.getPage("/xhost", headers=[('X-Host', 'http://www.yetanother.com')])
         self.assertHeader('Location', "http://www.yetanother.com/blah")
+        
+        # Test tree.url()
+        for sn in script_names:
+            self.getPage(sn + "/newurl")
+            self.assertBody("Browse to <a href='http://www.mydomain.com"
+                            + sn + "/this/new/page'>this page</a>.")
+            self.getPage(sn + "/newurl", headers=[('X-Forwarded-Host',
+                                                   'http://www.yetanother.com')])
+            self.assertBody("Browse to <a href='http://www.yetanother.com"
+                            + sn + "/this/new/page'>this page</a>.")
 
 
 if __name__ == '__main__':