(self, request, response, urls, code=None)
The constructor creates a new instance and modifies the
        *response* argument to reflect a redirect response to the
        given *url*.
The constructor creates a new instance and modifies the
        *response* argument to reflect a redirect response to the
        given *url*.
The constructor creates a new instance and modifies the * response * argument to reflect a redirect response to the given * url * .
def __init__(self, request, response, urls, code=None):
        """
        The constructor creates a new instance and modifies the
        *response* argument to reflect a redirect response to the
        given *url*.
        """

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

        abs_urls = []
        for url in urls:
            # 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 request is discarded.
            url = request.uri.relative(url).unicode()
            abs_urls.append(url)
        self.urls = 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://ppewww.ph.gla.ac.uk/~flavell/www/post-redirect.html
        if code is None:
            if request.protocol >= (1, 1):
                code = 303
            else:
                code = 302
        else:
            if code < 300 or code > 399:
                raise ValueError("status code must be between 300 and 399.")

        super(redirect, self).__init__(request, response, code)

        if code in (300, 301, 302, 303, 307):
            response.headers["Content-Type"] = "text/html"
            # "The ... URI SHOULD be given by the Location field
            # in the response."
            response.headers["Location"] = urls[0]

            # "Unless the request method was HEAD, the entity of the response
            # SHOULD contain a short hypertext note with a hyperlink to the
            # new URI(s)."
            msg = {300: "This resource can be found at <a href='%s'>%s</a>.",
                   301: ("This resource has permanently moved to "
                         "<a href='%s'>%s</a>."),
                   302: ("This resource resides temporarily at "
                         "<a href='%s'>%s</a>."),
                   303: ("This resource can be found at "
                         "<a href='%s'>%s</a>."),
                   307: ("This resource has moved temporarily to "
                         "<a href='%s'>%s</a>."),
                   }[code]
            response.body = "<br />\n".join([msg % (u, u) for u in urls])
            # Previous code may have set C-L, so we have to reset it
            # (allow finalize to set it).
            response.headers.pop("Content-Length", None)
        elif code == 304:
            # Not Modified.
            # "The response MUST include the following header fields:
            # Date, unless its omission is required by section 14.18.1"
            # The "Date" header should have been set in Response.__init__

            # "...the response SHOULD NOT include other entity-headers."
            for key in ("Allow", "Content-Encoding", "Content-Language",
                        "Content-Length", "Content-Location", "Content-MD5",
                        "Content-Range", "Content-Type", "Expires",
                        "Last-Modified"):
                if key in response.headers:
                    del response.headers[key]

            # "The 304 response MUST NOT contain a message-body."
            response.body = None
            # Previous code may have set C-L, so we have to reset it.
            response.headers.pop("Content-Length", None)
        elif code == 305:
            # Use Proxy.
            # urls[0] should be the URI of the proxy.
            response.headers["Location"] = urls[0]
            response.body = None
            # Previous code may have set C-L, so we have to reset it.
            response.headers.pop("Content-Length", None)
        else:
            raise ValueError("The %s status code is unknown." % code)
def __init__ ( self , request , response , urls , code = None ) : if isinstance ( urls , string_types ) : urls = [ urls ] abs_urls = [ ] for url in urls : # 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 request is discarded. url = request . uri . relative ( url ) . unicode ( ) abs_urls . append ( url ) self . urls = 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://ppewww.ph.gla.ac.uk/~flavell/www/post-redirect.html if code is None : if request . protocol >= ( 1 , 1 ) : code = 303 else : code = 302 else : if code < 300 or code > 399 : raise ValueError ( "status code must be between 300 and 399." ) super ( redirect , self ) . __init__ ( request , response , code ) if code in ( 300 , 301 , 302 , 303 , 307 ) : response . headers [ "Content-Type" ] = "text/html" # "The ... URI SHOULD be given by the Location field # in the response." response . headers [ "Location" ] = urls [ 0 ] # "Unless the request method was HEAD, the entity of the response # SHOULD contain a short hypertext note with a hyperlink to the # new URI(s)." msg = { 300 : "This resource can be found at <a href='%s'>%s</a>." , 301 : ( "This resource has permanently moved to " "<a href='%s'>%s</a>." ) , 302 : ( "This resource resides temporarily at " "<a href='%s'>%s</a>." ) , 303 : ( "This resource can be found at " "<a href='%s'>%s</a>." ) , 307 : ( "This resource has moved temporarily to " "<a href='%s'>%s</a>." ) , } [ code ] response . body = "<br />\n" . join ( [ msg % ( u , u ) for u in urls ] ) # Previous code may have set C-L, so we have to reset it # (allow finalize to set it). response . headers . pop ( "Content-Length" , None ) elif code == 304 : # Not Modified. # "The response MUST include the following header fields: # Date, unless its omission is required by section 14.18.1" # The "Date" header should have been set in Response.__init__ # "...the response SHOULD NOT include other entity-headers." for key in ( "Allow" , "Content-Encoding" , "Content-Language" , "Content-Length" , "Content-Location" , "Content-MD5" , "Content-Range" , "Content-Type" , "Expires" , "Last-Modified" ) : if key in response . headers : del response . headers [ key ] # "The 304 response MUST NOT contain a message-body." response . body = None # Previous code may have set C-L, so we have to reset it. response . headers . pop ( "Content-Length" , None ) elif code == 305 : # Use Proxy. # urls[0] should be the URI of the proxy. response . headers [ "Location" ] = urls [ 0 ] response . body = None # Previous code may have set C-L, so we have to reset it. response . headers . pop ( "Content-Length" , None ) else : raise ValueError ( "The %s status code is unknown." % code )