aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjonmv <venstad@gmail.com>2024-05-22 10:33:14 +0200
committerjonmv <venstad@gmail.com>2024-05-22 10:33:14 +0200
commit16a95dd84218e8bed8321798dcd06d31789dd008 (patch)
treec58c18e963610d3c93b409d36c65a5b4b20fdccb
parent656362675b248edaecfb12baec704bea384de451 (diff)
Override to 400 and 408 when client EoFs or times out
-rw-r--r--container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLog.java3
-rw-r--r--container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/HttpRequestDispatch.java7
-rw-r--r--container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java19
-rw-r--r--container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JettyMockResponseBuilder.java11
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;
}