diff options
author | jonmv <venstad@gmail.com> | 2024-05-22 10:33:14 +0200 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2024-05-22 10:33:14 +0200 |
commit | 16a95dd84218e8bed8321798dcd06d31789dd008 (patch) | |
tree | c58c18e963610d3c93b409d36c65a5b4b20fdccb | |
parent | 656362675b248edaecfb12baec704bea384de451 (diff) |
Override to 400 and 408 when client EoFs or times out
4 files changed, 36 insertions, 4 deletions
diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java index ccb41ca3055..94678c5ab3a 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java @@ -57,6 +57,7 @@ class AccessLogRequestLog extends AbstractLifeCycle implements org.eclipse.jetty int peerPort = request.getRemotePort(); long startTime = request.getTimeStamp(); long endTime = System.currentTimeMillis(); + Integer statusCodeOverride = (Integer) request.getAttribute(HttpRequestDispatch.STATUS_CODE_OVERRIDE); builder.peerAddress(peerAddress) .peerPort(peerPort) .localPort(getLocalPort(request)) @@ -64,7 +65,7 @@ class AccessLogRequestLog extends AbstractLifeCycle implements org.eclipse.jetty .duration(Duration.ofMillis(Math.max(0, endTime - startTime))) .responseSize(response.getHttpChannel().getBytesWritten()) .requestSize(request.getHttpInput().getContentReceived()) - .statusCode(response.getCommittedMetaData().getStatus()); + .statusCode(statusCodeOverride != null ? statusCodeOverride : response.getCommittedMetaData().getStatus()); addNonNullValue(builder, request.getMethod(), RequestLogEntry.Builder::httpMethod); addNonNullValue(builder, request.getRequestURI(), RequestLogEntry.Builder::rawPath); diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java index a2c2a5df4df..0ec01496cda 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java @@ -42,9 +42,10 @@ import static com.yahoo.jdisc.http.server.jetty.RequestUtils.getConnector; */ class HttpRequestDispatch { - private static final Logger log = Logger.getLogger(HttpRequestDispatch.class.getName()); + public static final String STATUS_CODE_OVERRIDE = "com.yahoo.jdisc.http.server.jetty.STATUS_CODE_OVERRIDE"; - private final static String CHARSET_ANNOTATION = ";charset="; + private static final Logger log = Logger.getLogger(HttpRequestDispatch.class.getName()); + private static final String CHARSET_ANNOTATION = ";charset="; private final JDiscContext jDiscContext; private final Request jettyRequest; @@ -129,10 +130,12 @@ class HttpRequestDispatch { error, () -> "Network connection was unexpectedly terminated: " + jettyRequest.getRequestURI()); metricReporter.prematurelyClosed(); + asyncCtx.getRequest().setAttribute(STATUS_CODE_OVERRIDE, 400); } else if (isErrorOfType(error, TimeoutException.class)) { log.log(Level.FINE, error, () -> "Request/stream was timed out by Jetty: " + jettyRequest.getRequestURI()); + asyncCtx.getRequest().setAttribute(STATUS_CODE_OVERRIDE, 408); } else if (!isErrorOfType(error, OverloadException.class, BindingNotFoundException.class, RequestException.class)) { log.log(Level.WARNING, "Request failed: " + jettyRequest.getRequestURI(), error); } diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java index e4c8c86d93e..6787829a48a 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java @@ -15,6 +15,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -23,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; * @author bjorncs */ public class AccessLogRequestLogTest { + @Test void requireThatQueryWithUnquotedSpecialCharactersIsHandled() { Request jettyRequest = createRequestBuilder() @@ -37,6 +39,22 @@ public class AccessLogRequestLogTest { assertTrue(entry.rawQuery().isPresent()); } + + @Test + void requireThatStatusCodeCanBeOverridden() { + Request jettyRequest = createRequestBuilder() + .uri("http", "localhost", 12345, "/api/", null) + .build(); + + InMemoryRequestLog requestLog = new InMemoryRequestLog(); + new AccessLogRequestLog(requestLog).log(jettyRequest, JettyMockResponseBuilder.newBuilder().build()); + assertEquals(200, requestLog.entries().remove(0).statusCode().getAsInt()); + + jettyRequest.setAttribute(HttpRequestDispatch.STATUS_CODE_OVERRIDE, 404); + new AccessLogRequestLog(requestLog).log(jettyRequest, JettyMockResponseBuilder.newBuilder().build()); + assertEquals(404, requestLog.entries().remove(0).statusCode().getAsInt()); + } + @Test void requireThatDoubleQuotingIsNotPerformed() { String path = "/search/"; @@ -129,4 +147,5 @@ public class AccessLogRequestLogTest { private Response createResponseMock() { return JettyMockResponseBuilder.newBuilder().build(); } + } diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JettyMockResponseBuilder.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JettyMockResponseBuilder.java index efdc9eab283..e83c446b96d 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JettyMockResponseBuilder.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JettyMockResponseBuilder.java @@ -15,14 +15,23 @@ import static org.mockito.Mockito.when; */ public class JettyMockResponseBuilder { + private int statusCode = 200; + private JettyMockResponseBuilder() {} public static JettyMockResponseBuilder newBuilder() { return new JettyMockResponseBuilder(); } + public JettyMockResponseBuilder withStatusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + public Response build() { + MetaData.Response metaData = mock(MetaData.Response.class); + when(metaData.getStatus()).thenReturn(statusCode); Response response = mock(Response.class); when(response.getHttpChannel()).thenReturn(mock(HttpChannel.class)); - when(response.getCommittedMetaData()).thenReturn(mock(MetaData.Response.class)); + when(response.getCommittedMetaData()).thenReturn(metaData); return response; } |