// // ======================================================================== // Copyright (c) 1995-2017 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 static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.StringReader; import java.io.StringWriter; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.Connector; 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.server.ServerConnector; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; /** * Testing oddball request scenarios (like error 400) where the error should * be logged */ @RunWith(Parameterized.class) @Ignore public class BadRequestLogHandlerTest { private static final Logger LOG = Log.getLogger(BadRequestLogHandlerTest.class); public static class CaptureLog extends AbstractLifeCycle implements RequestLog { public List<String> captured = new ArrayList<>(); @Override public void log(Request request, Response response) { int status = response.getCommittedMetaData().getStatus(); captured.add(String.format("%s %s %s %03d",request.getMethod(),request.getHttpURI(),request.getProtocol(),status)); } } private static class HelloHandler extends AbstractHandler { @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/plain"); response.getWriter().print("Hello World"); baseRequest.setHandled(true); } } @Parameters public static List<Object[]> data() { List<Object[]> data = new ArrayList<>(); data.add(new String[]{ "GET /bad VER\r\n" + "Host: localhost\r\n" + "Connection: close\r\n\r\n" , "GET <invalidrequest> HTTP/1.1 400" }); data.add(new String[]{ "GET /%%adsasd HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: close\r\n\r\n" , "GET <invalidrequest> HTTP/1.1 400" }); return data; } @Parameter(0) public String requestHeader; @Parameter(1) public String expectedLog; @Test(timeout=4000) public void testLogHandler() throws Exception { Server server = new Server(); ServerConnector connector = new ServerConnector(server); connector.setPort(0); server.setConnectors(new Connector[] { connector }); CaptureLog captureLog = new CaptureLog(); RequestLogHandler requestLog = new RequestLogHandler(); requestLog.setRequestLog(captureLog); requestLog.setHandler(new HelloHandler()); server.setHandler(requestLog); try { server.start(); String host = connector.getHost(); if (host == null) { host = "localhost"; } InetAddress destAddr = InetAddress.getByName(host); int port = connector.getLocalPort(); SocketAddress endpoint = new InetSocketAddress(destAddr,port); Socket socket = new Socket(); socket.setSoTimeout(1000); socket.connect(endpoint); try(OutputStream out = socket.getOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(out,StandardCharsets.UTF_8); InputStream in = socket.getInputStream(); InputStreamReader reader = new InputStreamReader(in,StandardCharsets.UTF_8)) { StringReader request = new StringReader(requestHeader); IO.copy(request,writer); writer.flush(); StringWriter response = new StringWriter(); IO.copy(reader,response); LOG.info("Response: {}",response); } finally { socket.close(); } assertRequestLog(captureLog); } finally { server.stop(); } } private void assertRequestLog(CaptureLog captureLog) { int captureCount = captureLog.captured.size(); if (captureCount != 1) { LOG.warn("Capture Log size is {}, expected to be 1",captureCount); if (captureCount > 1) { for (int i = 0; i < captureCount; i++) { LOG.warn("[{}] {}",i,captureLog.captured.get(i)); } } assertThat("Capture Log Entry Count",captureLog.captured.size(),is(1)); } String actual = captureLog.captured.get(0); assertThat("Capture Log",actual,is(expectedLog)); } }