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

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


The following commit(s) were added to refs/heads/11.0.x by this push:
     new a5bc1e4841 Add support for server and serverRemoveAppProvidedValues to 
h2
a5bc1e4841 is described below

commit a5bc1e484144f940e060381217c8b27772bdcfc2
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Sep 26 11:42:38 2024 +0100

    Add support for server and serverRemoveAppProvidedValues to h2
    
    These configuration properties are inherited from the parent HTTP/1.1
    connector.
---
 java/org/apache/coyote/http2/StreamProcessor.java  |  13 ++
 .../apache/coyote/http2/TestStreamProcessor.java   | 146 +++++++++++++++++++++
 webapps/docs/changelog.xml                         |   5 +
 webapps/docs/config/http2.xml                      |   2 +
 4 files changed, 166 insertions(+)

diff --git a/java/org/apache/coyote/http2/StreamProcessor.java 
b/java/org/apache/coyote/http2/StreamProcessor.java
index 6bde60d921..72c86020fd 100644
--- a/java/org/apache/coyote/http2/StreamProcessor.java
+++ b/java/org/apache/coyote/http2/StreamProcessor.java
@@ -242,6 +242,19 @@ class StreamProcessor extends AbstractProcessor {
             
headers.addValue("date").setString(FastHttpDateFormat.getCurrentDate());
         }
 
+        // Server header
+        if (protocol != null) {
+            String server = protocol.getHttp11Protocol().getServer();
+            if (server == null) {
+                if 
(protocol.getHttp11Protocol().getServerRemoveAppProvidedValues()) {
+                    headers.removeHeader("server");
+                }
+            } else {
+                // server always overrides anything the app might set
+                headers.setValue("Server").setString(server);
+            }
+        }
+
         // Exclude some HTTP header fields where the value is determined only
         // while generating the content as per section 9.3.2 of RFC 9110.
         if (coyoteRequest != null && coyoteRequest.method().equals("HEAD")) {
diff --git a/test/org/apache/coyote/http2/TestStreamProcessor.java 
b/test/org/apache/coyote/http2/TestStreamProcessor.java
index 4208ff5954..bfc4d8595b 100644
--- a/test/org/apache/coyote/http2/TestStreamProcessor.java
+++ b/test/org/apache/coyote/http2/TestStreamProcessor.java
@@ -653,4 +653,150 @@ public class TestStreamProcessor extends Http2TestBase {
             resp.getWriter().write("OK");
         }
     }
+
+
+    @Test
+    public void testServerHeaderDefault() throws Exception {
+        enableHttp2();
+
+        Tomcat tomcat = getTomcatInstance();
+
+        Context ctxt = getProgrammaticRootContext();
+        Tomcat.addServlet(ctxt, "simple", new SimpleServlet());
+        ctxt.addServletMappingDecoded("/simple", "simple");
+        Tomcat.addServlet(ctxt, "server", new ServerHeaderServlet());
+        ctxt.addServletMappingDecoded("/server", "server");
+        tomcat.start();
+
+        openClientConnection();
+        doHttpUpgrade();
+        sendClientPreface();
+        validateHttp2InitialResponse();
+
+        // Disable overhead protection for window update as it breaks some 
tests
+        http2Protocol.setOverheadWindowUpdateThreshold(0);
+
+        byte[] headersFrameHeader = new byte[9];
+        ByteBuffer headersPayload = ByteBuffer.allocate(128);
+
+        buildGetRequest(headersFrameHeader, headersPayload, null, 3, 
"/server");
+
+        // Write the headers
+        writeFrame(headersFrameHeader, headersPayload);
+
+        parser.readFrame();
+        parser.readFrame();
+
+        Assert.assertEquals("3-HeadersStart\n" + "3-Header-[:status]-[200]\n" +
+                "3-Header-[server]-[TestServerApp]\n" +
+                "3-Header-[content-type]-[text/plain;charset=UTF-8]\n" +
+                "3-Header-[content-length]-[2]\n" +
+                "3-Header-[date]-[" + DEFAULT_DATE + "]\n" + "3-HeadersEnd\n" 
+ "3-Body-2\n" + "3-EndOfStream\n",
+                output.getTrace());
+    }
+
+
+    @Test
+    public void testServerHeaderRemove() throws Exception {
+        enableHttp2();
+
+        Tomcat tomcat = getTomcatInstance();
+
+        tomcat.getConnector().setProperty("serverRemoveAppProvidedValues", 
"true");
+
+        Context ctxt = getProgrammaticRootContext();
+        Tomcat.addServlet(ctxt, "simple", new SimpleServlet());
+        ctxt.addServletMappingDecoded("/simple", "simple");
+        Tomcat.addServlet(ctxt, "server", new ServerHeaderServlet());
+        ctxt.addServletMappingDecoded("/server", "server");
+        tomcat.start();
+
+        openClientConnection();
+        doHttpUpgrade();
+        sendClientPreface();
+        validateHttp2InitialResponse();
+
+        // Disable overhead protection for window update as it breaks some 
tests
+        http2Protocol.setOverheadWindowUpdateThreshold(0);
+
+        byte[] headersFrameHeader = new byte[9];
+        ByteBuffer headersPayload = ByteBuffer.allocate(128);
+
+        buildGetRequest(headersFrameHeader, headersPayload, null, 3, 
"/server");
+
+        // Write the headers
+        writeFrame(headersFrameHeader, headersPayload);
+
+        parser.readFrame();
+        parser.readFrame();
+
+        Assert.assertEquals("3-HeadersStart\n" + "3-Header-[:status]-[200]\n" +
+                "3-Header-[content-type]-[text/plain;charset=UTF-8]\n" +
+                "3-Header-[content-length]-[2]\n" +
+                "3-Header-[date]-[" + DEFAULT_DATE + "]\n" + "3-HeadersEnd\n" 
+ "3-Body-2\n" + "3-EndOfStream\n",
+                output.getTrace());
+    }
+
+
+    @Test
+    public void testServerHeaderForce() throws Exception {
+        enableHttp2();
+
+        Tomcat tomcat = getTomcatInstance();
+
+        Context ctxt = getProgrammaticRootContext();
+        Tomcat.addServlet(ctxt, "simple", new SimpleServlet());
+        ctxt.addServletMappingDecoded("/simple", "simple");
+        Tomcat.addServlet(ctxt, "server", new ServerHeaderServlet());
+        ctxt.addServletMappingDecoded("/server", "server");
+        tomcat.start();
+
+        openClientConnection();
+        doHttpUpgrade();
+        sendClientPreface();
+        validateHttp2InitialResponse();
+
+        /*
+         * This adds the server header to every response. Set this after the 
initial response has been validated to
+         * avoid having to update the validation code to account for the 
additional server header.
+         */
+        tomcat.getConnector().setProperty("server", "TestServerForce");
+
+        // Disable overhead protection for window update as it breaks some 
tests
+        http2Protocol.setOverheadWindowUpdateThreshold(0);
+
+        byte[] headersFrameHeader = new byte[9];
+        ByteBuffer headersPayload = ByteBuffer.allocate(128);
+
+        buildGetRequest(headersFrameHeader, headersPayload, null, 3, 
"/server");
+
+        // Write the headers
+        writeFrame(headersFrameHeader, headersPayload);
+
+        parser.readFrame();
+        parser.readFrame();
+
+        Assert.assertEquals("3-HeadersStart\n" + "3-Header-[:status]-[200]\n" +
+                "3-Header-[server]-[TestServerForce]\n" +
+                "3-Header-[content-type]-[text/plain;charset=UTF-8]\n" +
+                "3-Header-[content-length]-[2]\n" +
+                "3-Header-[date]-[" + DEFAULT_DATE + "]\n" + "3-HeadersEnd\n" 
+ "3-Body-2\n" + "3-EndOfStream\n",
+                output.getTrace());
+    }
+
+
+    private static class ServerHeaderServlet extends HttpServlet {
+
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
+            resp.addHeader("server", "TestServerApp");
+
+            resp.setCharacterEncoding(StandardCharsets.UTF_8);
+            resp.setContentType("text/plain");
+
+            resp.getWriter().write("OK");
+        }
+    }
 }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 1130159b5c..ef38a12290 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -157,6 +157,11 @@
         Request start time may not have been accurately recorded for HTTP/1.1
         requests preceded by a large number of blank lines. (markt)
       </fix>
+      <add>
+        Add <code>server</code> and <code>serverRemoveAppProvidedValues</code>
+        to the list of attributes the HTTP/2 protocol will inherit from the
+        HTTP/1.1 connector it is nested within. 
+      </add>
     </changelog>
   </subsection>
   <subsection name="Jasper">
diff --git a/webapps/docs/config/http2.xml b/webapps/docs/config/http2.xml
index e3b763656c..8d918a5db9 100644
--- a/webapps/docs/config/http2.xml
+++ b/webapps/docs/config/http2.xml
@@ -244,6 +244,8 @@
     <li>maxSavePostSize</li>
     <li>maxTrailerSize</li>
     <li>noCompressionUserAgents</li>
+    <li>server</li>
+    <li>serverRemoveAppProvidedValues</li>
   </ul>
 
   </subsection>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to