| 131 | |
| 132 | |
| 133 | class MultiPartParser: |
| 134 | def __init__( |
| 135 | self, |
| 136 | *, |
| 137 | buffer_size: int = 64 * 1024, |
| 138 | cls: type[MultiDict] = MultiDict, |
| 139 | file_storage_cls: type[FileStorage] = FileStorage, |
| 140 | max_content_length: int | None = None, |
| 141 | max_form_memory_size: int | None = None, |
| 142 | max_form_parts: int | None = None, |
| 143 | stream_factory: StreamFactory = default_stream_factory, |
| 144 | ) -> None: |
| 145 | self.buffer_size = buffer_size |
| 146 | self.cls = cls |
| 147 | self.file_storage_cls = file_storage_cls |
| 148 | self.max_content_length = max_content_length |
| 149 | self.max_form_memory_size = max_form_memory_size |
| 150 | self.max_form_parts = max_form_parts |
| 151 | self.stream_factory = stream_factory |
| 152 | |
| 153 | def fail(self, message: str) -> NoReturn: |
| 154 | raise ValueError(message) |
| 155 | |
| 156 | def get_part_charset(self, headers: Headers) -> str: |
| 157 | content_type = headers.get("content-type") |
| 158 | |
| 159 | if content_type: |
| 160 | parameters = parse_options_header(content_type)[1] |
| 161 | ct_charset = parameters.get("charset", "").lower() |
| 162 | |
| 163 | # A safe list of encodings. Modern clients should only send ASCII or UTF-8. |
| 164 | # This list will not be extended further. |
| 165 | if ct_charset in {"ascii", "us-ascii", "utf-8", "iso-8859-1"}: |
| 166 | return ct_charset |
| 167 | |
| 168 | return "utf-8" |
| 169 | |
| 170 | def start_file_streaming(self, event: File, total_content_length: int) -> IO[bytes]: |
| 171 | content_type = event.headers.get("content-type") |
| 172 | |
| 173 | try: |
| 174 | content_length = int(event.headers["content-length"]) |
| 175 | except (KeyError, ValueError): |
| 176 | content_length = 0 |
| 177 | |
| 178 | container = self.stream_factory( |
| 179 | total_content_length, |
| 180 | content_type, |
| 181 | event.filename, |
| 182 | content_length, |
| 183 | ) |
| 184 | return container |
| 185 | |
| 186 | async def parse( |
| 187 | self, body: Body, boundary: bytes, content_length: int |
| 188 | ) -> tuple[MultiDict, MultiDict]: |
| 189 | container: IO[bytes] | list[bytes] |
| 190 | _write: Callable[[bytes], Any] |
no outgoing calls
searching dependent graphs…