Issue #113 - Parameterized RequestLogTest to test NCSA format string
renamed to NcsaRequestLogTest as is only testing NCSA log formats Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
e4d30b367c
commit
cc1ae54feb
|
@ -0,0 +1,863 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.BadMessageException;
|
||||
import org.eclipse.jetty.server.AbstractNCSARequestLog;
|
||||
import org.eclipse.jetty.server.CustomRequestLog;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.LocalConnector;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.RequestLog;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.BlockingArrayQueue;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
public class NcsaRequestLogTest
|
||||
{
|
||||
RequestLog _log;
|
||||
Server _server;
|
||||
LocalConnector _connector;
|
||||
BlockingQueue<String> _entries = new BlockingArrayQueue<>();
|
||||
|
||||
private void setup(String logType) throws Exception
|
||||
{
|
||||
TestRequestLogWriter writer = new TestRequestLogWriter();
|
||||
|
||||
switch (logType)
|
||||
{
|
||||
case "customNCSA":
|
||||
_log = new CustomRequestLog(writer, CustomRequestLog.NCSA_FORMAT);
|
||||
break;
|
||||
case "NCSA":
|
||||
{
|
||||
AbstractNCSARequestLog logNCSA = new AbstractNCSARequestLog(writer);
|
||||
logNCSA.setExtended(true);
|
||||
logNCSA.setLogLatency(true);
|
||||
logNCSA.setLogCookies(true);
|
||||
_log = logNCSA;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("invalid logType");
|
||||
}
|
||||
|
||||
_server = new Server();
|
||||
_connector = new LocalConnector(_server);
|
||||
_server.addConnector(_connector);
|
||||
}
|
||||
|
||||
void testHandlerServerStart() throws Exception
|
||||
{
|
||||
_server.setRequestLog(_log);
|
||||
_server.setHandler(new TestHandler());
|
||||
_server.start();
|
||||
}
|
||||
|
||||
private void startServer() throws Exception
|
||||
{
|
||||
_server.start();
|
||||
}
|
||||
|
||||
private void makeRequest(String requestPath) throws Exception
|
||||
{
|
||||
_connector.getResponse("GET "+requestPath+" HTTP/1.0\r\n\r\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@AfterEach
|
||||
public void after() throws Exception
|
||||
{
|
||||
_server.stop();
|
||||
}
|
||||
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testNotHandled(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("GET /foo HTTP/1.0\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET /foo HTTP/1.0\" 404 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testRequestLine(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("GET /foo?data=1 HTTP/1.0\nhost: host:80\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET /foo?data=1 HTTP/1.0\" 200 "));
|
||||
|
||||
_connector.getResponse("GET //bad/foo?data=1 HTTP/1.0\n\n");
|
||||
log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET //bad/foo?data=1 HTTP/1.0\" 200 "));
|
||||
|
||||
_connector.getResponse("GET http://host:80/foo?data=1 HTTP/1.0\n\n");
|
||||
log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET http://host:80/foo?data=1 HTTP/1.0\" 200 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testHTTP10Host(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse(
|
||||
"GET /foo?name=value HTTP/1.0\n"+
|
||||
"Host: servername\n"+
|
||||
"\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET /foo?name=value"));
|
||||
assertThat(log,containsString(" 200 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testHTTP11(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse(
|
||||
"GET /foo?name=value HTTP/1.1\n"+
|
||||
"Host: servername\n"+
|
||||
"\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET /foo?name=value"));
|
||||
assertThat(log,containsString(" 200 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testAbsolute(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse(
|
||||
"GET http://hostname:8888/foo?name=value HTTP/1.1\n"+
|
||||
"Host: servername\n"+
|
||||
"\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET http://hostname:8888/foo?name=value"));
|
||||
assertThat(log,containsString(" 200 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testQuery(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("GET /foo?name=value HTTP/1.0\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET /foo?name=value"));
|
||||
assertThat(log,containsString(" 200 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testSmallData(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("GET /foo?data=42 HTTP/1.0\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET /foo?"));
|
||||
assertThat(log,containsString(" 200 42 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testBigData(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("GET /foo?data=102400 HTTP/1.0\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET /foo?"));
|
||||
assertThat(log,containsString(" 200 102400 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testStatus(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("GET /foo?status=206 HTTP/1.0\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET /foo?"));
|
||||
assertThat(log,containsString(" 206 0 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testStatusData(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("GET /foo?status=206&data=42 HTTP/1.0\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET /foo?"));
|
||||
assertThat(log,containsString(" 206 42 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testBadRequest(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("XXXXXXXXXXXX\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("\"- - -\""));
|
||||
assertThat(log,containsString(" 400 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testBadCharacter(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("METHOD /f\00o HTTP/1.0\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("\"- - -\""));
|
||||
assertThat(log,containsString(" 400 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testBadVersion(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("METHOD /foo HTTP/9\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("\"- - -\""));
|
||||
assertThat(log,containsString(" 400 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testLongURI(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
char[] chars = new char[10000];
|
||||
Arrays.fill(chars,'o');
|
||||
String ooo = new String(chars);
|
||||
_connector.getResponse("METHOD /f"+ooo+" HTTP/1.0\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("\"- - -\""));
|
||||
assertThat(log,containsString(" 414 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testLongHeader(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
char[] chars = new char[10000];
|
||||
Arrays.fill(chars,'o');
|
||||
String ooo = new String(chars);
|
||||
_connector.getResponse("METHOD /foo HTTP/1.0\name: f+"+ooo+"\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("\"METHOD /foo HTTP/1.0\""));
|
||||
assertThat(log,containsString(" 431 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testBadRequestNoHost(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("GET /foo HTTP/1.1\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET /foo "));
|
||||
assertThat(log,containsString(" 400 "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testUseragentWithout(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("GET http://[:1]/foo HTTP/1.1\nReferer: http://other.site\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET http://[:1]/foo "));
|
||||
assertThat(log,containsString(" 400 50 \"http://other.site\" \"-\" - "));
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings = {"customNCSA", "NCSA"})
|
||||
public void testUseragentWith(String logType) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
testHandlerServerStart();
|
||||
|
||||
_connector.getResponse("GET http://[:1]/foo HTTP/1.1\nReferer: http://other.site\nUser-Agent: Mozilla/5.0 (test)\n\n");
|
||||
String log = _entries.poll(5,TimeUnit.SECONDS);
|
||||
assertThat(log,containsString("GET http://[:1]/foo "));
|
||||
assertThat(log,containsString(" 400 50 \"http://other.site\" \"Mozilla/5.0 (test)\" - "));
|
||||
}
|
||||
|
||||
|
||||
// Tests from here use these parameters
|
||||
public static Stream<Arguments> data()
|
||||
{
|
||||
List<Object[]> data = new ArrayList<>();
|
||||
|
||||
for(String logType : Arrays.asList("customNCSA","NCSA"))
|
||||
{
|
||||
data.add(new Object[]{logType, new NoopHandler(), "/noop", "\"GET /noop HTTP/1.0\" 404"});
|
||||
data.add(new Object[]{logType, new HelloHandler(), "/hello", "\"GET /hello HTTP/1.0\" 200"});
|
||||
data.add(new Object[]{logType, new ResponseSendErrorHandler(), "/sendError", "\"GET /sendError HTTP/1.0\" 599"});
|
||||
data.add(new Object[]{logType, new ServletExceptionHandler(), "/sex", "\"GET /sex HTTP/1.0\" 500"});
|
||||
data.add(new Object[]{logType, new IOExceptionHandler(), "/ioex", "\"GET /ioex HTTP/1.0\" 500"});
|
||||
data.add(new Object[]{logType, new IOExceptionPartialHandler(), "/ioex", "\"GET /ioex HTTP/1.0\" 200"});
|
||||
data.add(new Object[]{logType, new RuntimeExceptionHandler(), "/rtex", "\"GET /rtex HTTP/1.0\" 500"});
|
||||
data.add(new Object[]{logType, new BadMessageHandler(), "/bad", "\"GET /bad HTTP/1.0\" 499"});
|
||||
data.add(new Object[]{logType, new AbortHandler(), "/bad", "\"GET /bad HTTP/1.0\" 488"});
|
||||
data.add(new Object[]{logType, new AbortPartialHandler(), "/bad", "\"GET /bad HTTP/1.0\" 200"});
|
||||
}
|
||||
|
||||
return data.stream().map(Arguments::of);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testServerRequestLog(String logType, Handler testHandler, String requestPath, String expectedLogEntry) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
_server.setRequestLog(_log);
|
||||
_server.setHandler(testHandler);
|
||||
startServer();
|
||||
makeRequest(requestPath);
|
||||
assertRequestLog(expectedLogEntry, _log);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testLogHandlerWrapper(String logType, Handler testHandler, String requestPath, String expectedLogEntry) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
RequestLogHandler handler = new RequestLogHandler();
|
||||
handler.setRequestLog(_log);
|
||||
handler.setHandler(testHandler);
|
||||
_server.setHandler(handler);
|
||||
startServer();
|
||||
makeRequest(requestPath);
|
||||
assertRequestLog(expectedLogEntry, _log);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testLogHandlerCollectionFirst(String logType, Handler testHandler, String requestPath, String expectedLogEntry) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
RequestLogHandler handler = new RequestLogHandler();
|
||||
handler.setRequestLog(_log);
|
||||
HandlerCollection handlers = new HandlerCollection();
|
||||
handlers.setHandlers(new Handler[] { handler, testHandler });
|
||||
_server.setHandler(handlers);
|
||||
startServer();
|
||||
makeRequest(requestPath);
|
||||
assertRequestLog(expectedLogEntry, _log);
|
||||
}
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testLogHandlerCollectionLast(String logType, Handler testHandler, String requestPath, String expectedLogEntry) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
RequestLogHandler handler = new RequestLogHandler();
|
||||
handler.setRequestLog(_log);
|
||||
// This is the old ordering of request handler and it cannot well handle thrown exception
|
||||
Assumptions.assumeTrue(
|
||||
testHandler instanceof NoopHandler ||
|
||||
testHandler instanceof HelloHandler ||
|
||||
testHandler instanceof ResponseSendErrorHandler
|
||||
);
|
||||
|
||||
HandlerCollection handlers = new HandlerCollection();
|
||||
handlers.setHandlers(new Handler[] { testHandler, handler });
|
||||
_server.setHandler(handlers);
|
||||
startServer();
|
||||
makeRequest(requestPath);
|
||||
assertRequestLog(expectedLogEntry, _log);
|
||||
}
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testErrorHandler(String logType, Handler testHandler, String requestPath, String expectedLogEntry) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
_server.setRequestLog(_log);
|
||||
AbstractHandler.ErrorDispatchHandler wrapper = new AbstractHandler.ErrorDispatchHandler()
|
||||
{
|
||||
@Override
|
||||
protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
testHandler.handle(target,baseRequest,request,response);
|
||||
}
|
||||
};
|
||||
|
||||
_server.setHandler(wrapper);
|
||||
|
||||
List<String> errors = new ArrayList<>();
|
||||
ErrorHandler errorHandler = new ErrorHandler()
|
||||
{
|
||||
@Override
|
||||
public void doError(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
errors.add(baseRequest.getRequestURI());
|
||||
super.doError(target, baseRequest, request, response);
|
||||
}
|
||||
};
|
||||
_server.addBean(errorHandler);
|
||||
startServer();
|
||||
makeRequest(requestPath);
|
||||
assertRequestLog(expectedLogEntry, _log);
|
||||
|
||||
if (!(testHandler instanceof HelloHandler))
|
||||
assertThat(errors,contains(requestPath));
|
||||
}
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testOKErrorHandler(String logType, Handler testHandler, String requestPath, String expectedLogEntry) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
_server.setRequestLog(_log);
|
||||
AbstractHandler.ErrorDispatchHandler wrapper = new AbstractHandler.ErrorDispatchHandler()
|
||||
{
|
||||
@Override
|
||||
protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
testHandler.handle(target,baseRequest,request,response);
|
||||
}
|
||||
};
|
||||
|
||||
_server.setHandler(wrapper);
|
||||
|
||||
ErrorHandler errorHandler = new OKErrorHandler();
|
||||
_server.addBean(errorHandler);
|
||||
startServer();
|
||||
makeRequest(requestPath);
|
||||
|
||||
expectedLogEntry = "\"GET " + requestPath + " HTTP/1.0\" 200";
|
||||
assertRequestLog(expectedLogEntry, _log);
|
||||
}
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testAsyncDispatch(String logType, Handler testHandler, String requestPath, String expectedLogEntry) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
_server.setRequestLog(_log);
|
||||
_server.setHandler(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
if (Boolean.TRUE.equals(request.getAttribute("ASYNC")))
|
||||
testHandler.handle(target,baseRequest,request,response);
|
||||
else
|
||||
{
|
||||
request.setAttribute("ASYNC",Boolean.TRUE);
|
||||
AsyncContext ac = request.startAsync();
|
||||
ac.setTimeout(1000);
|
||||
ac.dispatch();
|
||||
baseRequest.setHandled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
startServer();
|
||||
makeRequest(requestPath);
|
||||
|
||||
assertRequestLog(expectedLogEntry, _log);
|
||||
}
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testAsyncComplete(String logType, Handler testHandler, String requestPath, String expectedLogEntry) throws Exception
|
||||
{
|
||||
setup(logType);
|
||||
_server.setRequestLog(_log);
|
||||
_server.setHandler(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
if (Boolean.TRUE.equals(request.getAttribute("ASYNC")))
|
||||
testHandler.handle(target,baseRequest,request,response);
|
||||
else
|
||||
{
|
||||
request.setAttribute("ASYNC",Boolean.TRUE);
|
||||
AsyncContext ac = request.startAsync();
|
||||
ac.setTimeout(1000);
|
||||
baseRequest.setHandled(true);
|
||||
_server.getThreadPool().execute(()->
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
baseRequest.setHandled(false);
|
||||
testHandler.handle(target, baseRequest, request, response);
|
||||
if (!baseRequest.isHandled())
|
||||
response.sendError(404);
|
||||
}
|
||||
catch (BadMessageException bad)
|
||||
{
|
||||
response.sendError(bad.getCode());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
response.sendError(500);
|
||||
}
|
||||
}
|
||||
catch(Throwable th)
|
||||
{
|
||||
throw new RuntimeException(th);
|
||||
}
|
||||
ac.complete();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
startServer();
|
||||
makeRequest(requestPath);
|
||||
assertRequestLog(expectedLogEntry, _log);
|
||||
}
|
||||
|
||||
|
||||
private void assertRequestLog(final String expectedLogEntry, RequestLog log) throws Exception
|
||||
{
|
||||
String line = _entries.poll(5, TimeUnit.SECONDS);
|
||||
Assertions.assertNotNull(line);
|
||||
assertThat(line,containsString(expectedLogEntry));
|
||||
Assertions.assertTrue(_entries.isEmpty());
|
||||
}
|
||||
|
||||
public static class CaptureLog extends AbstractLifeCycle implements RequestLog
|
||||
{
|
||||
public BlockingQueue<String> log = new BlockingArrayQueue<>();
|
||||
|
||||
@Override
|
||||
public void log(Request request, Response response)
|
||||
{
|
||||
int status = response.getCommittedMetaData().getStatus();
|
||||
log.add(String.format("%s %s %s %03d",request.getMethod(),request.getRequestURI(),request.getProtocol(),status));
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class AbstractTestHandler extends AbstractHandler
|
||||
{
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return this.getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class NoopHandler extends AbstractTestHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static class HelloHandler extends AbstractTestHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
response.setContentType("text/plain");
|
||||
response.getWriter().print("Hello World");
|
||||
if (baseRequest!=null)
|
||||
baseRequest.setHandled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ResponseSendErrorHandler extends AbstractTestHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
response.sendError(599,"expected");
|
||||
if (baseRequest!=null)
|
||||
baseRequest.setHandled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ServletExceptionHandler extends AbstractTestHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
throw new ServletException("expected");
|
||||
}
|
||||
}
|
||||
|
||||
private static class IOExceptionHandler extends AbstractTestHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
throw new IOException("expected");
|
||||
}
|
||||
}
|
||||
|
||||
private static class IOExceptionPartialHandler extends AbstractTestHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setContentType("text/plain");
|
||||
response.setContentLength(100);
|
||||
response.getOutputStream().println("You were expecting maybe a ");
|
||||
response.flushBuffer();
|
||||
throw new IOException("expected");
|
||||
}
|
||||
}
|
||||
|
||||
private static class RuntimeExceptionHandler extends AbstractTestHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
throw new RuntimeException("expected");
|
||||
}
|
||||
}
|
||||
|
||||
private static class BadMessageHandler extends AbstractTestHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
throw new BadMessageException(499);
|
||||
}
|
||||
}
|
||||
|
||||
private static class AbortHandler extends AbstractTestHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
BadMessageException bad = new BadMessageException(488);
|
||||
baseRequest.getHttpChannel().abort(bad);
|
||||
throw bad;
|
||||
}
|
||||
}
|
||||
|
||||
private static class AbortPartialHandler extends AbstractTestHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setContentType("text/plain");
|
||||
response.setContentLength(100);
|
||||
response.getOutputStream().println("You were expecting maybe a ");
|
||||
response.flushBuffer();
|
||||
baseRequest.getHttpChannel().abort(new Throwable("bomb"));
|
||||
}
|
||||
}
|
||||
|
||||
public static class OKErrorHandler extends ErrorHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
if (baseRequest.isHandled() || response.isCommitted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// collect error details
|
||||
String reason = (response instanceof Response)?((Response)response).getReason():null;
|
||||
int status = response.getStatus();
|
||||
|
||||
// intentionally set response status to OK (this is a test to see what is actually logged)
|
||||
response.setStatus(200);
|
||||
response.setContentType("text/plain");
|
||||
PrintWriter out = response.getWriter();
|
||||
out.printf("Error %d: %s%n",status,reason);
|
||||
baseRequest.setHandled(true);
|
||||
}
|
||||
}
|
||||
|
||||
class TestRequestLogWriter implements RequestLog.Writer
|
||||
{
|
||||
@Override
|
||||
public void write(String requestEntry)
|
||||
{
|
||||
try
|
||||
{
|
||||
_entries.add(requestEntry);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TestHandler extends AbstractHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
String q = request.getQueryString();
|
||||
if (q==null)
|
||||
return;
|
||||
|
||||
baseRequest.setHandled(true);
|
||||
for (String action : q.split("\\&"))
|
||||
{
|
||||
String[] param = action.split("=");
|
||||
String name=param[0];
|
||||
String value=param.length>1?param[1]:null;
|
||||
switch(name)
|
||||
{
|
||||
case "status":
|
||||
{
|
||||
response.setStatus(Integer.parseInt(value));
|
||||
break;
|
||||
}
|
||||
|
||||
case "data":
|
||||
{
|
||||
int data = Integer.parseInt(value);
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
int w=0;
|
||||
while (w<data)
|
||||
{
|
||||
if ((data-w)>17)
|
||||
{
|
||||
w+=17;
|
||||
out.print("0123456789ABCDEF\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
w++;
|
||||
out.print("\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "throw":
|
||||
{
|
||||
try
|
||||
{
|
||||
throw (Throwable)(Class.forName(value).getDeclaredConstructor().newInstance());
|
||||
}
|
||||
catch(ServletException | IOException | Error | RuntimeException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch(Throwable e)
|
||||
{
|
||||
throw new ServletException(e);
|
||||
}
|
||||
}
|
||||
case "flush":
|
||||
{
|
||||
response.flushBuffer();
|
||||
break;
|
||||
}
|
||||
|
||||
case "read":
|
||||
{
|
||||
InputStream in = request.getInputStream();
|
||||
while (in.read()>=0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue