Parses a form request body. Supports ``application/x-www-form-urlencoded`` and ``multipart/form-data``. The ``content_type`` parameter should be a string and ``body`` should be a byte string. The ``arguments`` and ``files`` parameters are dictionaries that will be updated with
(
content_type: str,
body: bytes,
arguments: Dict[str, List[bytes]],
files: Dict[str, List[HTTPFile]],
headers: Optional[HTTPHeaders] = None,
*,
config: Optional[ParseBodyConfig] = None,
)
| 991 | |
| 992 | |
| 993 | def parse_body_arguments( |
| 994 | content_type: str, |
| 995 | body: bytes, |
| 996 | arguments: Dict[str, List[bytes]], |
| 997 | files: Dict[str, List[HTTPFile]], |
| 998 | headers: Optional[HTTPHeaders] = None, |
| 999 | *, |
| 1000 | config: Optional[ParseBodyConfig] = None, |
| 1001 | ) -> None: |
| 1002 | """Parses a form request body. |
| 1003 | |
| 1004 | Supports ``application/x-www-form-urlencoded`` and |
| 1005 | ``multipart/form-data``. The ``content_type`` parameter should be |
| 1006 | a string and ``body`` should be a byte string. The ``arguments`` |
| 1007 | and ``files`` parameters are dictionaries that will be updated |
| 1008 | with the parsed contents. |
| 1009 | """ |
| 1010 | if config is None: |
| 1011 | config = _DEFAULT_PARSE_BODY_CONFIG |
| 1012 | if content_type.startswith("application/x-www-form-urlencoded"): |
| 1013 | if headers and "Content-Encoding" in headers: |
| 1014 | raise HTTPInputError( |
| 1015 | "Unsupported Content-Encoding: %s" % headers["Content-Encoding"] |
| 1016 | ) |
| 1017 | try: |
| 1018 | # real charset decoding will happen in RequestHandler.decode_argument() |
| 1019 | uri_arguments = parse_qs_bytes(body, keep_blank_values=True) |
| 1020 | except Exception as e: |
| 1021 | raise HTTPInputError("Invalid x-www-form-urlencoded body: %s" % e) from e |
| 1022 | for name, values in uri_arguments.items(): |
| 1023 | if values: |
| 1024 | arguments.setdefault(name, []).extend(values) |
| 1025 | elif content_type.startswith("multipart/form-data"): |
| 1026 | if headers and "Content-Encoding" in headers: |
| 1027 | raise HTTPInputError( |
| 1028 | "Unsupported Content-Encoding: %s" % headers["Content-Encoding"] |
| 1029 | ) |
| 1030 | try: |
| 1031 | fields = content_type.split(";") |
| 1032 | if fields[0].strip() != "multipart/form-data": |
| 1033 | # This catches "Content-Type: multipart/form-dataxyz" |
| 1034 | raise HTTPInputError("Invalid content type") |
| 1035 | for field in fields: |
| 1036 | k, sep, v = field.strip().partition("=") |
| 1037 | if k == "boundary" and v: |
| 1038 | parse_multipart_form_data( |
| 1039 | utf8(v), body, arguments, files, config=config.multipart |
| 1040 | ) |
| 1041 | break |
| 1042 | else: |
| 1043 | raise HTTPInputError("multipart boundary not found") |
| 1044 | except Exception as e: |
| 1045 | raise HTTPInputError("Invalid multipart/form-data: %s" % e) from e |
| 1046 | |
| 1047 | |
| 1048 | def parse_multipart_form_data( |
no test coverage detected