(self, headers: Mapping[str, str])
| 87 | return cls._urlnorm(uri) |
| 88 | |
| 89 | def parse_cache_control(self, headers: Mapping[str, str]) -> dict[str, int | None]: |
| 90 | known_directives = { |
| 91 | # https://tools.ietf.org/html/rfc7234#section-5.2 |
| 92 | "max-age": (int, True), |
| 93 | "max-stale": (int, False), |
| 94 | "min-fresh": (int, True), |
| 95 | "no-cache": (None, False), |
| 96 | "no-store": (None, False), |
| 97 | "no-transform": (None, False), |
| 98 | "only-if-cached": (None, False), |
| 99 | "must-revalidate": (None, False), |
| 100 | "public": (None, False), |
| 101 | "private": (None, False), |
| 102 | "proxy-revalidate": (None, False), |
| 103 | "s-maxage": (int, True), |
| 104 | } |
| 105 | |
| 106 | cc_headers = headers.get("cache-control", headers.get("Cache-Control", "")) |
| 107 | |
| 108 | retval: dict[str, int | None] = {} |
| 109 | |
| 110 | for cc_directive in cc_headers.split(","): |
| 111 | if not cc_directive.strip(): |
| 112 | continue |
| 113 | |
| 114 | parts = cc_directive.split("=", 1) |
| 115 | directive = parts[0].strip() |
| 116 | |
| 117 | try: |
| 118 | typ, required = known_directives[directive] |
| 119 | except KeyError: |
| 120 | logger.debug("Ignoring unknown cache-control directive: %s", directive) |
| 121 | continue |
| 122 | |
| 123 | if not typ or not required: |
| 124 | retval[directive] = None |
| 125 | if typ: |
| 126 | try: |
| 127 | retval[directive] = typ(parts[1].strip()) |
| 128 | except IndexError: |
| 129 | if required: |
| 130 | logger.debug( |
| 131 | "Missing value for cache-control " "directive: %s", |
| 132 | directive, |
| 133 | ) |
| 134 | except ValueError: |
| 135 | logger.debug( |
| 136 | "Invalid value for cache-control directive " "%s, must be %s", |
| 137 | directive, |
| 138 | typ.__name__, |
| 139 | ) |
| 140 | |
| 141 | return retval |
| 142 | |
| 143 | def _load_from_cache(self, request: PreparedRequest) -> HTTPResponse | None: |
| 144 | """ |
no test coverage detected