|
21 | 21 | from email.utils import parsedate
|
22 | 22 | from math import ceil
|
23 | 23 | from pathlib import Path
|
24 |
| -from types import TracebackType |
| 24 | +from types import MappingProxyType, TracebackType |
25 | 25 | from typing import (
|
26 | 26 | Any,
|
27 | 27 | Callable,
|
@@ -357,6 +357,20 @@ def parse_mimetype(mimetype: str) -> MimeType:
|
357 | 357 | )
|
358 | 358 |
|
359 | 359 |
|
| 360 | +@functools.lru_cache(maxsize=56) |
| 361 | +def parse_content_type(raw: str) -> Tuple[str, MappingProxyType[str, str]]: |
| 362 | + """Parse Content-Type header. |
| 363 | +
|
| 364 | + Returns a tuple of the parsed content type and a |
| 365 | + MappingProxyType of parameters. |
| 366 | + """ |
| 367 | + msg = HeaderParser().parsestr(f"Content-Type: {raw}") |
| 368 | + content_type = msg.get_content_type() |
| 369 | + params = msg.get_params(()) |
| 370 | + content_dict = dict(params[1:]) # First element is content type again |
| 371 | + return content_type, MappingProxyType(content_dict) |
| 372 | + |
| 373 | + |
360 | 374 | def guess_filename(obj: Any, default: Optional[str] = None) -> Optional[str]:
|
361 | 375 | name = getattr(obj, "name", None)
|
362 | 376 | if name and isinstance(name, str) and name[0] != "<" and name[-1] != ">":
|
@@ -710,10 +724,10 @@ def _parse_content_type(self, raw: Optional[str]) -> None:
|
710 | 724 | self._content_type = "application/octet-stream"
|
711 | 725 | self._content_dict = {}
|
712 | 726 | else:
|
713 |
| - msg = HeaderParser().parsestr("Content-Type: " + raw) |
714 |
| - self._content_type = msg.get_content_type() |
715 |
| - params = msg.get_params(()) |
716 |
| - self._content_dict = dict(params[1:]) # First element is content type again |
| 727 | + content_type, content_mapping_proxy = parse_content_type(raw) |
| 728 | + self._content_type = content_type |
| 729 | + # _content_dict needs to be mutable so we can update it |
| 730 | + self._content_dict = content_mapping_proxy.copy() |
717 | 731 |
|
718 | 732 | @property
|
719 | 733 | def content_type(self) -> str:
|
|
0 commit comments