def redirect_request(self, req, fp, code, msg, headers, newurl): """Return a Request or None in response to a redirect. This is called by the http_error_30x methods when a redirection response is received. If a redirection should take place, return a new Request to allow http_error_30x to perform the redirect. Otherwise, raise HTTPError if no-one else should try to handle this url. Return None if you can't but another Handler might. """ m = req.get_method() if (code in (301, 302, 303, 307, "refresh") and m in ("GET", "HEAD") or code in (301, 302, 303, "refresh") and m == "POST"): # Strictly (according to RFC 2616), 301 or 302 in response # to a POST MUST NOT cause a redirection without confirmation # from the user (of urllib2, in this case). In practice, # essentially all clients do redirect in this case, so we do # the same. # TODO: really refresh redirections should be visiting; tricky to fix new = _request.Request( newurl, headers=req.headers, origin_req_host=req.get_origin_req_host(), unverifiable=True, visit=False, timeout=req.timeout) new._origin_req = getattr(req, "_origin_req", req) return new else: raise HTTPError(req.get_full_url(), code, msg, headers, fp)
def visit_response(self, response, request=None): """Visit the response, as if it had been .open()ed. Unlike .set_response(), this updates history rather than replacing the current response. """ if request is None: request = _request.Request(response.geturl()) self._visit_request(request, True) self._set_response(response, False)