From 311c08200ae7ef83f74fb4ed0833372b9eab6583 Mon Sep 17 00:00:00 2001 From: Robert Elliot Date: Thu, 16 Jan 2025 15:02:53 +0000 Subject: [PATCH] Handle multiple headers with the same name Pushes the fixes in https://github.com/dropwizard/dropwizard/pull/8008 upstream into logback-access, where they probably should be. Unfortunately `HttpGetUtil` uses `HttpURLConnection`, which makes it hard to write a test for this because `HttpURLConnection` combines the headers for you. --- .../qos/logback/access/jetty/HeaderUtil.java | 27 +++++++++++++++++++ .../access/jetty/JettyServerAdapter.java | 18 +++---------- .../logback/access/jetty/RequestWrapper.java | 10 ++----- 3 files changed, 32 insertions(+), 23 deletions(-) create mode 100644 logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/HeaderUtil.java diff --git a/logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/HeaderUtil.java b/logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/HeaderUtil.java new file mode 100644 index 0000000..d041f0f --- /dev/null +++ b/logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/HeaderUtil.java @@ -0,0 +1,27 @@ +package ch.qos.logback.access.jetty; + +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; + +import java.util.Map; +import java.util.TreeMap; + +class HeaderUtil { + static Map buildHeaderMap(HttpFields headers) { + Map requestHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + for (HttpField f : headers) { + String existing = requestHeaderMap.get(f.getName()); + String value = combine(existing, f.getValue()); + requestHeaderMap.put(f.getName(), value); + } + return requestHeaderMap; + } + + private static String combine(String existing, String field) { + if (existing == null) { + return field; + } else { + return existing + "," + field; + } + } +} diff --git a/logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java b/logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java index ff47d63..fa301d6 100644 --- a/logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java +++ b/logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/JettyServerAdapter.java @@ -14,16 +14,13 @@ package ch.qos.logback.access.jetty; import ch.qos.logback.access.common.spi.ServerAdapter; - -import org.eclipse.jetty.http.HttpField; -import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; -import java.util.Enumeration; -import java.util.HashMap; import java.util.Map; +import static ch.qos.logback.access.jetty.HeaderUtil.buildHeaderMap; + /** * A jetty specific implementation of the {@link ServerAdapter} interface. * @@ -57,16 +54,7 @@ public long getRequestTimestamp() { @Override public Map buildResponseHeaderMap() { - Map responseHeaderMap = new HashMap(); - HttpFields.Mutable httpFields = response.getHeaders(); - - for(HttpField field: httpFields) { - String key = field.getName(); - String value = field.getValue(); - responseHeaderMap.put(key, value); - } - - return responseHeaderMap; + return buildHeaderMap(response.getHeaders()); } } diff --git a/logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/RequestWrapper.java b/logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/RequestWrapper.java index f404dcf..1e36b0f 100644 --- a/logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/RequestWrapper.java +++ b/logback-access-jetty12/src/main/java/ch/qos/logback/access/jetty/RequestWrapper.java @@ -17,9 +17,7 @@ import jakarta.servlet.http.HttpUpgradeHandler; import jakarta.servlet.http.Part; import org.eclipse.jetty.http.HttpCookie; -import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpScheme; -import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Session; @@ -37,10 +35,10 @@ import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.TreeMap; import java.util.stream.Collectors; import static ch.qos.logback.access.common.spi.IAccessEvent.NA; +import static ch.qos.logback.access.jetty.HeaderUtil.buildHeaderMap; import static java.nio.charset.StandardCharsets.UTF_8; public class RequestWrapper implements HttpServletRequest, WrappedHttpRequest { @@ -92,11 +90,7 @@ public Enumeration getHeaderNames() { @Override public Map buildRequestHeaderMap() { - Map requestHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - for (HttpField f : request.getHeaders()) { - requestHeaderMap.put(f.getName(), f.getValue()); - } - return requestHeaderMap; + return buildHeaderMap(request.getHeaders()); } @Override