summaryrefslogtreecommitdiffstats
path: root/container-core
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@vespa.ai>2023-11-17 10:48:11 +0100
committerBjørn Christian Seime <bjorncs@vespa.ai>2023-11-17 10:48:11 +0100
commit50c6735bca827a49aa1b2e552d5e9f45903c2d4b (patch)
tree10126d2e339b9a00fa0cac3891a6feb1fe0dad79 /container-core
parent91692155c1f63492ef8d57b35105a5ade375a6ba (diff)
Fail immediately when `Content-Length` is present
Diffstat (limited to 'container-core')
-rw-r--r--container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletRequestReader.java21
-rw-r--r--container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java14
2 files changed, 28 insertions, 7 deletions
diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletRequestReader.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletRequestReader.java
index a022d208d05..9fee54dd1d4 100644
--- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletRequestReader.java
+++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletRequestReader.java
@@ -1,7 +1,6 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.jdisc.http.server.jetty;
-import com.yahoo.jdisc.Response;
import com.yahoo.jdisc.handler.CompletionHandler;
import com.yahoo.jdisc.handler.ContentChannel;
import com.yahoo.jdisc.http.ConnectorConfig;
@@ -19,6 +18,8 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
+import static com.yahoo.jdisc.Response.Status.REQUEST_TOO_LONG;
+
/**
* Finished when either
* 1) There was an error
@@ -111,7 +112,8 @@ class ServletRequestReader {
long maxContentSize = resolveMaxContentSize(cfg);
var msgTemplate = resolveMaxContentSizeErrorMessage(cfg);
this.requestContentChannel = maxContentSize >= 0
- ? new ByteLimitedContentChannel(Objects.requireNonNull(requestContentChannel), maxContentSize, msgTemplate)
+ ? new ByteLimitedContentChannel(
+ Objects.requireNonNull(requestContentChannel), maxContentSize, msgTemplate, req.getContentLengthLong())
: Objects.requireNonNull(requestContentChannel);
this.janitor = Objects.requireNonNull(janitor);
this.metricReporter = Objects.requireNonNull(metricReporter);
@@ -285,24 +287,29 @@ class ServletRequestReader {
private static class ByteLimitedContentChannel implements ContentChannel {
private final long maxContentSize;
private final String messageTemplate;
+ private final long contentLengthHeader;
private final AtomicLong bytesWritten = new AtomicLong();
private final ContentChannel delegate;
- ByteLimitedContentChannel(ContentChannel delegate, long maxContentSize, String messageTemplate) {
+ ByteLimitedContentChannel(ContentChannel delegate, long maxContentSize, String messageTemplate, long contentLengthHeader) {
this.delegate = delegate;
this.maxContentSize = maxContentSize;
this.messageTemplate = messageTemplate;
+ this.contentLengthHeader = contentLengthHeader;
}
@Override
public void write(ByteBuffer buf, CompletionHandler handler) {
long written = bytesWritten.addAndGet(buf.remaining());
- if (written > maxContentSize) {
+ if (contentLengthHeader != -1 && contentLengthHeader > maxContentSize) {
handler.failed(new RequestException(
- Response.Status.REQUEST_TOO_LONG, messageTemplate.formatted(written, maxContentSize)));
- return;
+ REQUEST_TOO_LONG, messageTemplate.formatted(contentLengthHeader, maxContentSize)));
+ } else if (written > maxContentSize) {
+ handler.failed(new RequestException(
+ REQUEST_TOO_LONG, messageTemplate.formatted(written, maxContentSize)));
+ } else {
+ delegate.write(buf, handler);
}
- delegate.write(buf, handler);
}
@Override public void close(CompletionHandler h) { delegate.close(h); }
diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java
index 6e218a6ab66..adb35db8ebf 100644
--- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java
+++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java
@@ -160,6 +160,20 @@ public class HttpServerTest {
}
@Test
+ void requireThatTooLargePayloadFailsWith413() throws Exception {
+ final JettyTestDriver driver = JettyTestDriver.newConfiguredInstance(
+ new EchoRequestHandler(),
+ new ServerConfig.Builder(),
+ new ConnectorConfig.Builder()
+ .maxContentSize(100));
+ driver.client().newPost("/status.html")
+ .setBinaryContent(new byte[200])
+ .execute()
+ .expectStatusCode(is(REQUEST_TOO_LONG));
+ assertTrue(driver.close());
+ }
+
+ @Test
void requireThatMultipleHostHeadersReturns400() throws Exception {
var metricConsumer = new MetricConsumerMock();
JettyTestDriver driver = JettyTestDriver.newConfiguredInstance(