This is an automated email from the ASF dual-hosted git repository. markt 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 3701d8468d Add support for server and serverRemoveAppProvidedValues to h2 3701d8468d is described below commit 3701d8468dce193dfa38302dd20d413eb18af30f 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 6c53748d46..e33c521b5a 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 = ((AbstractHttp11Protocol<?>) protocol.getHttp11Protocol()).getServer(); + if (server == null) { + if (((AbstractHttp11Protocol<?>) 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 5c3daac77c..ce14db27bc 100644 --- a/test/org/apache/coyote/http2/TestStreamProcessor.java +++ b/test/org/apache/coyote/http2/TestStreamProcessor.java @@ -657,4 +657,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("UTF-8"); + resp.setContentType("text/plain"); + + resp.getWriter().write("OK"); + } + } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 3275a6950e..68af6d696a 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -148,6 +148,11 @@ input. Prior to this change, the output may have wrong by one second in some cases. Pull request <pr>751</pr> provided by Chenjp. (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 78cd8bc904..2293233651 100644 --- a/webapps/docs/config/http2.xml +++ b/webapps/docs/config/http2.xml @@ -319,6 +319,8 @@ <li>maxParameterCount</li> <li>maxPostSize</li> <li>maxSavePostSize</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