Changeset 1368
- Timestamp:
- 09/16/06 12:33:20
- Files:
-
- trunk/cherrypy/__init__.py (modified) (6 diffs)
- trunk/cherrypy/test/test_core.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/__init__.py
r1365 r1368 5 5 import os as _os 6 6 _localdir = _os.path.dirname(__file__) 7 from urlparse import urljoin as _urljoin 7 8 8 9 from cherrypy._cperror import HTTPError, HTTPRedirect, InternalRedirect, NotFound, CherryPyException … … 150 151 return expose_ 151 152 152 def url(path="", qs="", script_name=None, base=None ):153 def url(path="", qs="", script_name=None, base=None, relative=False): 153 154 """Create an absolute URL for the given path. 154 155 … … 161 162 to find a script_name, if available. 162 163 163 If base is None, cherrypy.request.base will be used if available.164 If base is None, cherrypy.request.base will be used (if available). 164 165 Note that you can use cherrypy.tools.proxy to change this. 165 166 … … 174 175 path = request.path_info 175 176 if not path.startswith("/"): 176 path = request.path_info + "/" + path177 path = _urljoin(request.path_info, path) 177 178 if script_name is None: 178 179 script_name = request.app.script_name … … 180 181 base = request.base 181 182 182 returnbase + script_name + path + qs183 newurl = base + script_name + path + qs 183 184 else: 184 185 # No request.app (we're being called outside a request). … … 206 207 base = "%s://%s" % (scheme, host) 207 208 path = (script_name or "") + path 208 return base + path + qs 209 newurl = base + path + qs 210 211 if './' in newurl: 212 # Normalize the URL by removing ./ and ../ 213 atoms = [] 214 for atom in newurl.split('/'): 215 if atom == '.': 216 pass 217 elif atom == '..': 218 atoms.pop() 219 else: 220 atoms.append(atom) 221 newurl = '/'.join(atoms) 222 223 if relative: 224 old = url().split('/')[:-1] 225 new = newurl.split('/') 226 while old and new: 227 a, b = old[0], new[0] 228 if a != b: 229 break 230 old.pop(0) 231 new.pop(0) 232 new = (['..'] * len(old)) + new 233 newurl = '/'.join(new) 234 235 return newurl 236 209 237 210 238 # Set up config last so it can wrap other top-level objects trunk/cherrypy/test/test_core.py
r1364 r1368 52 52 53 53 root = Root() 54 55 54 55 56 56 class TestType(type): 57 57 """Metaclass which automatically exposes all functions in each subclass, … … 66 66 class Test(object): 67 67 __metaclass__ = TestType 68 69 68 69 70 class URL(Test): 71 72 def index(self, path_info, relative=None): 73 return cherrypy.url(path_info, relative=bool(relative)) 74 75 def leaf(self, path_info, relative=None): 76 return cherrypy.url(path_info, relative=bool(relative)) 77 78 70 79 class Params(Test): 71 80 … … 941 950 self.assertHeader('Content-Type', 'text/plain') 942 951 self.getPage('/defct/html') 952 953 def test_cherrypy_url(self): 954 # Input relative to current 955 self.getPage('/url/leaf?path_info=page1') 956 self.assertBody('%s/url/page1' % self.base()) 957 self.getPage('/url/?path_info=page1') 958 self.assertBody('%s/url/page1' % self.base()) 959 960 # Input is 'absolute'; that is, relative to script_name 961 self.getPage('/url/leaf?path_info=/page1') 962 self.assertBody('%s/page1' % self.base()) 963 self.getPage('/url/?path_info=/page1') 964 self.assertBody('%s/page1' % self.base()) 965 966 # Single dots 967 self.getPage('/url/leaf?path_info=./page1') 968 self.assertBody('%s/url/page1' % self.base()) 969 self.getPage('/url/leaf?path_info=other/./page1') 970 self.assertBody('%s/url/other/page1' % self.base()) 971 self.getPage('/url/?path_info=/other/./page1') 972 self.assertBody('%s/other/page1' % self.base()) 973 974 # Double dots 975 self.getPage('/url/leaf?path_info=../page1') 976 self.assertBody('%s/page1' % self.base()) 977 self.getPage('/url/leaf?path_info=other/../page1') 978 self.assertBody('%s/url/page1' % self.base()) 979 self.getPage('/url/leaf?path_info=/other/../page1') 980 self.assertBody('%s/page1' % self.base()) 981 982 # Output relative to current path or script_name 983 self.getPage('/url/?path_info=page1&relative=True') 984 self.assertBody('page1') 985 self.getPage('/url/leaf?path_info=/page1&relative=True') 986 self.assertBody('../page1') 987 self.getPage('/url/leaf?path_info=../page1&relative=True') 988 self.assertBody('../page1') 989 self.getPage('/url/?path_info=other/../page1&relative=True') 990 self.assertBody('page1') 943 991 944 992

