Esempio n. 1
0
    def __init__(self, urls, status=None, encoding=None):
        import cherrypy
        request = cherrypy.serving.request

        if isinstance(urls, basestring):
            urls = [urls]

        abs_urls = []
        for url in urls:
            url = tonative(url, encoding or self.encoding)

            # Note that urljoin will "do the right thing" whether url is:
            #  1. a complete URL with host (e.g. "http://www.example.com/test")
            #  2. a URL relative to root (e.g. "/dummy")
            #  3. a URL relative to the current path
            # Note that any query string in cherrypy.request is discarded.
            url = _urljoin(cherrypy.url(), url)
            abs_urls.append(url)
        self.urls = abs_urls

        # RFC 2616 indicates a 301 response code fits our goal; however,
        # browser support for 301 is quite messy. Do 302/303 instead. See
        # http://www.alanflavell.org.uk/www/post-redirect.html
        if status is None:
            if request.protocol >= (1, 1):
                status = 303
            else:
                status = 302
        else:
            status = int(status)
            if status < 300 or status > 399:
                raise ValueError("status must be between 300 and 399.")

        self.status = status
        CherryPyException.__init__(self, abs_urls, status)
Esempio n. 2
0
    def __init__(self, urls, status=None, encoding=None):
        import cherrypy
        request = cherrypy.serving.request

        if isinstance(urls, text_or_bytes):
            urls = [urls]

        abs_urls = []
        for url in urls:
            url = tonative(url, encoding or self.encoding)

            # Note that urljoin will "do the right thing" whether url is:
            #  1. a complete URL with host (e.g. "http://www.example.com/test")
            #  2. a URL relative to root (e.g. "/dummy")
            #  3. a URL relative to the current path
            # Note that any query string in cherrypy.request is discarded.
            url = _urljoin(cherrypy.url(), url)
            abs_urls.append(url)
        self.urls = abs_urls

        # RFC 2616 indicates a 301 response code fits our goal; however,
        # browser support for 301 is quite messy. Do 302/303 instead. See
        # http://www.alanflavell.org.uk/www/post-redirect.html
        if status is None:
            if request.protocol >= (1, 1):
                status = 303
            else:
                status = 302
        else:
            status = int(status)
            if status < 300 or status > 399:
                raise ValueError("status must be between 300 and 399.")

        self.status = status
        CherryPyException.__init__(self, abs_urls, status)
Esempio n. 3
0
 def __init__(self, path, query_string=''):
     import cherrypy
     self.request = cherrypy.serving.request
     self.query_string = query_string
     if '?' in path:
         path, self.query_string = path.split('?', 1)
     path = _urljoin(self.request.path_info, path)
     self.path = path
     CherryPyException.__init__(self, path, self.query_string)
Esempio n. 4
0
 def __init__(self, path, query_string = ''):
     import cherrypy
     self.request = cherrypy.serving.request
     self.query_string = query_string
     if '?' in path:
         path, self.query_string = path.split('?', 1)
     path = _urljoin(self.request.path_info, path)
     self.path = path
     CherryPyException.__init__(self, path, self.query_string)
Esempio n. 5
0
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
Esempio n. 6
0
    def __init__(self, path, query_string=""):
        import cherrypy
        self.request = cherrypy.serving.request

        self.query_string = query_string
        if "?" in path:
            # Separate any params included in the path
            path, self.query_string = path.split("?", 1)

        # 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 query string will be discarded.
        path = _urljoin(self.request.path_info, path)

        # Set a 'path' member attribute so that code which traps this
        # error can have access to it.
        self.path = path

        CherryPyException.__init__(self, path, self.query_string)
Esempio n. 7
0
    def __init__(self, path, query_string=""):
        import cherrypy
        self.request = cherrypy.serving.request

        self.query_string = query_string
        if "?" in path:
            # Separate any params included in the path
            path, self.query_string = path.split("?", 1)

        # 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 query string will be discarded.
        path = _urljoin(self.request.path_info, path)

        # Set a 'path' member attribute so that code which traps this
        # error can have access to it.
        self.path = path

        CherryPyException.__init__(self, path, self.query_string)
Esempio n. 8
0
    def __init__(self, urls, status=None, encoding=None):
        import cherrypy
        request = cherrypy.serving.request
        if isinstance(urls, basestring):
            urls = [urls]
        abs_urls = []
        for url in urls:
            if isinstance(url, unicode):
                url = url.encode(encoding or self.encoding)
            url = _urljoin(cherrypy.url(), url)
            abs_urls.append(url)

        self.urls = abs_urls
        if status is None:
            if request.protocol >= (1, 1):
                status = 303
            else:
                status = 302
        else:
            status = int(status)
            if status < 300 or status > 399:
                raise ValueError('status must be between 300 and 399.')
        self.status = status
        CherryPyException.__init__(self, abs_urls, status)
Esempio n. 9
0
    def __init__(self, urls, status = None, encoding = None):
        import cherrypy
        request = cherrypy.serving.request
        if isinstance(urls, basestring):
            urls = [urls]
        abs_urls = []
        for url in urls:
            if isinstance(url, unicode):
                url = url.encode(encoding or self.encoding)
            url = _urljoin(cherrypy.url(), url)
            abs_urls.append(url)

        self.urls = abs_urls
        if status is None:
            if request.protocol >= (1, 1):
                status = 303
            else:
                status = 302
        else:
            status = int(status)
            if status < 300 or status > 399:
                raise ValueError('status must be between 300 and 399.')
        self.status = status
        CherryPyException.__init__(self, abs_urls, status)
Esempio n. 10
0
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
Esempio n. 11
0
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
Esempio n. 12
0
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