Ejemplo n.º 1
0
def test_response_with_immutable_headers() -> None:
    resp = Response(
        text="text", headers=CIMultiDictProxy(CIMultiDict({"Header": "Value"}))
    )
    assert resp.headers == {
        "Header": "Value",
        "Content-Type": "text/plain; charset=utf-8",
    }
Ejemplo n.º 2
0
 def function106(self, arg703, arg570=False):
     nonlocal conn
     function2369 = arg703
     self.attribute1481 = 123
     self.attribute1229 = 'Test OK'
     self.attribute2310 = CIMultiDictProxy(CIMultiDict())
     self.attribute1098 = SimpleCookie()
     return
 async def send(self, request, **config):
     response = await super(AiohttpTestTransport,
                            self).send(request, **config)
     if not isinstance(response.headers, CIMultiDictProxy):
         response.headers = CIMultiDictProxy(
             CIMultiDict(response.internal_response.headers))
         response.content_type = response.headers.get("content-type")
     return response
Ejemplo n.º 4
0
 def start(self, connection, read_until_eof=False):
     nonlocal conn
     conn = connection
     self.status = 123
     self.reason = 'Test OK'
     self.headers = CIMultiDictProxy(CIMultiDict())
     self.cookies = SimpleCookie()
     return
Ejemplo n.º 5
0
    def clone(
        self,
        *,
        method: Union[str, _SENTINEL] = sentinel,
        rel_url: Union[StrOrURL, _SENTINEL] = sentinel,
        headers: Union[LooseHeaders, _SENTINEL] = sentinel,
        scheme: Union[str, _SENTINEL] = sentinel,
        host: Union[str, _SENTINEL] = sentinel,
        remote: Union[str, _SENTINEL] = sentinel,
    ) -> "BaseRequest":
        """Clone itself with replacement some attributes.

        Creates and returns a new instance of Request object. If no parameters
        are given, an exact copy is returned. If a parameter is not passed, it
        will reuse the one from the current request object.

        """

        if self._read_bytes:
            raise RuntimeError("Cannot clone request "
                               "after reading its content")

        dct = {}  # type: Dict[str, Any]
        if method is not sentinel:
            dct["method"] = method
        if rel_url is not sentinel:
            new_url: URL = URL(rel_url)  # type: ignore
            dct["url"] = new_url
            dct["path"] = str(new_url)
        if headers is not sentinel:
            # a copy semantic
            new_headers = CIMultiDictProxy(
                CIMultiDict(headers))  # type: ignore
            dct["headers"] = new_headers
            dct["raw_headers"] = tuple((k.encode("utf-8"), v.encode("utf-8"))
                                       for k, v in new_headers.items())

        message = self._message._replace(**dct)

        kwargs: Dict[str, str] = {}
        if scheme is not sentinel:
            kwargs["scheme"] = scheme  # type: ignore
        if host is not sentinel:
            kwargs["host"] = host  # type: ignore
        if remote is not sentinel:
            kwargs["remote"] = remote  # type: ignore

        return self.__class__(
            message,
            self._payload,
            self._protocol,
            self._payload_writer,
            self._task,
            self._loop,
            client_max_size=self._client_max_size,
            state=self._state.copy(),
            **kwargs,
        )
Ejemplo n.º 6
0
def build_response(vcr_request, vcr_response, history):
    request_info = RequestInfo(
        url=URL(vcr_request.url),
        method=vcr_request.method,
        headers=CIMultiDictProxy(CIMultiDict(vcr_request.headers)),
        real_url=URL(vcr_request.url),
    )
    response = MockClientResponse(vcr_request.method,
                                  URL(vcr_response.get("url")),
                                  request_info=request_info)
    response.status = vcr_response["status"]["code"]
    response._body = vcr_response["body"].get("string", b"")
    response.reason = vcr_response["status"]["message"]
    response._headers = CIMultiDictProxy(CIMultiDict(vcr_response["headers"]))
    response._history = tuple(history)

    response.close()
    return response
Ejemplo n.º 7
0
    def headers(self) -> CIMultiDictProxy[str]:
        """Get headers as an immutable, case-insensitive multidict from raw headers"""
        def decode_header(header):
            return (
                header[0].decode('utf-8', 'surrogateescape'),
                header[1].decode('utf-8', 'surrogateescape'),
            )

        return CIMultiDictProxy(
            CIMultiDict([decode_header(h) for h in self.raw_headers]))
def test_update_from_response__disabled():
    """Response headers should not be used if cache_control=False"""
    url = 'https://img.site.com/base/img.jpg'
    headers = [('Cache-Control', 'max-age=60')]
    response = MagicMock(url=url,
                         headers=CIMultiDictProxy(CIMultiDict(headers)))

    actions = CacheActions(key='key', cache_control=False, expire_after=30)
    actions.update_from_response(response)
    assert actions.expire_after == 30
Ejemplo n.º 9
0
def _deserialize_headers(headers):
    deserialized_headers = CIMultiDict()
    for k, vs in headers.items():
        if isinstance(vs, list):
            for v in vs:
                deserialized_headers.add(k, v)
        else:
            deserialized_headers.add(k, vs)

    return CIMultiDictProxy(deserialized_headers)
Ejemplo n.º 10
0
    def start(self, connection, read_until_eof=False):
        """Start response processing."""
        self._closed = False
        self._protocol = connection.protocol
        self._connection = connection

        connection.protocol.set_response_params(
            timer=self._timer,
            skip_payload=self.method.lower() == 'head',
            skip_status_codes=(204, 304),
            read_until_eof=read_until_eof,
            auto_decompress=self._auto_decompress)

        with self._timer:
            while True:
                # read response
                try:
                    (message, payload) = yield from self._protocol.read()
                except http.HttpProcessingError as exc:
                    raise ClientResponseError(
                        self.request_info, self.history,
                        code=exc.code,
                        message=exc.message, headers=exc.headers) from exc

                if (message.code < 100 or
                        message.code > 199 or message.code == 101):
                    break

                if self._continue is not None and not self._continue.done():
                    self._continue.set_result(True)
                    self._continue = None

        # payload eof handler
        payload.on_eof(self._response_eof)

        # response status
        self.version = message.version
        self.status = message.code
        self.reason = message.reason

        # headers
        self.headers = CIMultiDictProxy(message.headers)
        self.raw_headers = tuple(message.raw_headers)

        # payload
        self.content = payload

        # cookies
        for hdr in self.headers.getall(hdrs.SET_COOKIE, ()):
            try:
                self.cookies.load(hdr)
            except CookieError as exc:
                client_logger.warning(
                    'Can not load response cookies: %s', exc)
        return self
Ejemplo n.º 11
0
 async def start(self, connection, read_until_eof=False):
     # vk.com return url like this: http://REDIRECT_URI#access_token=...
     # but aiohttp by default removes all parameters after '#'
     await super().start(connection, read_until_eof)
     headers = CIMultiDict(self.headers)
     location = headers.get(hdrs.LOCATION, None)
     if location is not None:
         headers[hdrs.LOCATION] = location.replace('#', '?')
     self.headers = CIMultiDictProxy(headers)
     self.raw_headers = tuple(headers.items())
     return self
Ejemplo n.º 12
0
Archivo: server.py Proyecto: fu2re/rssf
async def handle(request):
    url = request.query.get('url')
    if not url:
        return web.Response(status=403)
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            _m = [(k.decode("utf-8"), v.decode("utf-8"))
                  for k, v in response.raw_headers
                  if k not in headers_restricted]
            headers = CIMultiDictProxy(CIMultiDict(_m))
            text = await response.text()
            return web.Response(headers=headers, text=fix_text(text))
Ejemplo n.º 13
0
    def clone(self,
              *,
              method: str = sentinel,
              rel_url: StrOrURL = sentinel,
              headers: LooseHeaders = sentinel,
              scheme: str = sentinel,
              host: str = sentinel,
              remote: str = sentinel) -> 'BaseRequest':
        """Clone itself with replacement some attributes.

        Creates and returns a new instance of Request object. If no parameters
        are given, an exact copy is returned. If a parameter is not passed, it
        will reuse the one from the current request object.

        """

        if self._read_bytes:
            raise RuntimeError("Cannot clone request "
                               "after reading its content")

        dct = {}  # type: Dict[str, Any]
        if method is not sentinel:
            dct['method'] = method
        if rel_url is not sentinel:
            new_url = URL(rel_url)
            dct['url'] = new_url
            dct['path'] = str(new_url)
        if headers is not sentinel:
            # a copy semantic
            dct['headers'] = CIMultiDictProxy(CIMultiDict(headers))
            dct['raw_headers'] = tuple((k.encode('utf-8'), v.encode('utf-8'))
                                       for k, v in headers.items())

        message = self._message._replace(**dct)

        kwargs = {}
        if scheme is not sentinel:
            kwargs['scheme'] = scheme
        if host is not sentinel:
            kwargs['host'] = host
        if remote is not sentinel:
            kwargs['remote'] = remote

        return self.__class__(message,
                              self._payload,
                              self._protocol,
                              self._payload_writer,
                              self._task,
                              self._loop,
                              client_max_size=self._client_max_size,
                              state=self._state.copy(),
                              **kwargs)
Ejemplo n.º 14
0
 def __init__(self, request):
     self._request = request
     self._path = request.path
     self._method = request.method
     v = request.environ['SERVER_PROTOCOL']
     self._version = HttpVersion(*map(int, v.split('/')[1].split('.')))
     self._headers = CIMultiDictProxy(CIMultiDict(list(request.headers)))
     self._data = request.get_data()
     # XXX: werkzeug's form data returns dict of lists
     self._form = {
         k: v[0] if len(v) == 1 else v
         for k, v in request.form.items()
     }
def test_update_from_response(headers, expected_expiration):
    """Test with Cache-Control response headers"""
    url = 'https://img.site.com/base/img.jpg'
    response = MagicMock(url=url,
                         headers=CIMultiDictProxy(CIMultiDict(headers)))
    actions = CacheActions(key='key', cache_control=True)
    actions.update_from_response(response)

    if expected_expiration == DO_NOT_CACHE:
        assert actions.skip_write is True
    else:
        assert actions.expire_after == expected_expiration
        assert actions.skip_write is False
Ejemplo n.º 16
0
    async def start(self, connection):
        """Start response processing."""
        self._closed = False
        self._protocol = connection.protocol
        self._connection = connection

        with self._timer:
            while True:
                # read response
                try:
                    message, payload = await self._protocol.read()
                except http.HttpProcessingError as exc:
                    raise ClientResponseError(
                        self.request_info, self.history,
                        status=exc.code,
                        message=exc.message, headers=exc.headers) from exc

                if (message.code < 100 or
                        message.code > 199 or message.code == 101):
                    break

                if self._continue is not None:
                    set_result(self._continue, True)
                    self._continue = None

        # payload eof handler
        payload.on_eof(self._response_eof)

        # response status
        self.version = message.version
        self.status = message.code
        self.reason = message.reason

        # headers
        self._headers = CIMultiDictProxy(message.headers)
        self._raw_headers = tuple(message.raw_headers)

        # payload
        self.content = payload

        # cookies
        for hdr in self.headers.getall(hdrs.SET_COOKIE, ()):
            try:
                self.cookies.load(hdr)
            except CookieError as exc:
                client_logger.warning(
                    'Can not load response cookies: %s', exc)
        return self
Ejemplo n.º 17
0
def clean_response_headers(request: web.Request) -> CIMultiDictProxy:
    """Removes HTTP headers from an upstream response and add auth header if present.

    :param request: A web.Request containing the request whose headers are to be cleaned.
    :return: A CIMultiDictProxy containing the clean headers.
    """
    clean_headers = request.headers.copy()
    for header in DEFAULT_REMOVED_RESPONSE_HEADERS:
        clean_headers.popall(header, None)
    try:
        auth_header = request.pop("auth_payload")
    except KeyError:
        pass
    else:
        clean_headers.add(*auth_header)
    return CIMultiDictProxy(clean_headers)
Ejemplo n.º 18
0
    async def _http_request_task(self, request_envelope: Envelope) -> None:
        """
        Perform http request and send back response.

        :param request_http_message: HttpMessage with http request constructed.

        :return: None
        """
        if not self._loop:  # pragma: nocover
            raise ValueError("Channel is not connected")

        request_http_message, dialogue = self._get_message_and_dialogue(
            request_envelope)

        if not dialogue:
            self.logger.warning(
                "Could not create dialogue for message={}".format(
                    request_http_message))
            return

        try:
            resp = await asyncio.wait_for(
                self._perform_http_request(request_http_message),
                timeout=self.DEFAULT_TIMEOUT,
            )
            envelope = self.to_envelope(
                request_http_message,
                status_code=resp.status,
                headers=resp.headers,
                status_text=resp.reason,
                body=resp._body  # pylint: disable=protected-access
                if resp._body is not None  # pylint: disable=protected-access
                else b"",
                dialogue=dialogue,
            )
        except Exception:  # pylint: disable=broad-except
            envelope = self.to_envelope(
                request_http_message,
                status_code=self.DEFAULT_EXCEPTION_CODE,
                headers=CIMultiDictProxy(CIMultiDict()),
                status_text="HTTPConnection request error.",
                body=format_exc().encode("utf-8"),
                dialogue=dialogue,
            )

        if self._in_queue is not None:
            await self._in_queue.put(envelope)
Ejemplo n.º 19
0
    async def start(self, connection, read_until_eof=False):
        """Start response processing."""
        self._setup_connection(connection)
        message = None

        while True:
            httpstream = self._reader.set_parser(self._response_parser)

            # read response
            message = await httpstream.read()
            if message.code != 100:
                break

            if self._continue is not None and not self._continue.done():
                self._continue.set_result(True)
                self._continue = None

        # response status
        self.version = message.version
        self.status = message.code
        self.reason = message.reason
        self._should_close = message.should_close

        # headers
        self.headers = CIMultiDictProxy(message.headers)

        # payload
        response_with_body = self._need_parse_response_body()
        self._reader.set_parser(
            aiohttp.HttpPayloadParser(
                message,
                compression=False,
                readall=read_until_eof,
                response_with_body=response_with_body),
            self.content
        )

        # cookies
        self.cookies = http.cookies.SimpleCookie()
        if aiohttp.client.hdrs.SET_COOKIE in self.headers:
            for hdr in self.headers.getall(aiohttp.client.hdrs.SET_COOKIE):
                try:
                    self.cookies.load(hdr)
                except http.cookies.CookieError as exc:
                    aiohttp.log.client_logger.warning(
                        'Can not load response cookies: %s', exc)
        return self
Ejemplo n.º 20
0
    def start(self, connection, read_until_eof=False):
        """Start response processing."""
        self._setup_connection(connection)

        with self._timer:
            while True:
                httpstream = self._reader.set_parser(self._response_parser)

                # read response
                message = yield from httpstream.read()
                if (message.code < 100 or
                        message.code > 199 or message.code == 101):
                    break

                if self._continue is not None and not self._continue.done():
                    self._continue.set_result(True)
                    self._continue = None

        # response status
        self.version = message.version
        self.status = message.code
        self.reason = message.reason
        self._should_close = message.should_close

        # headers
        self.headers = CIMultiDictProxy(message.headers)
        self.raw_headers = tuple(message.raw_headers)

        # payload
        rwb = self._need_parse_response_body()
        self._reader.set_parser(
            aiohttp.HttpPayloadParser(message,
                                      readall=read_until_eof,
                                      response_with_body=rwb),
            self.content)

        # cookies
        for hdr in self.headers.getall(hdrs.SET_COOKIE, ()):
            try:
                self.cookies.load(hdr)
            except CookieError as exc:
                client_logger.warning(
                    'Can not load response cookies: %s', exc)
        return self
Ejemplo n.º 21
0
    def start(self, connection, read_until_eof=False):
        """Start response processing."""
        self._protocol = connection.protocol
        self._connection = connection
        connection.protocol.set_response_params(
            timer=self._timer,
            skip_payload=self.method.lower() == 'head',
            skip_status_codes=(204, 304),
            read_until_eof=read_until_eof)

        with self._timer:
            while True:
                # read response
                (message, payload) = yield from self._protocol.read()
                if (message.code < 100 or
                        message.code > 199 or message.code == 101):
                    break

                if self._continue is not None and not self._continue.done():
                    self._continue.set_result(True)
                    self._continue = None

        # response status
        self.version = message.version
        self.status = message.code
        self.reason = message.reason
        self._should_close = message.should_close

        # headers
        self.headers = CIMultiDictProxy(message.headers)
        self.raw_headers = tuple(message.raw_headers)

        # payload
        self.content = payload

        # cookies
        for hdr in self.headers.getall(hdrs.SET_COOKIE, ()):
            try:
                self.cookies.load(hdr)
            except CookieError as exc:
                client_logger.warning(
                    'Can not load response cookies: %s', exc)
        return self
Ejemplo n.º 22
0
 def _create_record(self, request: web.Request, response: web.Response,
                    request_time: datetime,
                    response_time: datetime) -> TraceRecord:
     new_record: TraceRecord = TraceRecord(
         request_time,
         None,
         None,
         TraceRequest(
             request.method,
             str(request.url),
             self._create_headers_dictionary(request.headers),
         ),
         TraceResponse(
             response.status,
             self._create_headers_dictionary(
                 CIMultiDictProxy(response.headers))),
         int((response_time.timestamp() - request_time.timestamp()) * 1000),
     )
     return new_record
Ejemplo n.º 23
0
    def build_response(self, method: str, url: str, payload: str, *,
                       session: ClientSession, status: int) -> ClientResponse:
        response = session._response_class(
            method,
            URL(url),
            request_info=self.mock_module.Mock(),
            writer=self.mock_module.Mock(),
            continue100=None,
            timer=TimerNoop(),
            traces=[],
            loop=session.loop,
            session=session)
        response._headers = CIMultiDictProxy(
            CIMultiDict({'Content-Type': 'application/json'}))
        response.status = status
        if status >= 400:
            response.reason = payload

        response.content = StreamReader(ResponseHandler(session.loop))
        response.content.feed_data(str.encode(payload))
        response.content.feed_eof()
        return response
Ejemplo n.º 24
0
def test_base_ctor() -> None:
    message = RawRequestMessage(
        "GET",
        "/path/to?a=1&b=2",
        HttpVersion(1, 1),
        CIMultiDictProxy(CIMultiDict()),
        (),
        False,
        False,
        False,
        False,
        URL("/path/to?a=1&b=2"),
    )

    req = web.BaseRequest(message, mock.Mock(), mock.Mock(), mock.Mock(),
                          mock.Mock(), mock.Mock())

    assert "GET" == req.method
    assert HttpVersion(1, 1) == req.version
    # MacOS may return CamelCased host name, need .lower()
    # FQDN can be wider than host, e.g.
    # 'fv-az397-495' in 'fv-az397-495.internal.cloudapp.net'
    assert req.host.lower() in socket.getfqdn().lower()
    assert "/path/to?a=1&b=2" == req.path_qs
    assert "/path/to" == req.path
    assert "a=1&b=2" == req.query_string
    assert CIMultiDict() == req.headers
    assert () == req.raw_headers

    get = req.query
    assert MultiDict([("a", "1"), ("b", "2")]) == get
    # second call should return the same object
    assert get is req.query

    assert req.keep_alive

    assert "__dict__" not in dir(req)

    assert req
Ejemplo n.º 25
0
def test_base_ctor() -> None:
    message = RawRequestMessage(
        "GET",
        "/path/to?a=1&b=2",
        HttpVersion(1, 1),
        CIMultiDictProxy(CIMultiDict()),
        (),
        False,
        False,
        False,
        False,
        URL("/path/to?a=1&b=2"),
    )

    req = web.BaseRequest(
        message, mock.Mock(), mock.Mock(), mock.Mock(), mock.Mock(), mock.Mock()
    )

    assert "GET" == req.method
    assert HttpVersion(1, 1) == req.version
    assert req.host == socket.getfqdn()
    assert "/path/to?a=1&b=2" == req.path_qs
    assert "/path/to" == req.path
    assert "a=1&b=2" == req.query_string
    assert CIMultiDict() == req.headers
    assert () == req.raw_headers

    get = req.query
    assert MultiDict([("a", "1"), ("b", "2")]) == get
    # second call should return the same object
    assert get is req.query

    assert req.keep_alive

    assert "__dict__" not in dir(req)

    assert req
Ejemplo n.º 26
0
 def request_info(self) -> RequestInfo:
     headers = CIMultiDictProxy(self.headers)  # type: CIMultiDictProxy[str]
     return RequestInfo(self.url, self.method, headers, self.original_url)
Ejemplo n.º 27
0
    def parse_headers(
            self,
            lines: List[bytes]) -> Tuple['CIMultiDictProxy[str]', RawHeaders]:
        headers = CIMultiDict()  # type: CIMultiDict[str]
        raw_headers = []

        lines_idx = 1
        line = lines[1]
        line_count = len(lines)

        while line:
            # Parse initial header name : value pair.
            try:
                bname, bvalue = line.split(b':', 1)
            except ValueError:
                raise InvalidHeader(line) from None

            bname = bname.strip(b' \t')
            bvalue = bvalue.lstrip()
            if HDRRE.search(bname):
                raise InvalidHeader(bname)
            if len(bname) > self.max_field_size:
                raise LineTooLong(
                    "request header name {}".format(
                        bname.decode("utf8", "xmlcharrefreplace")),
                    str(self.max_field_size), str(len(bname)))

            header_length = len(bvalue)

            # next line
            lines_idx += 1
            line = lines[lines_idx]

            # consume continuation lines
            continuation = line and line[0] in (32, 9)  # (' ', '\t')

            if continuation:
                bvalue_lst = [bvalue]
                while continuation:
                    header_length += len(line)
                    if header_length > self.max_field_size:
                        raise LineTooLong(
                            'request header field {}'.format(
                                bname.decode("utf8", "xmlcharrefreplace")),
                            str(self.max_field_size), str(header_length))
                    bvalue_lst.append(line)

                    # next line
                    lines_idx += 1
                    if lines_idx < line_count:
                        line = lines[lines_idx]
                        if line:
                            continuation = line[0] in (32, 9)  # (' ', '\t')
                    else:
                        line = b''
                        break
                bvalue = b''.join(bvalue_lst)
            else:
                if header_length > self.max_field_size:
                    raise LineTooLong(
                        'request header field {}'.format(
                            bname.decode("utf8", "xmlcharrefreplace")),
                        str(self.max_field_size), str(header_length))

            bvalue = bvalue.strip()
            name = bname.decode('utf-8', 'surrogateescape')
            value = bvalue.decode('utf-8', 'surrogateescape')

            headers.add(name, value)
            raw_headers.append((bname, bvalue))

        return (CIMultiDictProxy(headers), tuple(raw_headers))
Ejemplo n.º 28
0
def make_mocked_request(
    method: str,
    path: str,
    headers: Any = None,
    *,
    match_info: Any = sentinel,
    version: HttpVersion = HttpVersion(1, 1),
    closing: bool = False,
    app: Any = None,
    writer: Any = sentinel,
    protocol: Any = sentinel,
    transport: Any = sentinel,
    payload: Any = sentinel,
    sslcontext: Optional[SSLContext] = None,
    client_max_size: int = 1024 ** 2,
    loop: Any = ...,
) -> Any:
    """Creates mocked web.Request testing purposes.

    Useful in unit tests, when spinning full web server is overkill or
    specific conditions and errors are hard to trigger.

    """

    task = mock.Mock()
    if loop is ...:
        loop = mock.Mock()
        loop.create_future.return_value = ()

    if version < HttpVersion(1, 1):
        closing = True

    if headers:
        headers = CIMultiDictProxy(CIMultiDict(headers))
        raw_hdrs = tuple(
            (k.encode("utf-8"), v.encode("utf-8")) for k, v in headers.items()
        )
    else:
        headers = CIMultiDictProxy(CIMultiDict())
        raw_hdrs = ()

    chunked = "chunked" in headers.get(hdrs.TRANSFER_ENCODING, "").lower()

    message = RawRequestMessage(
        method,
        path,
        version,
        headers,
        raw_hdrs,
        closing,
        False,
        False,
        chunked,
        URL(path),
    )
    if app is None:
        app = _create_app_mock()

    if transport is sentinel:
        transport = _create_transport(sslcontext)

    if protocol is sentinel:
        protocol = mock.Mock()
        protocol.transport = transport

    if writer is sentinel:
        writer = mock.Mock()
        writer.write_headers = make_mocked_coro(None)
        writer.write = make_mocked_coro(None)
        writer.write_eof = make_mocked_coro(None)
        writer.drain = make_mocked_coro(None)
        writer.transport = transport

    protocol.transport = transport
    protocol.writer = writer

    if payload is sentinel:
        payload = mock.Mock()

    req = Request(
        message, payload, protocol, writer, task, loop, client_max_size=client_max_size
    )

    match_info = UrlMappingMatchInfo(
        {} if match_info is sentinel else match_info, mock.Mock()
    )
    match_info.add_app(app)
    req._match_info = match_info

    return req
Ejemplo n.º 29
0
 async def headers(self) -> MultiMapping[str]:
     headers: MultiMapping[str] = await self._response.headers()
     new_headers: CIMultiDict[str] = CIMultiDict(headers)
     for h, v in self._headers.items():
         new_headers.add(h, v)
     return CIMultiDictProxy(new_headers)
Ejemplo n.º 30
0
    def parse_headers(self, lines):
        """Parses RFC 5322 headers from a stream.

        Line continuations are supported. Returns list of header name
        and value pairs. Header name is in upper case.
        """
        headers = CIMultiDict()
        raw_headers = []

        lines_idx = 1
        line = lines[1]
        line_count = len(lines)

        while line:
            # Parse initial header name : value pair.
            try:
                bname, bvalue = line.split(b':', 1)
            except ValueError:
                raise InvalidHeader(line) from None

            bname = bname.strip(b' \t')
            bvalue = bvalue.lstrip()
            if HDRRE.search(bname):
                raise InvalidHeader(bname)
            if len(bname) > self.max_field_size:
                raise LineTooLong(
                    "request header name {}".format(
                        bname.decode("utf8", "xmlcharrefreplace")),
                    self.max_field_size, len(bname))

            header_length = len(bvalue)

            # next line
            lines_idx += 1
            line = lines[lines_idx]

            # consume continuation lines
            continuation = line and line[0] in (32, 9)  # (' ', '\t')

            if continuation:
                bvalue = [bvalue]
                while continuation:
                    header_length += len(line)
                    if header_length > self.max_field_size:
                        raise LineTooLong(
                            'request header field {}'.format(
                                bname.decode("utf8", "xmlcharrefreplace")),
                            self.max_field_size, header_length)
                    bvalue.append(line)

                    # next line
                    lines_idx += 1
                    if lines_idx < line_count:
                        line = lines[lines_idx]
                        if line:
                            continuation = line[0] in (32, 9)  # (' ', '\t')
                    else:
                        line = b''
                        break
                bvalue = b''.join(bvalue)
            else:
                if header_length > self.max_field_size:
                    raise LineTooLong(
                        'request header field {}'.format(
                            bname.decode("utf8", "xmlcharrefreplace")),
                        self.max_field_size, header_length)

            bvalue = bvalue.strip()
            name = bname.decode('utf-8', 'surrogateescape')
            value = bvalue.decode('utf-8', 'surrogateescape')

            headers.add(name, value)
            raw_headers.append((bname, bvalue))

        close_conn = None
        encoding = None
        upgrade = False
        chunked = False
        raw_headers = tuple(raw_headers)
        headers = CIMultiDictProxy(headers)

        # keep-alive
        conn = headers.get(hdrs.CONNECTION)
        if conn:
            v = conn.lower()
            if v == 'close':
                close_conn = True
            elif v == 'keep-alive':
                close_conn = False
            elif v == 'upgrade':
                upgrade = True

        # encoding
        enc = headers.get(hdrs.CONTENT_ENCODING)
        if enc:
            enc = enc.lower()
            if enc in ('gzip', 'deflate', 'br'):
                encoding = enc

        # chunking
        te = headers.get(hdrs.TRANSFER_ENCODING)
        if te and 'chunked' in te.lower():
            chunked = True

        return headers, raw_headers, close_conn, encoding, upgrade, chunked