|
24 | 24 | from http.cookies import SimpleCookie
|
25 | 25 | from math import ceil
|
26 | 26 | from pathlib import Path
|
27 |
| -from types import TracebackType |
| 27 | +from types import MappingProxyType, TracebackType |
28 | 28 | from typing import (
|
29 | 29 | TYPE_CHECKING,
|
30 | 30 | Any,
|
@@ -367,6 +367,20 @@ def parse_mimetype(mimetype: str) -> MimeType:
|
367 | 367 | )
|
368 | 368 |
|
369 | 369 |
|
| 370 | +@functools.lru_cache(maxsize=56) |
| 371 | +def parse_content_type(raw: str) -> Tuple[str, MappingProxyType[str, str]]: |
| 372 | + """Parse Content-Type header. |
| 373 | +
|
| 374 | + Returns a tuple of the parsed content type and a |
| 375 | + MappingProxyType of parameters. |
| 376 | + """ |
| 377 | + msg = HeaderParser().parsestr(f"Content-Type: {raw}") |
| 378 | + content_type = msg.get_content_type() |
| 379 | + params = msg.get_params(()) |
| 380 | + content_dict = dict(params[1:]) # First element is content type again |
| 381 | + return content_type, MappingProxyType(content_dict) |
| 382 | + |
| 383 | + |
370 | 384 | def guess_filename(obj: Any, default: Optional[str] = None) -> Optional[str]:
|
371 | 385 | name = getattr(obj, "name", None)
|
372 | 386 | if name and isinstance(name, str) and name[0] != "<" and name[-1] != ">":
|
@@ -733,10 +747,10 @@ def _parse_content_type(self, raw: Optional[str]) -> None:
|
733 | 747 | self._content_type = "application/octet-stream"
|
734 | 748 | self._content_dict = {}
|
735 | 749 | else:
|
736 |
| - msg = HeaderParser().parsestr("Content-Type: " + raw) |
737 |
| - self._content_type = msg.get_content_type() |
738 |
| - params = msg.get_params(()) |
739 |
| - self._content_dict = dict(params[1:]) # First element is content type again |
| 750 | + content_type, content_mapping_proxy = parse_content_type(raw) |
| 751 | + self._content_type = content_type |
| 752 | + # _content_dict needs to be mutable so we can update it |
| 753 | + self._content_dict = content_mapping_proxy.copy() |
740 | 754 |
|
741 | 755 | @property
|
742 | 756 | def content_type(self) -> str:
|
|
0 commit comments