diff --git a/connexion/utils.py b/connexion/utils.py index 5458ca85b..f97567b4d 100644 --- a/connexion/utils.py +++ b/connexion/utils.py @@ -158,7 +158,7 @@ def is_json_mimetype(mimetype): if mimetype is None: return False - maintype, subtype = mimetype.split("/") # type: str, str + maintype, subtype = mimetype.split("/", maxsplit=1) # type: str, str if ";" in subtype: subtype, parameter = subtype.split(";", maxsplit=1) return maintype == "application" and ( @@ -310,10 +310,8 @@ def extract_content_type( if decoded_key.lower() == "content-type": if isinstance(value, bytes): - content_type = value.decode("latin-1") - else: - content_type = value - break + value = value.decode("latin-1") + content_type = ",".join([content_type, value] if content_type else [value]) return content_type diff --git a/tests/test_json_validation.py b/tests/test_json_validation.py index aa9b0cf30..a51685450 100644 --- a/tests/test_json_validation.py +++ b/tests/test_json_validation.py @@ -175,3 +175,26 @@ class MyDefaultsJSONBodyValidator(DefaultsJSONRequestBodyValidator): ) assert res.status_code == 200 assert res.json().get("human") + + +def test_multiple_json_content_type(json_validation_spec_dir, spec): + """ensure that defaults applied that modify the body""" + + class MyDefaultsJSONBodyValidator(DefaultsJSONRequestBodyValidator): + pass + + validator_map = {"body": {"application/json": MyDefaultsJSONBodyValidator}} + + app = App(__name__, specification_dir=json_validation_spec_dir) + app.add_api(spec, validate_responses=True, validator_map=validator_map) + app_client = app.test_client() + + res = app_client.post( + "/v1.0/user", + data=json.dumps({"name": "foo"}), + headers={ + "content-type": "application/json", + "Content-Type": "application/json", + }, + ) + assert res.status_code == 415 diff --git a/tests/test_utils.py b/tests/test_utils.py index adfa1b115..26a8763bd 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -62,16 +62,29 @@ def test_deep_get_list(): assert utils.deep_get(obj, ["0", "properties", "id"]) == {"type": "string"} -def test_is_json_mimetype(): - assert utils.is_json_mimetype("application/json") - assert utils.is_json_mimetype("application/vnd.com.myEntreprise.v6+json") - assert utils.is_json_mimetype( - "application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0" - ) - assert utils.is_json_mimetype( - "application/vnd.com.myEntreprise.v6+json; charset=UTF-8" - ) - assert not utils.is_json_mimetype("text/html") +@pytest.mark.parametrize( + "mime_type", + [ + "application/json", + "application/vnd.com.myEntreprise.v6+json", + "application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0", + "application/vnd.com.myEntreprise.v6+json; charset=UTF-8", + ], +) +def test_is_json_mimetype_true(mime_type: str): + assert utils.is_json_mimetype(mime_type) + + +@pytest.mark.parametrize( + "mime_type", + [ + "application/json,application/json", + "text/html", + "text/json", + ], +) +def test_is_json_mimetype_false(mime_type: str): + assert not utils.is_json_mimetype(mime_type) def test_sort_routes():