diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResourceParameter.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResourceParameter.java index 73665fd9150..ec964a4cc0c 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResourceParameter.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/ResourceParameter.java @@ -157,9 +157,6 @@ public class ResourceParameter implements IParameter { } } if (isBlank(ctValue)) { - /* - * If the client didn't send a content type, try to guess - */ String body; try { body = IOUtils.toString(requestReader); @@ -170,12 +167,9 @@ public class ResourceParameter implements IParameter { if (isBlank(body)) { return null; } - encoding = EncodingEnum.detectEncodingNoDefault(body); - if (encoding == null) { - String msg = ctx.getLocalizer().getMessage(ResourceParameter.class, "noContentTypeInRequest", restOperationType); - throw new InvalidRequestException(msg); - } - requestReader = new InputStreamReader(new ByteArrayInputStream(theRequest.loadRequestContents()), charset); + + String msg = ctx.getLocalizer().getMessage(ResourceParameter.class, "noContentTypeInRequest", restOperationType); + throw new InvalidRequestException(msg); } else { String msg = ctx.getLocalizer().getMessage(ResourceParameter.class, "invalidContentTypeInRequest", ctValue, restOperationType); throw new InvalidRequestException(msg); diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CreateR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CreateR4Test.java index d949ac99dee..a2fcf4c1259 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CreateR4Test.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CreateR4Test.java @@ -77,6 +77,23 @@ public class CreateR4Test { } + @Test + public void testCreateFailsIfNoContentTypeProvided() throws Exception { + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity("{\"resourceType\":\"Patient\", \"id\":\"999\", \"status\":\"active\"}", (ContentType) null)); + try (CloseableHttpResponse status = ourClient.execute(httpPost)) { + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(400, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("No Content-Type header was provided in the request. This is required for \\\"CREATE\\\" operation")); + + } + } + /** * #472 */ diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/OperationGenericServer2R4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/OperationGenericServer2R4Test.java index 79a25080d06..d618fe85a45 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/OperationGenericServer2R4Test.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/OperationGenericServer2R4Test.java @@ -232,9 +232,9 @@ public class OperationGenericServer2R4Test { HttpGet httpPost = new HttpGet("http://localhost:" + myPort + "/Patient/123/$OP_INSTANCE"); try (CloseableHttpResponse status = ourClient.execute(httpPost)) { - assertEquals(200, status.getStatusLine().getStatusCode()); String response = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info(response); + assertEquals(200, status.getStatusLine().getStatusCode()); status.getEntity().getContent().close(); assertEquals("123", ourLastId.getIdPart()); diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 0b8341c4de2..af872a8c8df 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -110,6 +110,13 @@ A note has been added to the downloads page explaning the removal of the hapi-fhir-utilities module. Thanks to Andrew Fitzgerald for the PR! + + REST servers will no longer try to guess the content type for HTTP requests where a body + is provided but no Content-Type header is included. These requests are invalid, and will now + result in an HTTP 400. This change corrects an error where some interceptors (notably + the RequestValidatingInterceptor, but not including any HAPI FHIR security interceptors) + could be bypassed if a Content Type was not included. +