async def send(self, request):
        proxy_url = self._proxy_config.proxy_url_for(request.url)

        try:
            url = request.url
            headers = request.headers
            data = request.body

            # https://github.com/boto/botocore/issues/1255
            headers['Accept-Encoding'] = 'identity'

            headers_ = MultiDict(
                (z[0], _text(z[1], encoding='utf-8')) for z in headers.items())

            if isinstance(data, io.IOBase):
                data = _IOBaseWrapper(data)

            url = URL(url, encoded=True)
            resp = await self._session.request(
                request.method, url=url, headers=headers_, data=data, proxy=proxy_url)

            if not request.stream_output:
                # Cause the raw stream to be exhausted immediately. We do it
                # this way instead of using preload_content because
                # preload_content will never buffer chunked responses
                await resp.read()

            return resp
        except ClientSSLError as e:
            raise SSLError(endpoint_url=request.url, error=e)
        except (ClientConnectorError, socket.gaierror) as e:
            raise EndpointConnectionError(endpoint_url=request.url, error=e)
        except (ClientProxyConnectionError, ClientHttpProxyError) as e:
            raise ProxyConnectionError(proxy_url=proxy_url, error=e)
        except ServerTimeoutError as e:
            raise ConnectTimeoutError(endpoint_url=request.url, error=e)
        except asyncio.TimeoutError as e:
            raise ReadTimeoutError(endpoint_url=request.url, error=e)
        except ServerDisconnectedError as e:
            raise ConnectionClosedError(
                error=e,
                request=request,
                endpoint_url=request.url
            )
        except Exception as e:
            message = 'Exception received when sending urllib3 HTTP request'
            logger.debug(message, exc_info=True)
            raise HTTPClientError(error=e)
Exemple #2
0
    async def _send(self, request):
        # Note: When using aiobotocore with dynamodb, requests fail on crc32
        # checksum computation as soon as the response data reaches ~5KB.
        # When AWS response is gzip compressed:
        # 1. aiohttp is automatically decompressing the data
        # (http://aiohttp.readthedocs.io/en/stable/client.html#binary-response-content)
        # 2. botocore computes crc32 on the uncompressed data bytes and fails
        # cause crc32 has been computed on the compressed data
        # The following line forces aws not to use gzip compression,
        # if there is a way to configure aiohttp not to perform decompression,
        # we can remove the following line and take advantage of
        # aws gzip compression.
        # https://github.com/boto/botocore/issues/1255
        url = request.url
        headers = request.headers
        data = request.body

        headers['Accept-Encoding'] = 'identity'
        headers_ = MultiDict(
            (z[0], _text(z[1], encoding='utf-8')) for z in headers.items())

        # botocore does this during the request so we do this here as well
        # TODO: this should be part of the ClientSession, perhaps make wrapper
        proxy = self.proxies.get(urlparse(url.lower()).scheme)

        if isinstance(data, io.IOBase):
            data = _IOBaseWrapper(data)

        url = URL(url, encoded=True)
        resp = await self.http_session.request(request.method,
                                               url=url,
                                               headers=headers_,
                                               data=data,
                                               proxy=proxy)

        # If we're not streaming, read the content so we can retry any timeout
        #  errors, see:
        # https://github.com/boto/botocore/blob/develop/botocore/vendored/requests/sessions.py#L604
        if not request.stream_output:
            await resp.read()

        return resp