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 _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)
def dataReceived(self, data): """ Decompress C{data} with the zlib decompressor, forwarding the raw data to the original protocol. """ try: rawData = self._zlibDecompress.decompress(data) except zlib.error: raise ResponseFailed([failure.Failure()], self._response) if rawData: self.original.dataReceived(rawData)
def connectionLost(self, reason): """ Forward the connection lost event, flushing remaining data from the decompressor if any. """ try: rawData = self._zlibDecompress.flush() except zlib.error: raise ResponseFailed([reason, failure.Failure()], self._response) if rawData: self.original.dataReceived(rawData) self.original.connectionLost(reason)
def _handleResponse(self, response, method, uri, headers, redirectCount): """ Handle the response, making another request if it indicates a redirect. """ if response.code in (http.MOVED_PERMANENTLY, http.FOUND, http.TEMPORARY_REDIRECT): if method not in ('GET', 'HEAD'): err = error.PageRedirect(response.code, location=uri) raise ResponseFailed([failure.Failure(err)], response) return self._handleRedirect(response, method, uri, headers, redirectCount) elif response.code == http.SEE_OTHER: return self._handleRedirect(response, 'GET', uri, headers, redirectCount) return response