def url(path = '', qs = '', script_name = None, base = None, relative = None): if isinstance(qs, (tuple, list, dict)): qs = _urlencode(qs) if qs: qs = '?' + qs if request.app: if not path.startswith('/'): pi = request.path_info if request.is_index is True: if not pi.endswith('/'): pi = pi + '/' elif request.is_index is False: if pi.endswith('/') and pi != '/': pi = pi[:-1] if path == '': path = pi else: path = _urljoin(pi, path) if script_name is None: script_name = request.script_name if base is None: base = request.base newurl = base + script_name + path + qs else: if base is None: base = server.base() path = (script_name or '') + path newurl = base + path + qs if './' in newurl: atoms = [] for atom in newurl.split('/'): if atom == '.': pass elif atom == '..': atoms.pop() else: atoms.append(atom) newurl = '/'.join(atoms) if relative is None: relative = getattr(request.app, 'relative_urls', False) if relative == 'server': newurl = '/' + '/'.join(newurl.split('/', 3)[3:]) elif relative: old = url().split('/')[:-1] new = newurl.split('/') while old and new: a, b = old[0], new[0] if a != b: break old.pop(0) new.pop(0) new = ['..'] * len(old) + new newurl = '/'.join(new) return newurl
def url(path='', qs='', script_name=None, base=None, relative=None): """Create an absolute URL for the given path. If 'path' starts with a slash ('/'), this will return (base + script_name + path + qs). If it does not start with a slash, this returns (base + script_name [+ request.path_info] + path + qs). If script_name is None, cherrypy.request will be used to find a script_name, if available. If base is None, cherrypy.request.base will be used (if available). Note that you can use cherrypy.tools.proxy to change this. Finally, note that this function can be used to obtain an absolute URL for the current request path (minus the querystring) by passing no args. If you call url(qs=cherrypy.request.query_string), you should get the original browser URL (assuming no internal redirections). If relative is None or not provided, request.app.relative_urls will be used (if available, else False). If False, the output will be an absolute URL (including the scheme, host, vhost, and script_name). If True, the output will instead be a URL that is relative to the current request path, perhaps including '..' atoms. If relative is the string 'server', the output will instead be a URL that is relative to the server root; i.e., it will start with a slash. """ if isinstance(qs, (tuple, list, dict)): qs = _urlencode(qs) if qs: qs = '?' + qs if request.app: if not path.startswith('/'): pi = request.path_info if request.is_index is True: if not pi.endswith('/'): pi = pi + '/' elif request.is_index is False: if pi.endswith('/') and pi != '/': pi = pi[:-1] if path == '': path = pi else: path = _urljoin(pi, path) if script_name is None: script_name = request.script_name if base is None: base = request.base newurl = base + script_name + path + qs else: if base is None: base = server.base() path = (script_name or '') + path newurl = base + path + qs if './' in newurl: atoms = [] for atom in newurl.split('/'): if atom == '.': pass elif atom == '..': atoms.pop() else: atoms.append(atom) newurl = '/'.join(atoms) if relative is None: relative = getattr(request.app, 'relative_urls', False) if relative == 'server': newurl = '/' + '/'.join(newurl.split('/', 3)[3:]) elif relative: old = url().split('/')[:-1] new = newurl.split('/') while old and new: a, b = old[0], new[0] if a != b: break old.pop(0) new.pop(0) new = ['..'] * len(old) + new newurl = '/'.join(new) return newurl
def url(path="", qs="", script_name=None, base=None, relative=None): """Create an absolute URL for the given path. If 'path' starts with a slash ('/'), this will return (base + script_name + path + qs). If it does not start with a slash, this returns (base + script_name [+ request.path_info] + path + qs). If script_name is None, cherrypy.request will be used to find a script_name, if available. If base is None, cherrypy.request.base will be used (if available). Note that you can use cherrypy.tools.proxy to change this. Finally, note that this function can be used to obtain an absolute URL for the current request path (minus the querystring) by passing no args. If you call url(qs=cherrypy.request.query_string), you should get the original browser URL (assuming no internal redirections). If relative is None or not provided, request.app.relative_urls will be used (if available, else False). If False, the output will be an absolute URL (including the scheme, host, vhost, and script_name). If True, the output will instead be a URL that is relative to the current request path, perhaps including '..' atoms. If relative is the string 'server', the output will instead be a URL that is relative to the server root; i.e., it will start with a slash. """ if isinstance(qs, (tuple, list, dict)): qs = _urlencode(qs) if qs: qs = '?' + qs if request.app: if not path.startswith("/"): # Append/remove trailing slash from path_info as needed # (this is to support mistyped URL's without redirecting; # if you want to redirect, use tools.trailing_slash). pi = request.path_info if request.is_index is True: if not pi.endswith('/'): pi = pi + '/' elif request.is_index is False: if pi.endswith('/') and pi != '/': pi = pi[:-1] if path == "": path = pi else: path = _urljoin(pi, path) if script_name is None: script_name = request.script_name if base is None: base = request.base newurl = base + script_name + path + qs else: # No request.app (we're being called outside a request). # We'll have to guess the base from server.* attributes. # This will produce very different results from the above # if you're using vhosts or tools.proxy. if base is None: base = server.base() path = (script_name or "") + path newurl = base + path + qs if './' in newurl: # Normalize the URL by removing ./ and ../ atoms = [] for atom in newurl.split('/'): if atom == '.': pass elif atom == '..': atoms.pop() else: atoms.append(atom) newurl = '/'.join(atoms) # At this point, we should have a fully-qualified absolute URL. if relative is None: relative = getattr(request.app, "relative_urls", False) # See http://www.ietf.org/rfc/rfc2396.txt if relative == 'server': # "A relative reference beginning with a single slash character is # termed an absolute-path reference, as defined by <abs_path>..." # This is also sometimes called "server-relative". newurl = '/' + '/'.join(newurl.split('/', 3)[3:]) elif relative: # "A relative reference that does not begin with a scheme name # or a slash character is termed a relative-path reference." old = url(relative=False).split('/')[:-1] new = newurl.split('/') while old and new: a, b = old[0], new[0] if a != b: break old.pop(0) new.pop(0) new = (['..'] * len(old)) + new newurl = '/'.join(new) return newurl