def _handleRedirect(self, response, method, uri, headers, redirectCount): """ Handle a redirect response, checking the number of redirects already followed, and extracting the location header fields. """ if redirectCount >= self._redirectLimit: err = httperror.InfiniteRedirection( response.code, b'Infinite redirection detected', location=uri) raise ResponseFailed([Failure(err)], response) locationHeaders = response.headers.getRawHeaders(b'location', []) if not locationHeaders: err = httperror.RedirectWithNoLocation( response.code, b'No location header field', uri) raise ResponseFailed([Failure(err)], response) # ZPS-4904 location = self._resolveLocation(response.request.absoluteURI, locationHeaders[0]) deferred = self._agent.request(method, location, headers) def _chainResponse(newResponse): newResponse.setPreviousResponse(response) return newResponse deferred.addCallback(_chainResponse) return deferred.addCallback(self._handleResponse, method, uri, headers, redirectCount + 1)
def _handleRedirect(self, response, method, uri, headers, redirectCount): """ Handle a redirect response, checking the number of redirects already followed, and extracting the location header fields. """ if redirectCount >= self._redirectLimit: err = error.InfiniteRedirection(response.code, 'Infinite redirection detected', location=uri) raise ResponseFailed([failure.Failure(err)], response) location_headers = response.headers.getRawHeaders('location', []) if not location_headers: err = error.RedirectWithNoLocation(response.code, 'No location header field', uri) raise ResponseFailed([failure.Failure(err)], response) location = self._resolveLocation(uri, location_headers[0]) deferred = self._agent.request(method, location, headers) def chain_response_(new_response): """Chains responses""" new_response.setPreviousResponse(response) return new_response deferred.addCallback(chain_response_) return deferred.addCallback(self._handleResponse, method, location, headers, redirectCount + 1)
def test_validMessage(self): """ When C{code}, C{message}, and C{uri} are passed to the L{RedirectWithNoLocation} constructor, the C{message} and C{uri} attributes are set, respectively. """ e = error.RedirectWithNoLocation(b"302", b"REDIRECT", b"https://example.com") self.assertEqual(e.message, b"REDIRECT to https://example.com") self.assertEqual(e.uri, b"https://example.com")
def _handleRedirect(self, response, method, uri, headers, redirectCount): """ Handle a redirect response, checking the number of redirects already followed, and extracting the location header fields. This is patched to fix a bug in infinite redirect loop. """ if redirectCount >= self._redirectLimit: err = error.InfiniteRedirection( response.code, b'Infinite redirection detected', location=uri) raise ResponseFailed([Failure(err)], response) locationHeaders = response.headers.getRawHeaders(b'location', []) if not locationHeaders: err = error.RedirectWithNoLocation( response.code, b'No location header field', uri) raise ResponseFailed([Failure(err)], response) location = self._resolveLocation( # This is the fix to properly handle redirects response.request.absoluteURI, locationHeaders[0] ) if getattr(client, 'URI', None): uri = client.URI.fromBytes(location) else: # Backward compatibility with twisted 14.0.2 uri = client._URI.fromBytes(location) if self.ignorePrivateRedirects and is_private_address(uri.host, only_loopback=True): return response deferred = self._agent.request(method, location, headers) def _chainResponse(newResponse): if isinstance(newResponse, Failure): # This is needed to write the response even in case of failure newResponse.previousResponse = response newResponse.requestLocation = location return newResponse newResponse.setPreviousResponse(response) return newResponse deferred.addBoth(_chainResponse) return deferred.addCallback( self._handleResponse, method, uri, headers, redirectCount + 1)