aboutsummaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorMorten Tokle <mortent@verizonmedia.com>2021-05-20 15:42:13 +0200
committerMorten Tokle <mortent@verizonmedia.com>2021-05-20 16:06:53 +0200
commit156c15e72404e9ffec6ffdb2103d151e5a528705 (patch)
tree71aad894694f049b24748a813b662d401c87b948 /configserver
parent864eb3da782e9795826ec78add953a76eeb2ea17 (diff)
Parse content type header
Diffstat (limited to 'configserver')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationApiHandler.java5
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandler.java12
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java34
3 files changed, 42 insertions, 9 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationApiHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationApiHandler.java
index 8bc792a179d..5b520b10fcf 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationApiHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationApiHandler.java
@@ -16,6 +16,8 @@ import com.yahoo.vespa.config.server.http.SessionHandler;
import com.yahoo.vespa.config.server.http.Utils;
import com.yahoo.vespa.config.server.session.PrepareParams;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
+import com.yahoo.vespa.model.content.Content;
+import org.apache.hc.core5.http.ContentType;
import org.eclipse.jetty.http.MultiPartFormInputStream;
import javax.servlet.http.Part;
@@ -70,7 +72,8 @@ public class ApplicationApiHandler extends SessionHandler {
PrepareParams prepareParams;
CompressedApplicationInputStream compressedStream;
boolean multipartRequest = Optional.ofNullable(request.getHeader(HttpHeaders.Names.CONTENT_TYPE))
- .map(val -> val.equalsIgnoreCase(MULTIPART_FORM_DATA))
+ .map(ContentType::parse)
+ .map(contentType -> contentType.getMimeType().equalsIgnoreCase(MULTIPART_FORM_DATA))
.orElse(false);
if(multipartRequest) {
try {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandler.java
index a3e82c51dfa..61f099fb8ea 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandler.java
@@ -9,6 +9,7 @@ import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.container.jdisc.HttpResponse;
+import com.yahoo.jdisc.HeaderFields;
import com.yahoo.jdisc.application.UriPattern;
import com.yahoo.vespa.config.server.ApplicationRepository;
import com.yahoo.vespa.config.server.deploy.DeployHandlerLogger;
@@ -16,6 +17,8 @@ import com.yahoo.vespa.config.server.TimeoutBudget;
import com.yahoo.vespa.config.server.http.BadRequestException;
import com.yahoo.vespa.config.server.http.SessionHandler;
import com.yahoo.vespa.config.server.http.Utils;
+import com.yahoo.vespa.model.content.Content;
+import org.apache.hc.core5.http.ContentType;
import java.net.URI;
import java.time.Duration;
@@ -93,9 +96,12 @@ public class SessionCreateHandler extends SessionHandler {
String header = request.getHeader(ApplicationApiHandler.contentTypeHeader);
if (header == null) {
throw new BadRequestException("Request contains no " + ApplicationApiHandler.contentTypeHeader + " header");
- } else if (!supportedContentTypes.contains(header)) {
- throw new BadRequestException("Request contains invalid " + ApplicationApiHandler.contentTypeHeader + " header, only '["
- + String.join(", ", supportedContentTypes) + "' are supported");
+ } else {
+ ContentType contentType = ContentType.parse(header);
+ if (!supportedContentTypes.contains(contentType.getMimeType())) {
+ throw new BadRequestException("Request contains invalid " + ApplicationApiHandler.contentTypeHeader + " header (" + contentType.getMimeType() + "), only '["
+ + String.join(", ", supportedContentTypes) + "]' are supported");
+ }
}
}
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java
index 83d6ac5b288..5d7322070e7 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java
@@ -16,19 +16,24 @@ import com.yahoo.vespa.config.server.http.SessionHandlerTest;
import com.yahoo.vespa.config.server.session.Session;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.config.server.tenant.TestTenantRepository;
+import org.apache.hc.core5.http.ContentType;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import static com.yahoo.jdisc.Response.Status.BAD_REQUEST;
@@ -43,6 +48,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
* @author hmusum
@@ -171,6 +177,22 @@ public class SessionCreateHandlerTest extends SessionHandlerTest {
assertIllegalFromParameter("http://host:4013/application/v2/tenant/" + tenant + "/application/foo/environment/prod/region/baz/instance");
}
+ @Test
+ public void require_that_content_type_is_parsed_correctly() throws FileNotFoundException {
+ HttpRequest request = post(new ByteArrayInputStream("foo".getBytes(StandardCharsets.UTF_8)),
+ Map.of("Content-Type", "multipart/form-data; charset=ISO-8859-1; boundary=g5gJAzUWl_t6"),
+ Collections.emptyMap());
+
+ // Valid header should validate ok
+ SessionCreateHandler.validateDataAndHeader(request, List.of(ContentType.MULTIPART_FORM_DATA.getMimeType()));
+
+ // Accepting only application/json should fail:
+ try {
+ SessionCreateHandler.validateDataAndHeader(request, List.of(ContentType.APPLICATION_JSON.getMimeType()));
+ fail("Request contained invalid content type, but validated ok");
+ } catch (Exception expected) {}
+ }
+
private SessionCreateHandler createHandler() {
return new SessionCreateHandler(SessionCreateHandler.testOnlyContext(),
applicationRepository,
@@ -178,7 +200,7 @@ public class SessionCreateHandlerTest extends SessionHandlerTest {
}
private HttpRequest post() throws FileNotFoundException {
- return post(null, postHeaders, new HashMap<>());
+ return post((InputStream) null, postHeaders, new HashMap<>());
}
private HttpRequest post(File file) throws FileNotFoundException {
@@ -186,10 +208,12 @@ public class SessionCreateHandlerTest extends SessionHandlerTest {
}
private HttpRequest post(File file, Map<String, String> headers, Map<String, String> parameters) throws FileNotFoundException {
+ return post(file == null ? null : new FileInputStream(file), headers, parameters);
+ }
+
+ private HttpRequest post(InputStream data, Map <String, String > headers, Map < String, String > parameters) throws FileNotFoundException {
HttpRequest request = HttpRequest.createTestRequest("http://" + hostname + ":" + port + "/application/v2/tenant/" + tenant + "/session",
- POST,
- file == null ? null : new FileInputStream(file),
- parameters);
+ POST, data, parameters);
for (Map.Entry<String, String> entry : headers.entrySet()) {
request.getJDiscRequest().headers().put(entry.getKey(), entry.getValue());
}
@@ -197,6 +221,6 @@ public class SessionCreateHandlerTest extends SessionHandlerTest {
}
private HttpRequest post(Map<String, String> parameters) throws FileNotFoundException {
- return post(null, new HashMap<>(), parameters);
+ return post((InputStream) null, new HashMap<>(), parameters);
}
}