Re-enable RequestLog tests.

Re-implemented features that were commented out.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2022-10-12 17:46:49 +02:00
parent 48c085d082
commit 557696653d
No known key found for this signature in database
GPG Key ID: 1677D141BCF3584D
7 changed files with 714 additions and 594 deletions

View File

@ -37,6 +37,7 @@ import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.resource.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -318,11 +319,13 @@ import static java.lang.invoke.MethodType.methodType;
@ManagedObject("Custom format request log")
public class CustomRequestLog extends ContainerLifeCycle implements RequestLog
{
protected static final Logger LOG = LoggerFactory.getLogger(CustomRequestLog.class);
public static final String DEFAULT_DATE_FORMAT = "dd/MMM/yyyy:HH:mm:ss ZZZ";
public static final String NCSA_FORMAT = "%{client}a - %u %t \"%r\" %s %O";
public static final String EXTENDED_NCSA_FORMAT = NCSA_FORMAT + " \"%{Referer}i\" \"%{User-Agent}i\"";
public static final String HANDLER_NAME = CustomRequestLog.class.getName() + ".handlerName";
public static final String REAL_PATH = CustomRequestLog.class.getName() + ".realPath";
public static final String USER_NAME = CustomRequestLog.class.getName() + ".userPrincipal";
private static final Logger LOG = LoggerFactory.getLogger(CustomRequestLog.class);
private static final ThreadLocal<StringBuilder> _buffers = ThreadLocal.withInitial(() -> new StringBuilder(256));
private final RequestLog.Writer _requestLogWriter;
@ -379,11 +382,6 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog
return _requestLogWriter;
}
/**
* Writes the request and response information to the output stream.
*
* @see org.eclipse.jetty.server.RequestLog#log(Request, Response)
*/
@Override
public void log(Request request, Response response)
{
@ -409,27 +407,6 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog
}
}
/**
* Extract the user authentication
*
* @param request The request to extract from
* @param checkDeferred Whether to check for deferred authentication
* @return The string to log for authenticated user.
*/
protected static String getAuthentication(Request request, boolean checkDeferred)
{
// TODO
// Authentication authentication = request.getAuthentication();
// if (checkDeferred && authentication instanceof Authentication.Deferred)
// authentication = ((Authentication.Deferred)authentication).authenticate(request);
String name = null;
// if (authentication instanceof Authentication.User)
// name = ((Authentication.User)authentication).getUserIdentity().getUserPrincipal().getName();
//
return name;
}
/**
* Set request paths that will not be logged.
*
@ -1046,8 +1023,7 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog
@SuppressWarnings("unused")
private static void logResponseSize(StringBuilder b, Request request, Response response)
{
long written = Response.getContentBytesWritten(response);
b.append(written);
b.append(Response.getContentBytesWritten(response));
}
@SuppressWarnings("unused")
@ -1123,7 +1099,6 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog
}
}
}
b.append('-');
}
@ -1132,7 +1107,9 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog
{
List<HttpCookie> cookies = Request.getCookies(request);
if (cookies == null || cookies.size() == 0)
{
b.append('-');
}
else
{
for (int i = 0; i < cookies.size(); i++)
@ -1155,17 +1132,25 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog
@SuppressWarnings("unused")
private static void logFilename(StringBuilder b, Request request, Response response)
{
b.append('-');
// TODO UserIdentity.Scope scope = request.getUserIdentityScope();
// if (scope == null || scope.getContextHandler() == null)
// b.append('-');
// else
// {
// ContextHandler context = scope.getContextHandler();
// int lengthToStrip = scope.getContextPath().length() > 1 ? scope.getContextPath().length() : 0;
// String filename = context.getServletContext().getRealPath(request.getPathInfo().substring(lengthToStrip));
// append(b, filename);
// }
String realPath = (String)request.getAttribute(REAL_PATH);
if (realPath == null)
{
Context context = request.getContext();
Resource baseResource = context.getBaseResource();
if (baseResource != null)
{
String fileName = baseResource.resolve(request.getPathInContext()).getName();
append(b, fileName);
}
else
{
b.append("-");
}
}
else
{
b.append(realPath);
}
}
@SuppressWarnings("unused")
@ -1221,8 +1206,7 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog
@SuppressWarnings("unused")
private static void logRequestHandler(StringBuilder b, Request request, Response response)
{
b.append('-');
// TODO append(b, request.getServletName());
append(b, (String)request.getAttribute(HANDLER_NAME));
}
@SuppressWarnings("unused")
@ -1242,39 +1226,38 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog
@SuppressWarnings("unused")
private static void logLatencyMicroseconds(StringBuilder b, Request request, Response response)
{
long currentTime = System.currentTimeMillis();
long requestTime = request.getTimeStamp();
long latencyMs = currentTime - requestTime;
long latencyUs = TimeUnit.MILLISECONDS.toMicros(latencyMs);
b.append(latencyUs);
logLatency(b, request, TimeUnit.MICROSECONDS);
}
@SuppressWarnings("unused")
private static void logLatencyMilliseconds(StringBuilder b, Request request, Response response)
{
long latency = System.currentTimeMillis() - request.getTimeStamp();
b.append(latency);
logLatency(b, request, TimeUnit.MILLISECONDS);
}
@SuppressWarnings("unused")
private static void logLatencySeconds(StringBuilder b, Request request, Response response)
{
logLatency(b, request, TimeUnit.SECONDS);
}
private static void logLatency(StringBuilder b, Request request, TimeUnit unit)
{
long latency = System.currentTimeMillis() - request.getTimeStamp();
b.append(TimeUnit.MILLISECONDS.toSeconds(latency));
b.append(unit.convert(latency, TimeUnit.MILLISECONDS));
}
@SuppressWarnings("unused")
private static void logRequestAuthentication(StringBuilder b, Request request, Response response)
{
append(b, getAuthentication(request, false));
append(b, (String)request.getAttribute(USER_NAME));
}
@SuppressWarnings("unused")
private static void logRequestAuthenticationWithDeferred(StringBuilder b, Request request, Response response)
{
append(b, getAuthentication(request, true));
// TODO: deferred to be implemented.
logRequestAuthentication(b, request, response);
}
@SuppressWarnings("unused")

View File

@ -29,8 +29,8 @@ import java.util.function.Consumer;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.http.HttpServletRequest;
import org.eclipse.jetty.ee10.servlet.ServletRequestState.Action;
import org.eclipse.jetty.ee10.servlet.security.Authentication;
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
@ -41,6 +41,7 @@ import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.QuietException;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.CustomRequestLog;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
@ -781,14 +782,27 @@ public class ServletChannel implements Runnable
public void onCompleted()
{
HttpServletRequest httpServletRequest = _request.getHttpServletRequest();
ServletContextRequest.ServletApiRequest apiRequest = _request.getServletApiRequest();
if (LOG.isDebugEnabled())
LOG.debug("onCompleted for {} written={}", httpServletRequest.getRequestURI(), getBytesWritten());
LOG.debug("onCompleted for {} written={}", apiRequest.getRequestURI(), getBytesWritten());
long idleTO = _configuration.getIdleTimeout();
if (idleTO >= 0 && getIdleTimeout() != _oldIdleTimeout)
setIdleTimeout(_oldIdleTimeout);
if (getServer().getRequestLog() != null)
{
Authentication authentication = apiRequest.getAuthentication();
if (authentication instanceof Authentication.User userAuthentication)
_request.setAttribute(CustomRequestLog.USER_NAME, userAuthentication.getUserIdentity().getUserPrincipal().getName());
String realPath = apiRequest.getServletContext().getRealPath(_request.getPathInContext());
_request.setAttribute(CustomRequestLog.REAL_PATH, realPath);
String servletName = _request.getServletName();
_request.setAttribute(CustomRequestLog.HANDLER_NAME, servletName);
}
// Callback will either be succeeded here or failed in abort().
if (_state.completeResponse())
_callback.succeeded();

View File

@ -1,141 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee10.servlet;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.CustomRequestLog;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.BlockingArrayQueue;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
@Disabled
public class CustomRequestLogServletTest
{
RequestLog _log;
Server _server;
LocalConnector _connector;
BlockingQueue<String> _entries = new BlockingArrayQueue<>();
String _tmpDir;
@BeforeEach
public void before() throws Exception
{
_server = new Server();
_connector = new LocalConnector(_server);
_server.addConnector(_connector);
_tmpDir = new File(System.getProperty("java.io.tmpdir")).getCanonicalPath();
}
void testHandlerServerStart(String formatString) throws Exception
{
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/context");
context.setBaseResource(Paths.get(_tmpDir));
context.addServlet(TestServlet.class, "/servlet/*");
TestRequestLogWriter writer = new TestRequestLogWriter();
_log = new CustomRequestLog(writer, formatString);
_server.setRequestLog(_log);
_server.setHandler(context);
_server.start();
}
@AfterEach
public void after() throws Exception
{
_server.stop();
}
@Test
public void testLogFilename() throws Exception
{
testHandlerServerStart("Filename: %f");
_connector.getResponse("GET /context/servlet/info HTTP/1.0\n\n");
String log = _entries.poll(5, TimeUnit.SECONDS);
String expected = new File(_tmpDir + File.separator + "servlet" + File.separator + "info").getCanonicalPath();
assertThat(log, is("Filename: " + expected));
}
@Test
public void testLogRequestHandler() throws Exception
{
testHandlerServerStart("RequestHandler: %R");
_connector.getResponse("GET /context/servlet/ HTTP/1.0\n\n");
String log = _entries.poll(5, TimeUnit.SECONDS);
assertThat(log, Matchers.containsString("TestServlet"));
}
class TestRequestLogWriter implements RequestLog.Writer
{
@Override
public void write(String requestEntry)
{
try
{
_entries.add(requestEntry);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public static class TestServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
if (request.getRequestURI().contains("error404"))
{
response.setStatus(404);
}
else if (request.getRequestURI().contains("error301"))
{
response.setStatus(301);
}
else if (request.getHeader("echo") != null)
{
ServletOutputStream outputStream = response.getOutputStream();
outputStream.print(request.getHeader("echo"));
}
else if (request.getRequestURI().contains("responseHeaders"))
{
response.addHeader("Header1", "value1");
response.addHeader("Header2", "value2");
}
}
}
}

View File

@ -0,0 +1,158 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.ee10.servlet;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Base64;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.ee10.servlet.security.ConstraintMapping;
import org.eclipse.jetty.ee10.servlet.security.ConstraintSecurityHandler;
import org.eclipse.jetty.ee10.servlet.security.HashLoginService;
import org.eclipse.jetty.ee10.servlet.security.UserStore;
import org.eclipse.jetty.ee10.servlet.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.server.CustomRequestLog;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.BlockingArrayQueue;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.security.Credential;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class CustomRequestLogTest
{
private final BlockingQueue<String> _logs = new BlockingArrayQueue<>();
private Server _server;
private LocalConnector _connector;
private Path _tmpDir;
private void start(String formatString, HttpServlet servlet) throws Exception
{
_server = new Server();
_connector = new LocalConnector(_server);
_server.addConnector(_connector);
TestRequestLogWriter writer = new TestRequestLogWriter();
RequestLog requestLog = new CustomRequestLog(writer, formatString);
_server.setRequestLog(requestLog);
_tmpDir = Path.of(System.getProperty("java.io.tmpdir")).toRealPath();
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setBaseResource(_tmpDir);
context.setContextPath("/context");
context.addServlet(new ServletHolder(servlet), "/servlet/*");
HashLoginService loginService = new HashLoginService();
UserStore userStore = new UserStore();
userStore.addUser("username", Credential.getCredential("password"), new String[]{"user"});
loginService.setUserStore(userStore);
loginService.setName("realm");
Constraint constraint = new Constraint();
constraint.setName("auth");
constraint.setAuthenticate(true);
constraint.setRoles(new String[]{"**"});
ConstraintMapping mapping = new ConstraintMapping();
mapping.setPathSpec("/secure/*");
mapping.setConstraint(constraint);
ConstraintSecurityHandler security = new ConstraintSecurityHandler();
security.addConstraintMapping(mapping);
security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService);
context.setSecurityHandler(security);
_server.setHandler(context);
_server.start();
}
@AfterEach
public void after()
{
LifeCycle.stop(_server);
}
@Test
public void testLogFilename() throws Exception
{
start("Filename: %f", new SimpleServlet());
_connector.getResponse("GET /context/servlet/info HTTP/1.0\n\n");
String log = _logs.poll(5, TimeUnit.SECONDS);
String expected = new File(_tmpDir + File.separator + "servlet" + File.separator + "info").getCanonicalPath();
assertThat(log, is("Filename: " + expected));
}
@Test
public void testLogRequestHandler() throws Exception
{
start("RequestHandler: %R", new SimpleServlet());
_connector.getResponse("GET /context/servlet/ HTTP/1.0\n\n");
String log = _logs.poll(5, TimeUnit.SECONDS);
assertThat(log, Matchers.containsString(SimpleServlet.class.getSimpleName()));
}
@Test
public void testLogRemoteUser() throws Exception
{
String authHeader = HttpHeader.AUTHORIZATION + ": Basic " + Base64.getEncoder().encodeToString("username:password".getBytes());
start("%u", new SimpleServlet());
_connector.getResponse("GET /context/servlet/unsecure HTTP/1.0\n\n");
String log = _logs.poll(5, TimeUnit.SECONDS);
assertThat(log, is("-"));
_connector.getResponse("GET /context/servlet/secure HTTP/1.0\n" + authHeader + "\n\n");
log = _logs.poll(5, TimeUnit.SECONDS);
assertThat(log, is("username"));
}
private class TestRequestLogWriter implements RequestLog.Writer
{
@Override
public void write(String requestEntry)
{
_logs.add(requestEntry);
}
}
private static class SimpleServlet extends HttpServlet
{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// Trigger the authentication.
request.getRemoteUser();
}
}
}

View File

@ -50,6 +50,7 @@ import org.eclipse.jetty.io.QuietException;
import org.eclipse.jetty.server.AbstractConnector;
import org.eclipse.jetty.server.ConnectionMetaData;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.CustomRequestLog;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.BufferUtil;
@ -945,12 +946,25 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
public void onCompleted()
{
if (LOG.isDebugEnabled())
LOG.debug("onCompleted for {} written={}", getRequest().getRequestURI(), getBytesWritten());
LOG.debug("onCompleted for {} written={}", _request.getRequestURI(), getBytesWritten());
long idleTO = _configuration.getIdleTimeout();
if (idleTO >= 0 && getIdleTimeout() != _oldIdleTimeout)
setIdleTimeout(_oldIdleTimeout);
if (getServer().getRequestLog() != null)
{
Authentication authentication = _request.getAuthentication();
if (authentication instanceof Authentication.User userAuthentication)
_request.setAttribute(CustomRequestLog.USER_NAME, userAuthentication.getUserIdentity().getUserPrincipal().getName());
String realPath = _request.getServletContext().getRealPath(_request.getPathInContext());
_request.setAttribute(CustomRequestLog.REAL_PATH, realPath);
String servletName = _request.getServletName();
_request.setAttribute(CustomRequestLog.HANDLER_NAME, servletName);
}
_request.onCompleted();
_combinedListener.onComplete(_request);
Callback callback = _coreCallback;

View File

@ -15,73 +15,99 @@ package org.eclipse.jetty.ee9.servlet;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Base64;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.ee9.security.ConstraintMapping;
import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler;
import org.eclipse.jetty.ee9.security.HashLoginService;
import org.eclipse.jetty.ee9.security.UserStore;
import org.eclipse.jetty.ee9.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.server.CustomRequestLog;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.BlockingArrayQueue;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.security.Credential;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
@Disabled // TODO
public class CustomRequestLogTest
{
RequestLog _log;
Server _server;
LocalConnector _connector;
BlockingQueue<String> _entries = new BlockingArrayQueue<>();
String _tmpDir;
private final BlockingQueue<String> _logs = new BlockingArrayQueue<>();
private Server _server;
private LocalConnector _connector;
private Path _tmpDir;
@BeforeEach
public void before() throws Exception
private void start(String formatString, HttpServlet servlet) throws Exception
{
_server = new Server();
_connector = new LocalConnector(_server);
_server.addConnector(_connector);
_tmpDir = new File(System.getProperty("java.io.tmpdir")).getCanonicalPath();
}
void testHandlerServerStart(String formatString) throws Exception
{
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/context");
context.setResourceBase(_tmpDir);
context.addServlet(TestServlet.class, "/servlet/*");
TestRequestLogWriter writer = new TestRequestLogWriter();
_log = new CustomRequestLog(writer, formatString);
_server.setRequestLog(_log);
RequestLog requestLog = new CustomRequestLog(writer, formatString);
_server.setRequestLog(requestLog);
_tmpDir = Path.of(System.getProperty("java.io.tmpdir")).toRealPath();
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setBaseResource(_tmpDir);
context.setContextPath("/context");
context.addServlet(new ServletHolder(servlet), "/servlet/*");
HashLoginService loginService = new HashLoginService();
UserStore userStore = new UserStore();
userStore.addUser("username", Credential.getCredential("password"), new String[]{"user"});
loginService.setUserStore(userStore);
loginService.setName("realm");
Constraint constraint = new Constraint();
constraint.setName("auth");
constraint.setAuthenticate(true);
constraint.setRoles(new String[]{"**"});
ConstraintMapping mapping = new ConstraintMapping();
mapping.setPathSpec("/secure/*");
mapping.setConstraint(constraint);
ConstraintSecurityHandler security = new ConstraintSecurityHandler();
security.addConstraintMapping(mapping);
security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService);
context.setSecurityHandler(security);
_server.setHandler(context);
_server.start();
}
@AfterEach
public void after() throws Exception
public void after()
{
_server.stop();
LifeCycle.stop(_server);
}
@Test
public void testLogFilename() throws Exception
{
testHandlerServerStart("Filename: %f");
start("Filename: %f", new SimpleServlet());
_connector.getResponse("GET /context/servlet/info HTTP/1.0\n\n");
String log = _entries.poll(5, TimeUnit.SECONDS);
String log = _logs.poll(5, TimeUnit.SECONDS);
String expected = new File(_tmpDir + File.separator + "servlet" + File.separator + "info").getCanonicalPath();
assertThat(log, is("Filename: " + expected));
}
@ -89,52 +115,44 @@ public class CustomRequestLogTest
@Test
public void testLogRequestHandler() throws Exception
{
testHandlerServerStart("RequestHandler: %R");
start("RequestHandler: %R", new SimpleServlet());
_connector.getResponse("GET /context/servlet/ HTTP/1.0\n\n");
String log = _entries.poll(5, TimeUnit.SECONDS);
assertThat(log, Matchers.containsString("TestServlet"));
String log = _logs.poll(5, TimeUnit.SECONDS);
assertThat(log, Matchers.containsString(SimpleServlet.class.getSimpleName()));
}
class TestRequestLogWriter implements RequestLog.Writer
@Test
public void testLogRemoteUser() throws Exception
{
String authHeader = HttpHeader.AUTHORIZATION + ": Basic " + Base64.getEncoder().encodeToString("username:password".getBytes());
start("%u", new SimpleServlet());
_connector.getResponse("GET /context/servlet/unsecure HTTP/1.0\n\n");
String log = _logs.poll(5, TimeUnit.SECONDS);
assertThat(log, is("-"));
_connector.getResponse("GET /context/servlet/secure HTTP/1.0\n" + authHeader + "\n\n");
log = _logs.poll(5, TimeUnit.SECONDS);
assertThat(log, is("username"));
}
private class TestRequestLogWriter implements RequestLog.Writer
{
@Override
public void write(String requestEntry)
{
try
{
_entries.add(requestEntry);
}
catch (Exception e)
{
e.printStackTrace();
}
_logs.add(requestEntry);
}
}
public static class TestServlet extends HttpServlet
private static class SimpleServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
if (request.getRequestURI().contains("error404"))
{
response.setStatus(404);
}
else if (request.getRequestURI().contains("error301"))
{
response.setStatus(301);
}
else if (request.getHeader("echo") != null)
{
ServletOutputStream outputStream = response.getOutputStream();
outputStream.print(request.getHeader("echo"));
}
else if (request.getRequestURI().contains("responseHeaders"))
{
response.addHeader("Header1", "value1");
response.addHeader("Header2", "value2");
}
// Trigger the authentication.
request.getRemoteUser();
}
}
}