This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 5b9021e43f Fix inconsistencies with special headers and getHeader
5b9021e43f is described below

commit 5b9021e43f27440243b6c82e540aedf6e29a9041
Author: remm <[email protected]>
AuthorDate: Wed Mar 4 00:15:20 2026 +0100

    Fix inconsistencies with special headers and getHeader
    
    Handling of Content-Type and Content-Length with getHeader,
    getHeaderNames and getHeaders.
    BZ69967
---
 java/org/apache/catalina/connector/Response.java   | 51 +++++++++++++++++++++-
 .../apache/catalina/connector/TestResponse.java    | 18 ++++++++
 webapps/docs/changelog.xml                         |  9 ++++
 3 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/catalina/connector/Response.java 
b/java/org/apache/catalina/connector/Response.java
index fa4e12c56f..7e4f5380dc 100644
--- a/java/org/apache/catalina/connector/Response.java
+++ b/java/org/apache/catalina/connector/Response.java
@@ -33,6 +33,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
@@ -790,6 +791,23 @@ public class Response implements HttpServletResponse {
 
     @Override
     public String getHeader(String name) {
+        // Need special handling for Content-Type and Content-Length due to
+        // special handling of these in coyoteResponse
+        char cc = name.charAt(0);
+        if (cc == 'C' || cc == 'c') {
+            if (name.equalsIgnoreCase("Content-Type")) {
+                // Will return null if this has not been set
+                return getCoyoteResponse().getContentType();
+            }
+            if (name.equalsIgnoreCase("Content-Length")) {
+                // -1 means not known and is not sent to client
+                if (getCoyoteResponse().getContentLengthLong() != -1) {
+                    return 
String.valueOf(getCoyoteResponse().getContentLengthLong());
+                } else {
+                    return null;
+                }
+            }
+        }
         return getCoyoteResponse().getMimeHeaders().getHeader(name);
     }
 
@@ -802,13 +820,44 @@ public class Response implements HttpServletResponse {
         for (int i = 0; i < n; i++) {
             result.add(headers.getName(i).toString());
         }
+        if (getCoyoteResponse().getContentType() != null) {
+            result.add("Content-Type");
+        }
+        if (getCoyoteResponse().getContentLengthLong() != -1) {
+            result.add("Content-Length");
+        }
         return result;
-
     }
 
 
     @Override
     public Collection<String> getHeaders(String name) {
+        // Need special handling for Content-Type and Content-Length due to
+        // special handling of these in coyoteResponse
+        char cc = name.charAt(0);
+        if (cc == 'C' || cc == 'c') {
+            if (name.equalsIgnoreCase("Content-Type")) {
+                // Will return null if this has not been set
+                String contentType = getCoyoteResponse().getContentType();
+                if (contentType != null) {
+                    Set<String> result = new HashSet<>();
+                    result.add(contentType);
+                    return result;
+                } else {
+                    return new HashSet<>();
+                }
+            }
+            if (name.equalsIgnoreCase("Content-Length")) {
+                // -1 means not known and is not sent to client
+                if (getCoyoteResponse().getContentLengthLong() != -1) {
+                    Set<String> result = new HashSet<>();
+                    
result.add(String.valueOf(getCoyoteResponse().getContentLengthLong()));
+                    return result;
+                } else {
+                    return new HashSet<>();
+                }
+            }
+        }
         Enumeration<String> enumeration = 
getCoyoteResponse().getMimeHeaders().values(name);
         Set<String> result = new LinkedHashSet<>();
         while (enumeration.hasMoreElements()) {
diff --git a/test/org/apache/catalina/connector/TestResponse.java 
b/test/org/apache/catalina/connector/TestResponse.java
index 90bc48c141..e092980999 100644
--- a/test/org/apache/catalina/connector/TestResponse.java
+++ b/test/org/apache/catalina/connector/TestResponse.java
@@ -738,6 +738,24 @@ public class TestResponse extends TomcatBaseTest {
     }
 
 
+    @Test
+    public void testSetContentLengthHeader() {
+        Response response = setupResponse();
+
+        response.setContentLength(10);
+        Assert.assertEquals("10", response.getHeader("Content-Length"));
+    }
+
+
+    @Test
+    public void testSetContentTypeHeader() {
+        Response response = setupResponse();
+
+        response.setContentType(TEXT_UTF_8);
+        Assert.assertEquals(TEXT_UTF_8, response.getHeader("Content-Type"));
+    }
+
+
     @Test
     public void testSetContentType01() {
         Response response = setupResponse();
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 66e4747709..b7b39075e6 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -105,6 +105,15 @@
   issues do not "pop up" wrt. others).
 -->
 <section name="Tomcat 9.0.116 (remm)" rtext="in development">
+  <subsection name="Catalina">
+    <changelog>
+      <fix>
+        <bug>69967</bug>: Fix inconsistencies related to
+        <code>Content-Length</code> and <code>Content-Type</code> headers when
+        accessed using the <code>getHeader</code> method and similar. (remm)
+      </fix>
+    </changelog>
+  </subsection>
   <subsection name="Coyote">
     <changelog>
       <fix>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to