This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new 748c584f8c Add support for server and serverRemoveAppProvidedValues to
h2
748c584f8c is described below
commit 748c584f8c8225a8d875e4396c74fa92349de147
Author: Mark Thomas <[email protected]>
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 6344e0f610..fe5bb2ade0 100644
--- a/java/org/apache/coyote/http2/StreamProcessor.java
+++ b/java/org/apache/coyote/http2/StreamProcessor.java
@@ -241,6 +241,19 @@ class StreamProcessor extends AbstractProcessor {
if (statusCode >= 200 && headers.getValue("date") == null) {
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);
+ }
+ }
}
diff --git a/test/org/apache/coyote/http2/TestStreamProcessor.java
b/test/org/apache/coyote/http2/TestStreamProcessor.java
index 5082349a6e..0788815e76 100644
--- a/test/org/apache/coyote/http2/TestStreamProcessor.java
+++ b/test/org/apache/coyote/http2/TestStreamProcessor.java
@@ -652,4 +652,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 6eacc77ce1..f8290bb500 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 97b4a4b73d..a7b8b12ee5 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: [email protected]
For additional commands, e-mail: [email protected]