Returns a dictionary from HTTP header text. >>> h = HTTPHeaders.parse("Content-Type: text/html\\r\\nContent-Length: 42\\r\\n") >>> sorted(h.items()) [('Content-Length', '42'), ('Content-Type', 'text/html')] .. versionchanged:: 5.1 Raises `HTTPInputError`
(cls, headers: str, *, _chars_are_bytes: bool = True)
| 295 | |
| 296 | @classmethod |
| 297 | def parse(cls, headers: str, *, _chars_are_bytes: bool = True) -> "HTTPHeaders": |
| 298 | """Returns a dictionary from HTTP header text. |
| 299 | |
| 300 | >>> h = HTTPHeaders.parse("Content-Type: text/html\\r\\nContent-Length: 42\\r\\n") |
| 301 | >>> sorted(h.items()) |
| 302 | [('Content-Length', '42'), ('Content-Type', 'text/html')] |
| 303 | |
| 304 | .. versionchanged:: 5.1 |
| 305 | |
| 306 | Raises `HTTPInputError` on malformed headers instead of a |
| 307 | mix of `KeyError`, and `ValueError`. |
| 308 | |
| 309 | """ |
| 310 | # _chars_are_bytes is a hack. This method is used in two places, HTTP headers (in which |
| 311 | # non-ascii characters are to be interpreted as latin-1) and multipart/form-data (in which |
| 312 | # they are to be interpreted as utf-8). For historical reasons, this method handled this by |
| 313 | # expecting both callers to decode the headers to strings before parsing them. This wasn't a |
| 314 | # problem until we started doing stricter validation of the characters allowed in HTTP |
| 315 | # headers (using ABNF rules defined in terms of byte values), which inadvertently started |
| 316 | # disallowing non-latin1 characters in multipart/form-data filenames. |
| 317 | # |
| 318 | # This method should have accepted bytes and a desired encoding, but this change is being |
| 319 | # introduced in a patch release that shouldn't change the API. Instead, the _chars_are_bytes |
| 320 | # flag decides whether to use HTTP-style ABNF validation (treating the string as bytes |
| 321 | # smuggled through the latin1 encoding) or to accept any non-control unicode characters |
| 322 | # as required by multipart/form-data. This method will change to accept bytes in a future |
| 323 | # release. |
| 324 | h = cls() |
| 325 | |
| 326 | start = 0 |
| 327 | while True: |
| 328 | lf = headers.find("\n", start) |
| 329 | if lf == -1: |
| 330 | h.parse_line(headers[start:], _chars_are_bytes=_chars_are_bytes) |
| 331 | break |
| 332 | line = headers[start : lf + 1] |
| 333 | start = lf + 1 |
| 334 | h.parse_line(line, _chars_are_bytes=_chars_are_bytes) |
| 335 | return h |
| 336 | |
| 337 | # MutableMapping abstract method implementations. |
| 338 |
no test coverage detected