AccessLogRequestLog extends AbstractLifeCycle implements RequestLog { @Override public void log(Request request, Response response) { try { AccessLogEntry accessLogEntry = Optional.ofNullable(request.getAttribute(JDiscHttpServlet.ATTRIBUTE_NAME_ACCESS_LOG_ENTRY)) .map(AccessLogEntry.class::cast) .orElseGet(AccessLogEntry::new); accessLogEntry.setRawPath(request.getRequestURI()); String queryString = request.getQueryString(); if (queryString != null) { accessLogEntry.setRawQuery(queryString); } accessLogEntry.setUserAgent(request.getHeader("User-Agent")); accessLogEntry.setHttpMethod(request.getMethod()); accessLogEntry.setHostString(request.getHeader("Host")); accessLogEntry.setReferer(request.getHeader("Referer")); String peerAddress = request.getRemoteAddr(); accessLogEntry.setIpV4Address(peerAddress); accessLogEntry.setPeerAddress(peerAddress); String remoteAddress = getRemoteAddress(request); if (!Objects.equal(remoteAddress, peerAddress)) { accessLogEntry.setRemoteAddress(remoteAddress); } int peerPort = request.getRemotePort(); accessLogEntry.setPeerPort(peerPort); int remotePort = getRemotePort(request); if (remotePort != peerPort) { accessLogEntry.setRemotePort(remotePort); } accessLogEntry.setHttpVersion(request.getProtocol()); accessLogEntry.setScheme(request.getScheme()); accessLogEntry.setLocalPort(getConnectorLocalPort(request)); Principal principal = (Principal) request.getAttribute(ServletRequest.JDISC_REQUEST_PRINCIPAL); if (principal != null) { accessLogEntry.setUserPrincipal(principal); } X509Certificate[] clientCert = (X509Certificate[]) request.getAttribute(ServletRequest.SERVLET_REQUEST_X509CERT); if (clientCert != null && clientCert.length > 0) { accessLogEntry.setSslPrincipal(clientCert[0].getSubjectX500Principal()); } String sslSessionId = (String) request.getAttribute(ServletRequest.SERVLET_REQUEST_SSL_SESSION_ID); if (sslSessionId != null) { accessLogEntry.addKeyValue("ssl-session-id", sslSessionId); } String cipherSuite = (String) request.getAttribute(ServletRequest.SERVLET_REQUEST_CIPHER_SUITE); if (cipherSuite != null) { accessLogEntry.addKeyValue("cipher-suite", cipherSuite); } long startTime = request.getTimeStamp(); long endTime = System.currentTimeMillis(); accessLogEntry.setTimeStamp(startTime); accessLogEntry.setDurationBetweenRequestResponse(endTime - startTime); accessLogEntry.setReturnedContentSize(response.getHttpChannel().getBytesWritten()); accessLogEntry.setStatusCode(response.getCommittedMetaData().getStatus()); LOGGED_REQUEST_HEADERS.forEach(header -> { String value = request.getHeader(header); if (value != null) { accessLogEntry.addKeyValue(header, value); } }); accessLog.log(accessLogEntry); } catch (Exception e) { logger.log(Level.SEVERE, "Failed to log access log entry: " + e.getMessage(), e); } } AccessLogRequestLog(AccessLog accessLog); @Override void log(Request request, Response response);  }
@Test public void requireThatQueryWithUnquotedSpecialCharactersIsHandled() { final AccessLogEntry accessLogEntry = new AccessLogEntry(); final Request jettyRequest = createRequestMock(accessLogEntry); when(jettyRequest.getRequestURI()).thenReturn("/search/"); when(jettyRequest.getQueryString()).thenReturn("query=year:>2010"); new AccessLogRequestLog(mock(AccessLog.class)).log(jettyRequest, createResponseMock()); assertThat(accessLogEntry.getRawPath(), is(not(nullValue()))); assertTrue(accessLogEntry.getRawQuery().isPresent()); }
@Test public void requireThatDoubleQuotingIsNotPerformed() { final AccessLogEntry accessLogEntry = new AccessLogEntry(); final Request jettyRequest = createRequestMock(accessLogEntry); final String path = "/search/"; when(jettyRequest.getRequestURI()).thenReturn(path); final String query = "query=year%252010+%3B&customParameter=something"; when(jettyRequest.getQueryString()).thenReturn(query); new AccessLogRequestLog(mock(AccessLog.class)).log(jettyRequest, createResponseMock()); assertThat(accessLogEntry.getRawPath(), is(path)); assertThat(accessLogEntry.getRawQuery().get(), is(query)); }
@Test public void raw_path_and_query_are_set_from_request() { AccessLogEntry accessLogEntry = new AccessLogEntry(); Request jettyRequest = createRequestMock(accessLogEntry); String rawPath = " when(jettyRequest.getRequestURI()).thenReturn(rawPath); String rawQuery = "q=%%2"; when(jettyRequest.getQueryString()).thenReturn(rawQuery); new AccessLogRequestLog(mock(AccessLog.class)).log(jettyRequest, createResponseMock()); assertThat(accessLogEntry.getRawPath(), is(rawPath)); Optional<String> actualRawQuery = accessLogEntry.getRawQuery(); assertThat(actualRawQuery.isPresent(), is(true)); assertThat(actualRawQuery.get(), is(rawQuery)); }