diff options
Diffstat (limited to 'container-core/src/main/java/com')
-rw-r--r-- | container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java | 5 | ||||
-rw-r--r-- | container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ServletRequestReader.java | 37 |
2 files changed, 38 insertions, 4 deletions
diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java index e1ec22bd622..af98e380f2a 100644 --- a/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java +++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.container.jdisc.state; +import ai.vespa.metrics.ContainerMetrics; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -289,7 +290,7 @@ public class StateHandler extends AbstractRequestHandler implements CapabilityRe Tuple latencySeconds = new Tuple(NULL_DIMENSIONS, "latencySeconds", null); for (Map.Entry<MetricDimensions, MetricSet> entry : snapshot) { MetricSet metricSet = entry.getValue(); - MetricValue val = metricSet.get("serverTotalSuccessfulResponseLatency"); + MetricValue val = metricSet.get(ContainerMetrics.SERVER_TOTAL_SUCCESFUL_RESPONSE_LATENCY.baseName()); if (val instanceof GaugeMetric gauge) { latencySeconds.add(GaugeMetric.newInstance(gauge.getLast() / 1000, gauge.getMax() / 1000, @@ -297,7 +298,7 @@ public class StateHandler extends AbstractRequestHandler implements CapabilityRe gauge.getSum() / 1000, gauge.getCount())); } - requestsPerSecond.add(metricSet.get("serverNumSuccessfulResponses")); + requestsPerSecond.add(metricSet.get(ContainerMetrics.SERVER_NUM_SUCCESSFUL_RESPONSES.baseName())); } List<Tuple> lst = new ArrayList<>(); if (requestsPerSecond.val != null) { 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 2f2c48e0b48..75ef655c60c 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,16 +1,19 @@ // Copyright Yahoo. 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 jakarta.servlet.ReadListener; import jakarta.servlet.ServletInputStream; import jakarta.servlet.http.HttpServletRequest; +import org.eclipse.jetty.server.Request; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Objects; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import java.util.logging.Logger; @@ -33,6 +36,7 @@ import java.util.logging.Logger; */ class ServletRequestReader { + private enum State { NOT_STARTED, READING, ALL_DATA_READ, REQUEST_CONTENT_CLOSED } @@ -96,12 +100,15 @@ class ServletRequestReader { private final CompletableFuture<Void> finishedFuture = new CompletableFuture<>(); ServletRequestReader( - HttpServletRequest req, + Request req, ContentChannel requestContentChannel, Janitor janitor, RequestMetricReporter metricReporter) { this.req = Objects.requireNonNull(req); - this.requestContentChannel = Objects.requireNonNull(requestContentChannel); + long maxContentSize = RequestUtils.getConnector(req).connectorConfig().maxContentSize(); + this.requestContentChannel = maxContentSize >= 0 + ? new ByteLimitedContentChannel(Objects.requireNonNull(requestContentChannel), maxContentSize) + : Objects.requireNonNull(requestContentChannel); this.janitor = Objects.requireNonNull(janitor); this.metricReporter = Objects.requireNonNull(metricReporter); } @@ -259,4 +266,30 @@ class ServletRequestReader { } } + private static class ByteLimitedContentChannel implements ContentChannel { + private final long maxContentSize; + private final AtomicLong bytesWritten = new AtomicLong(); + private final ContentChannel delegate; + + ByteLimitedContentChannel(ContentChannel delegate, long maxContentSize) { + this.delegate = delegate; + this.maxContentSize = maxContentSize; + } + + @Override + public void write(ByteBuffer buf, CompletionHandler handler) { + long written = bytesWritten.addAndGet(buf.remaining()); + if (written > maxContentSize) { + handler.failed(new RequestException( + Response.Status.REQUEST_TOO_LONG, + "Request content length %d exceeds limit of %d bytes".formatted(written, maxContentSize))); + return; + } + delegate.write(buf, handler); + } + + @Override public void close(CompletionHandler h) { delegate.close(h); } + @Override public void onError(Throwable t) { delegate.onError(t); } + } + } |