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.
+