From ed12c3f22a28e704c327c17dbd7acc063f8f3a81 Mon Sep 17 00:00:00 2001 From: Peter Nied Date: Tue, 21 Nov 2023 14:03:22 -0600 Subject: [PATCH] [Backport 2.x] Validate content type of responses (#3719) Makes sure that for response with a body they are returning the expected content type Signed-off-by: Peter Nied --- .../framework/cluster/TestRestClient.java | 41 +++++++++++++++++++ .../security/test/helper/rest/RestHelper.java | 28 ++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClient.java b/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClient.java index 3d8fe6686a..592c31d626 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClient.java +++ b/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClient.java @@ -48,6 +48,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import org.apache.commons.io.IOUtils; +<<<<<<< HEAD import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; @@ -66,6 +67,27 @@ import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.message.BasicHeader; +======= +import org.apache.hc.client5.http.classic.methods.HttpDelete; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpHead; +import org.apache.hc.client5.http.classic.methods.HttpOptions; +import org.apache.hc.client5.http.classic.methods.HttpPatch; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.classic.methods.HttpPut; +import org.apache.hc.client5.http.classic.methods.HttpUriRequest; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.routing.HttpRoutePlanner; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.io.entity.StringEntity; +import org.apache.hc.core5.http.message.BasicHeader; +import org.apache.hc.core5.net.URIBuilder; +import org.apache.http.HttpHeaders; +>>>>>>> c30c084b9 (Validate content type of responses (#3719)) import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -78,6 +100,7 @@ import static java.util.Objects.requireNonNull; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; /** @@ -294,6 +317,24 @@ public HttpResponse(CloseableHttpResponse inner) throws IllegalStateException, I this.statusCode = inner.getStatusLine().getStatusCode(); this.statusReason = inner.getStatusLine().getReasonPhrase(); inner.close(); + + if (this.body.length() != 0) { + verifyContentType(); + } + } + + private void verifyContentType() { + final String contentType = this.getHeader(HttpHeaders.CONTENT_TYPE).getValue(); + if (contentType.contains("application/json")) { + assertThat("Response body format was not json, body: " + body, body.charAt(0), equalTo('{')); + } else { + assertThat( + "Response body format was json, whereas content-type was " + contentType + ", body: " + body, + body.charAt(0), + not(equalTo('{')) + ); + } + } public String getContentType() { diff --git a/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java b/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java index 065c72afeb..f9986c9733 100644 --- a/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java +++ b/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java @@ -76,6 +76,10 @@ import org.opensearch.security.test.helper.cluster.ClusterInfo; import org.opensearch.security.test.helper.file.FileHelper; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; + public class RestHelper { protected final Logger log = LogManager.getLogger(RestHelper.class); @@ -313,7 +317,29 @@ public HttpResponse(CloseableHttpResponse inner) throws IllegalStateException, I this.header = inner.getAllHeaders(); this.statusCode = inner.getStatusLine().getStatusCode(); this.statusReason = inner.getStatusLine().getReasonPhrase(); - inner.close(); + + if (this.body.length() != 0) { + verifyBodyContentType(); + } + } + + private void verifyBodyContentType() { + final String contentType = this.getHeaders() + .stream() + .filter(h -> HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(h.getName())) + .map(Header::getValue) + .findFirst() + .orElseThrow(() -> new RuntimeException("No content type found. Headers:\n" + getHeaders() + "\n\nBody:\n" + body)); + + if (contentType.contains("application/json")) { + assertThat("Response body format was not json, body: " + body, body.charAt(0), equalTo('{')); + } else { + assertThat( + "Response body format was json, whereas content-type was " + contentType + ", body: " + body, + body.charAt(0), + not(equalTo('{')) + ); + } } public String getContentType() {