Exemple #1
0
    async def handle_redirect(self, request: Request, response: Response, stream: bool, follow_redirects: bool,
                              max_redirects: int, decode: bool, validate_ssl, headers: dict) -> Response:
        """

        :param headers:
        :param validate_ssl:
        :param decode:
        :param max_redirects:
        :param follow_redirects:
        :param stream:
        :param response:
        :param request:
        :return:
        """
        if max_redirects == 0:
            raise TooManyRedirects
        try:
            location = response.headers['location']
        except KeyError:
            raise Exception('HTTP redirect response missing location header.')
        if not location.startswith('http'):
            if not location.startswith('/'):
                location = '/' + location
            location = request.url.netloc + location

        redirect_url = parse_url(location.encode())
        headers['Host'] = redirect_url.host
        return await self.request(
            url=redirect_url, method='GET', stream=stream, follow_redirects=follow_redirects,
            max_redirects=(max_redirects - 1), decode=decode, validate_ssl=validate_ssl, headers=headers,
            origin=response
        )
Exemple #2
0
    async def request(self, url: str = '/', stream: bool = None, follow_redirects: bool = None,
                      max_redirects: int = 30, decode: bool = True, ssl=None, timeout=ClientDefaults.TIMEOUT,
                      retries: Union[RetryStrategy, int] = None,
                      headers: dict = None, method: str = 'GET', query: dict = None,
                      json: dict = None, ignore_prefix: bool = False, body=None,
                      form: dict = None) -> Response:

        # Asserting the user is not using conflicting params.
        if sum([body is not None, json is not None, form is not None]) > 1:
            raise ValueError('You cannot set body, json or form together. You must pick one and only one.')

        # Handling default parameters.
        stream = stream if stream is not None else self.stream
        follow_redirects = follow_redirects if follow_redirects is not None else self.follow_redirects
        max_redirects = max_redirects if max_redirects is not None else self.max_redirects
        decode = decode if decode else self.decode
        ssl = ssl if ssl is not None else self.ssl
        retries = retries.clone() if retries is not None else RetryStrategy()

        request_headers = self._headers.copy()
        if headers:
            request_headers.update(headers)

        # Constructing the URL.
        url = self.build_url(prefix=self.prefix if not ignore_prefix else b'', url=url.encode(URL_ENCODING),
                             query=query)
        parsed_url = parse_url(url)

        if json is not None:
            body = json_module.dumps(json).encode('utf-8')
            request_headers['Content-Type'] = 'application/json'

        if form is not None:
            boundary = str(uuid.uuid4()).replace('-', '').encode()
            body = MultipartEncoder(delimiter=boundary, params=form)
            request_headers['Content-Type'] = f'multipart/form-data; boundary={boundary.decode()}'

        while True:
            try:
                task = self._engine.request(
                    url=parsed_url, data=body, method=method, stream=stream,
                    follow_redirects=follow_redirects, max_redirects=max_redirects, decode=decode,
                    validate_ssl=ssl, headers=request_headers)
                if timeout:
                    response = await asyncio.wait_for(task, timeout)
                else:
                    response = await task
                if retries.responses.get(response.status_code, 0) > 0:
                    retries.responses[response.status_code] -= 1
                    continue
                return response
            except (ConnectionError, TimeoutError) as error:
                if retries.network_failures.get(method, 0) > 0:
                    retries.network_failures[method] -= 1
                    continue
                raise error