Example #1
0
def parse_cache_control_directives(headers: Headers):
    known_directives = {
        # https://tools.ietf.org/html/rfc7234#section-5.2
        "max-age": (int, True),
        "max-stale": (int, False),
        "min-fresh": (int, True),
        "no-cache": (None, False),
        "no-store": (None, False),
        "no-transform": (None, False),
        "only-if-cached": (None, False),
        "must-revalidate": (None, False),
        "public": (None, False),
        "private": (None, False),
        "proxy-revalidate": (None, False),
        "s-maxage": (int, True),
    }

    cc_headers = headers.get("cache-control", "")

    retval = {}  # type: ignore

    for cc_directive in cc_headers.split(","):
        if not cc_directive.strip():
            continue

        parts = cc_directive.split("=", 1)
        directive = parts[0].strip()

        try:
            typ, required = known_directives[directive]
        except KeyError:
            logger.debug("Ignoring unknown cache-control directive: %s",
                         directive)
            continue

        if not typ or not required:
            retval[directive] = None
        if typ:
            try:
                retval[directive] = typ(parts[1].strip())
            except IndexError:
                if required:
                    logger.debug(
                        "Missing value for cache-control "
                        "directive: %s",
                        directive,
                    )
            except ValueError:
                logger.debug(
                    "Invalid value for cache-control directive "
                    "%s, must be %s",
                    directive,
                    typ.__name__,
                )

    return retval
Example #2
0
def check_vary_headers(request_headers: Headers,
                       cached_vary_data: dict) -> bool:
    """Verify our vary headers match."""
    # Ensure that the Vary headers for the cached response match our
    # request
    # TODO: this should not be here, no reason for request headers to be so deep in deserialization.
    for header, value in cached_vary_data.items():
        if request_headers.get(header, None) != value:
            return False

    return True
Example #3
0
async def process_headers(headers: Headers) -> Dict:
    """Filter out unwanted headers and return as a dictionary."""
    headers = dict(headers)
    header_keys = (
        "user-agent",
        "referer",
        "accept-encoding",
        "accept-language",
        "x-real-ip",
        "x-forwarded-for",
    )
    return {k: headers.get(k) for k in header_keys}
Example #4
0
def get_vary_headers(request_headers: Headers, response: Response):
    """Get vary headers values for persisting in the cache for later checking"""
    vary = {}

    # Construct our vary headers
    if "vary" in response.headers:
        varied_headers = response.headers["vary"].split(",")
        for header in varied_headers:
            header = header.strip()
            header_value = request_headers.get(header, None)
            vary[header] = header_value

    return vary