Пример #1
0
def update_with_304_response(cached_response: Response,
                             new_response_headers: Headers) -> Response:
    """On a 304 we will get a new set of headers that we want to
    update our cached value with, assuming we have one.

    This should only ever be called when we've sent an ETag and
    gotten a 304 as the response.
    """
    updated_response = copy(cached_response)

    # Lets update our headers with the headers from the new request:
    # http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-26#section-4.1
    #
    # The server isn't supposed to send headers that would make
    # the cached body invalid. But... just in case, we'll be sure
    # to strip out ones we know that might be problematic due to
    # typical assumptions.
    excluded_headers = ["content-length"]

    updated_response.headers.update(
        dict((k, v) for k, v in new_response_headers.items()
             # TODO: Don't think .lower() is necessary
             if k.lower() not in excluded_headers))

    # we want a 200 b/c we have content via the cache
    updated_response.status_code = 200

    return updated_response
Пример #2
0
    async def request(
            self, method: str, path: str, headers: typing.Union[Headers, dict],
            result_body: io.BytesIO, body: typing.Union[io.BytesIO, bytes] = None) -> Headers:
        """Returns the headers from the server after making the given request
        at the given path using the given headers. The body of the response is
        written to the result body.

        Arguments:
        - `method (str)`: The HTTP verb to perform, uppercased, e.g., 'GET'
        - `path (str)`: The path within the host, e.g., /api/foo
        - `headers (Headers, dict)`: The headers to send with case-insensitive
          keys.
        - `result_body (io.BaseIO)`: The IO to write the body from the server;
          nothing is written if the server does not provide a body.
        - `body (bytes, io.BaseIO, None)`: The bytes to send to the server in
           the body, specified either as bytes (which are wrapped with BytesIO)
           or just an bytes-based io object.

        Returns:
        - `headers (Headers)`: The returned headers and trailers from the server.
        """
        if not self.opened:
            await self.open()

        if not isinstance(headers, Headers):
            headers = Headers(headers)

        itr = self.rconn.request(method, self.host, path, headers.multi_items(), body)

        raw_headers = await itr.__anext__()
        response_headers = Headers(raw_headers)

        chunk = await itr.__anext__()
        while chunk is not None:
            result_body.write(chunk)
            chunk = await itr.__anext__()

        raw_trailers = await itr.__anext__()
        response_trailers = Headers(raw_trailers)
        for key, val in response_trailers.items():
            response_headers[key] = val

        return response_headers