aboutsummaryrefslogtreecommitdiffstats
path: root/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java')
-rw-r--r--container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java156
1 files changed, 156 insertions, 0 deletions
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
new file mode 100644
index 00000000000..6370912af48
--- /dev/null
+++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/AccessLogRequestLogTest.java
@@ -0,0 +1,156 @@
+// Copyright 2017 Yahoo Holdings. 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.container.logging.AccessLogEntry;
+import com.yahoo.container.logging.RequestLog;
+import com.yahoo.container.logging.RequestLogEntry;
+import com.yahoo.jdisc.http.ConnectorConfig;
+import com.yahoo.jdisc.http.ServerConfig;
+import org.eclipse.jetty.http.MetaData;
+import org.eclipse.jetty.server.HttpChannel;
+import org.eclipse.jetty.server.HttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Optional;
+
+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.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author Oyvind Bakksjo
+ * @author bjorncs
+ */
+public class AccessLogRequestLogTest {
+ @Test
+ public void requireThatQueryWithUnquotedSpecialCharactersIsHandled() {
+ final Request jettyRequest = createRequestMock();
+ when(jettyRequest.getRequestURI()).thenReturn("/search/");
+ when(jettyRequest.getQueryString()).thenReturn("query=year:>2010");
+
+ InMemoryRequestLog requestLog = new InMemoryRequestLog();
+ doAccessLoggingOfRequest(requestLog, jettyRequest);
+ RequestLogEntry entry = requestLog.entries().get(0);
+
+ assertThat(entry.rawPath().get(), is(not(nullValue())));
+ assertTrue(entry.rawQuery().isPresent());
+ }
+
+ @Test
+ public void requireThatDoubleQuotingIsNotPerformed() {
+ final Request jettyRequest = createRequestMock();
+ final String path = "/search/";
+ when(jettyRequest.getRequestURI()).thenReturn(path);
+ final String query = "query=year%252010+%3B&customParameter=something";
+ when(jettyRequest.getQueryString()).thenReturn(query);
+
+ InMemoryRequestLog requestLog = new InMemoryRequestLog();
+ doAccessLoggingOfRequest(requestLog, jettyRequest);
+ RequestLogEntry entry = requestLog.entries().get(0);
+
+ assertThat(entry.rawPath().get(), is(path));
+ assertThat(entry.rawQuery().get(), is(query));
+
+ }
+
+ @Test
+ public void raw_path_and_query_are_set_from_request() {
+ Request jettyRequest = createRequestMock();
+ String rawPath = "//search/";
+ when(jettyRequest.getRequestURI()).thenReturn(rawPath);
+ String rawQuery = "q=%%2";
+ when(jettyRequest.getQueryString()).thenReturn(rawQuery);
+
+ InMemoryRequestLog requestLog = new InMemoryRequestLog();
+ doAccessLoggingOfRequest(requestLog, jettyRequest);
+ RequestLogEntry entry = requestLog.entries().get(0);
+ assertThat(entry.rawPath().get(), is(rawPath));
+ Optional<String> actualRawQuery = entry.rawQuery();
+ assertThat(actualRawQuery.isPresent(), is(true));
+ assertThat(actualRawQuery.get(), is(rawQuery));
+ }
+
+ @Test
+ public void verify_x_forwarded_for_precedence () {
+ Request jettyRequest = createRequestMock();
+ when(jettyRequest.getRequestURI()).thenReturn("//search/");
+ when(jettyRequest.getQueryString()).thenReturn("q=%%2");
+ when(jettyRequest.getHeader("x-forwarded-for")).thenReturn("1.2.3.4");
+ when(jettyRequest.getHeader("y-ra")).thenReturn("2.3.4.5");
+
+ InMemoryRequestLog requestLog = new InMemoryRequestLog();
+ doAccessLoggingOfRequest(requestLog, jettyRequest);
+ RequestLogEntry entry = requestLog.entries().get(0);
+ assertThat(entry.remoteAddress().get(), is("1.2.3.4"));
+ }
+
+ @Test
+ public void verify_x_forwarded_port_precedence () {
+ Request jettyRequest = createRequestMock();
+ when(jettyRequest.getRequestURI()).thenReturn("//search/");
+ when(jettyRequest.getQueryString()).thenReturn("q=%%2");
+ when(jettyRequest.getHeader("X-Forwarded-Port")).thenReturn("80");
+ when(jettyRequest.getHeader("y-rp")).thenReturn("8080");
+
+ InMemoryRequestLog requestLog = new InMemoryRequestLog();
+ doAccessLoggingOfRequest(requestLog, jettyRequest);
+ RequestLogEntry entry = requestLog.entries().get(0);
+ assertThat(entry.remotePort().getAsInt(), is(80));
+ }
+
+ @Test
+ public void defaults_to_peer_port_if_remote_port_header_is_invalid() {
+ final Request jettyRequest = createRequestMock();
+ when(jettyRequest.getRequestURI()).thenReturn("/search/");
+ when(jettyRequest.getHeader("X-Forwarded-Port")).thenReturn("8o8o");
+ when(jettyRequest.getRemotePort()).thenReturn(80);
+
+ InMemoryRequestLog requestLog = new InMemoryRequestLog();
+ doAccessLoggingOfRequest(requestLog, jettyRequest);
+ RequestLogEntry entry = requestLog.entries().get(0);
+ assertFalse(entry.remotePort().isPresent());
+ assertThat(entry.peerPort().getAsInt(), is(80));
+ }
+
+ private void doAccessLoggingOfRequest(RequestLog requestLog, Request jettyRequest) {
+ ServerConfig.AccessLog config = new ServerConfig.AccessLog(
+ new ServerConfig.AccessLog.Builder()
+ .remoteAddressHeaders(List.of("x-forwarded-for", "y-ra"))
+ .remotePortHeaders(List.of("X-Forwarded-Port", "y-rp")));
+ new AccessLogRequestLog(requestLog, config).log(jettyRequest, createResponseMock());
+ }
+
+ private static Request createRequestMock() {
+ JDiscServerConnector serverConnector = mock(JDiscServerConnector.class);
+ int localPort = 1234;
+ when(serverConnector.connectorConfig()).thenReturn(new ConnectorConfig(new ConnectorConfig.Builder().listenPort(localPort)));
+ when(serverConnector.getLocalPort()).thenReturn(localPort);
+ HttpConnection httpConnection = mock(HttpConnection.class);
+ when(httpConnection.getConnector()).thenReturn(serverConnector);
+ Request request = mock(Request.class);
+ when(request.getMethod()).thenReturn("GET");
+ when(request.getRemoteAddr()).thenReturn("localhost");
+ when(request.getRemotePort()).thenReturn(12345);
+ when(request.getProtocol()).thenReturn("HTTP/1.1");
+ when(request.getScheme()).thenReturn("http");
+ when(request.getTimeStamp()).thenReturn(0L);
+ when(request.getAttribute(JDiscHttpServlet.ATTRIBUTE_NAME_ACCESS_LOG_ENTRY)).thenReturn(new AccessLogEntry());
+ when(request.getAttribute("org.eclipse.jetty.server.HttpConnection")).thenReturn(httpConnection);
+ return request;
+ }
+
+ private Response createResponseMock() {
+ Response response = mock(Response.class);
+ when(response.getHttpChannel()).thenReturn(mock(HttpChannel.class));
+ when(response.getCommittedMetaData()).thenReturn(mock(MetaData.Response.class));
+ return response;
+ }
+}