From ee7d2dadf9ac25fbb24c8f17dc1cc514c621dc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20Nie=C3=9Fing?= Date: Fri, 2 Sep 2022 13:48:19 +0200 Subject: [PATCH] Fix request log on Jetty 10.0.x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Steffen Nießing --- .../jetty/JettyModernServerAdapter.java | 19 +++++++++++++- .../logback/access/jetty/RequestLogImpl.java | 25 ++++++++++++++++--- .../logback/access/jetty/JettyBasicTest.java | 1 + 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyModernServerAdapter.java b/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyModernServerAdapter.java index 58971ee565..505aabc054 100644 --- a/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyModernServerAdapter.java +++ b/logback-access/src/main/java/ch/qos/logback/access/jetty/JettyModernServerAdapter.java @@ -13,6 +13,8 @@ */ package ch.qos.logback.access.jetty; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -30,7 +32,15 @@ * @author Joakim Erdfelt */ public class JettyModernServerAdapter extends JettyServerAdapter { + private static final Method RESPONSE_GET_HTTP_FIELDS; + static { + try { + RESPONSE_GET_HTTP_FIELDS = Response.class.getDeclaredMethod("getHttpFields"); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } public JettyModernServerAdapter(Request jettyRequest, Response jettyResponse) { super(jettyRequest, jettyResponse); @@ -52,9 +62,16 @@ public long getRequestTimestamp() { } @Override + @SuppressWarnings("unchecked") public Map buildResponseHeaderMap() { Map responseHeaderMap = new HashMap(); - Iterator httpFieldIter = response.getHttpFields().iterator(); + Iterable httpFields; + try { + httpFields = (Iterable) RESPONSE_GET_HTTP_FIELDS.invoke(response); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + Iterator httpFieldIter = httpFields.iterator(); while (httpFieldIter.hasNext()) { HttpField httpField = httpFieldIter.next(); String key = httpField.getName(); diff --git a/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java b/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java index acb9aa67a9..bd934bea3a 100644 --- a/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java +++ b/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java @@ -15,6 +15,7 @@ import java.io.File; import java.net.URL; +import java.util.EventListener; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -65,6 +66,14 @@ * even bad requests, and context-less requests. *

*

+ * Note: + * Jetty 9.4.x and Jetty 10.0.x don't have equal method signatures for all methods. E.g. the return type for + * {@code Response#getHttpFields()} changed from {@code HttpFields} to {@code HttpFields.Mutable}. + * To properly support Jetty 9.4.x and Jetty 10.0.x reflection is used to resolve the correct method. + * If this is too slow for an application, the {@link #makeJettyServerAdapter(Request, Response)} method can be used + * to override the {@link JettyServerAdapter} implementation. + *

+ *

* The internals of the Jetty Request and Response objects track the state of the object at the time * they are committed (the actual state during the application when an action on the network commits the * request/response exchange). This prevents behaviors from 3rd party libraries @@ -244,7 +253,7 @@ enum State { String resource; // Jetty 9.4.x and newer is considered modern. - boolean modernJettyRequestLog; + protected boolean modernJettyRequestLog; boolean quiet = false; public RequestLogImpl() { @@ -269,7 +278,7 @@ public void log(Request jettyRequest, Response jettyResponse) { aai.appendLoopOnAppenders(accessEvent); } - private JettyServerAdapter makeJettyServerAdapter(Request jettyRequest, Response jettyResponse) { + protected JettyServerAdapter makeJettyServerAdapter(Request jettyRequest, Response jettyResponse) { if (modernJettyRequestLog) { return new JettyModernServerAdapter(jettyRequest, jettyResponse); } else { @@ -467,13 +476,21 @@ public FilterReply getFilterChainDecision(IAccessEvent event) { } - @Override public void addLifeCycleListener(LifeCycle.Listener listener) { // we'll implement this when asked } - @Override public void removeLifeCycleListener(LifeCycle.Listener listener) { // we'll implement this when asked } + + public boolean addEventListener(EventListener eventListener) { + // we'll implement this when asked + return false; + } + + public boolean removeEventListener(EventListener eventListener) { + // we'll implement this when asked + return false; + } } diff --git a/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java b/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java index eb4b559635..c6a718ac01 100644 --- a/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java +++ b/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyBasicTest.java @@ -83,6 +83,7 @@ public void eventGoesToAppenders() throws Exception { assertEquals("127.0.0.1", event.getRemoteHost()); assertEquals("localhost", event.getServerName()); + assertEquals("text/plain;charset=utf-8", event.getResponseHeader("Content-Type")); listAppender.list.clear(); }