diff --git a/conf/server.xml b/conf/server.xml
index 1be01d58594b..7df34e0038eb 100644
--- a/conf/server.xml
+++ b/conf/server.xml
@@ -160,6 +160,9 @@
resourceName="UserDatabase"/>
+
+
+
diff --git a/java/org/apache/catalina/valves/LowerCaseHeadersValve.java b/java/org/apache/catalina/valves/LowerCaseHeadersValve.java
new file mode 100644
index 000000000000..dcc41a447604
--- /dev/null
+++ b/java/org/apache/catalina/valves/LowerCaseHeadersValve.java
@@ -0,0 +1,57 @@
+package org.apache.catalina.valves;
+
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.valves.ValveBase;
+import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.MimeHeaders;
+
+import javax.servlet.ServletException;
+import java.io.IOException;
+import java.util.*;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+public class LowerCaseHeadersValve extends ValveBase {
+ private static final Log log = LogFactory.getLog(LowerCaseHeadersValve.class);
+
+ @Override
+ public void invoke(org.apache.catalina.connector.Request request, Response response) throws IOException, ServletException {
+ log.debug("in");
+ // Access the Coyote request (Tomcat's internal request object)
+ org.apache.coyote.Request coyoteRequest = request.getCoyoteRequest();
+ MimeHeaders mimeHeaders = coyoteRequest.getMimeHeaders();
+
+ // Preserve original header names with case
+ Map> originalHeaders = new LinkedHashMap<>();
+
+ for (int i = 0; i < mimeHeaders.size(); i++) {
+ MessageBytes nameMessageBytes = mimeHeaders.getName(i);
+ MessageBytes valueMessageBytes = mimeHeaders.getValue(i);
+
+ String name = nameMessageBytes.toString();
+ String value = valueMessageBytes.toString();
+
+ if(log.isDebugEnabled()) {
+ log.debug("raw: "+name+": "+value);
+ }
+
+ originalHeaders.computeIfAbsent(name, k -> new ArrayList<>()).add(value);
+
+ nameMessageBytes.setString(name.toLowerCase());
+
+ if(log.isDebugEnabled()) {
+ name = nameMessageBytes.toString();
+ value = valueMessageBytes.toString();
+ log.debug("current: "+name+": "+value);
+ }
+ }
+
+ // Store headers in request attributes for downstream use
+ request.setAttribute("originalHeaders", originalHeaders);
+
+ // Continue pipeline
+ getNext().invoke(request, response);
+ }
+}
+
diff --git a/java/org/apache/coyote/http11/Http11InputBuffer.java b/java/org/apache/coyote/http11/Http11InputBuffer.java
index 9903301011a3..66eab7d781e4 100644
--- a/java/org/apache/coyote/http11/Http11InputBuffer.java
+++ b/java/org/apache/coyote/http11/Http11InputBuffer.java
@@ -906,11 +906,6 @@ private HeaderParseStatus parseHeader() throws IOException {
// skipLine() will handle the error
return skipLine(false);
}
-
- // chr is next byte of header name. Convert to lowercase.
- if (chr >= Constants.A && chr <= Constants.Z) {
- byteBuffer.put(pos, (byte) (chr - Constants.LC_OFFSET));
- }
}
// Skip the line and ignore the header