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

jbertram pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/main by this push:
     new 0ecbae6108 ARTEMIS-4939 allow config of header sizes for embedded web 
server
0ecbae6108 is described below

commit 0ecbae61080dd9c028a5aa22c2501c5e74bfa3ef
Author: Justin Bertram <[email protected]>
AuthorDate: Fri Jul 19 12:45:50 2024 -0500

    ARTEMIS-4939 allow config of header sizes for embedded web server
---
 .../apache/activemq/artemis/dto/WebServerDTO.java  |  6 ++
 .../artemis/component/WebServerComponent.java      |  8 +++
 docs/user-manual/web-server.adoc                   |  8 +++
 .../isolated/web/WebServerComponentTest.java       | 71 ++++++++++++++++++++++
 4 files changed, 93 insertions(+)

diff --git 
a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java 
b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java
index 8f8bbeaeef..b118c708ad 100644
--- 
a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java
+++ 
b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java
@@ -107,6 +107,12 @@ public class WebServerDTO extends ComponentDTO {
    @XmlAttribute
    public Integer scanPeriod;
 
+   @XmlAttribute
+   public Integer maxRequestHeaderSize;
+
+   @XmlAttribute
+   public Integer maxResponseHeaderSize;
+
    public String getPath() {
       return path;
    }
diff --git 
a/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java
 
b/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java
index 4b77d51641..53470e7678 100644
--- 
a/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java
+++ 
b/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java
@@ -136,6 +136,14 @@ public class WebServerComponent implements 
ExternalComponent, WebServerComponent
 
       HttpConfiguration httpConfiguration = new HttpConfiguration();
 
+      if (webServerConfig.maxRequestHeaderSize != null) {
+         
httpConfiguration.setRequestHeaderSize(webServerConfig.maxRequestHeaderSize);
+      }
+
+      if (webServerConfig.maxResponseHeaderSize != null) {
+         
httpConfiguration.setResponseHeaderSize(webServerConfig.maxResponseHeaderSize);
+      }
+
       if (this.webServerConfig.customizer != null) {
          try {
             httpConfiguration.addCustomizer((HttpConfiguration.Customizer) 
ClassloadingUtil.getInstanceWithTypeCheck(this.webServerConfig.customizer, 
HttpConfiguration.Customizer.class, this.getClass().getClassLoader()));
diff --git a/docs/user-manual/web-server.adoc b/docs/user-manual/web-server.adoc
index 0a17a8d67b..672bf208c1 100644
--- a/docs/user-manual/web-server.adoc
+++ b/docs/user-manual/web-server.adoc
@@ -45,6 +45,14 @@ idleThreadTimeout::
 The time to wait before terminating an idle thread from the embedded web 
server. Measured in milliseconds. Default is `60000`.
 scanPeriod::
 How often to scan for changes of the key and trust store files related to a 
binding when the `sslAutoReload` attribute value of the `binding` element is 
`true`, for further details see <<Binding>>. Measured in seconds. Default is 
`5`.
+maxRequestHeaderSize::
+The maximum allowed size for the HTTP request line and HTTP request headers.
+Measured in bytes.
+Default is `8192`.
+maxResponseHeaderSize::
+The maximum allowed size for the HTTP response headers.
+Measured in bytes.
+Default is `8192`.
 
 === Binding
 
diff --git 
a/tests/integration-tests-isolated/src/test/java/org/apache/activemq/artemis/tests/integration/isolated/web/WebServerComponentTest.java
 
b/tests/integration-tests-isolated/src/test/java/org/apache/activemq/artemis/tests/integration/isolated/web/WebServerComponentTest.java
index cd0dea2824..9e6345df5c 100644
--- 
a/tests/integration-tests-isolated/src/test/java/org/apache/activemq/artemis/tests/integration/isolated/web/WebServerComponentTest.java
+++ 
b/tests/integration-tests-isolated/src/test/java/org/apache/activemq/artemis/tests/integration/isolated/web/WebServerComponentTest.java
@@ -56,6 +56,8 @@ import 
org.apache.activemq.artemis.core.server.ActiveMQComponent;
 import org.apache.activemq.artemis.dto.BindingDTO;
 import org.apache.activemq.artemis.dto.RequestLogDTO;
 import org.apache.activemq.artemis.dto.WebServerDTO;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -143,6 +145,75 @@ public class WebServerComponentTest {
       assertTrue(logEntryFound);
    }
 
+   @Test
+   public void testLargeRequestHeader() throws Exception {
+      testLargeRequestHeader(false);
+   }
+
+   @Test
+   public void testLargeRequestHeaderNegative() throws Exception {
+      testLargeRequestHeader(true);
+   }
+
+   private void testLargeRequestHeader(boolean fail) throws Exception {
+      final int defaultRequestHeaderSize = new 
HttpConfiguration().getRequestHeaderSize();
+      BindingDTO bindingDTO = new BindingDTO();
+      bindingDTO.uri = "http://localhost:0";;
+      WebServerDTO webServerDTO = new WebServerDTO();
+      webServerDTO.setBindings(Collections.singletonList(bindingDTO));
+      webServerDTO.path = "webapps";
+      webServerDTO.webContentEnabled = true;
+      if (!fail) {
+         webServerDTO.maxRequestHeaderSize = defaultRequestHeaderSize * 2;
+      }
+      WebServerComponent webServerComponent = new WebServerComponent();
+      assertFalse(webServerComponent.isStarted());
+      webServerComponent.configure(webServerDTO, "./src/test/resources/", 
"./src/test/resources/");
+      testedComponents.add(webServerComponent);
+      webServerComponent.start();
+
+      final int port = webServerComponent.getPort();
+      // Make the connection attempt.
+      CountDownLatch latch = new CountDownLatch(1);
+      final ClientHandler clientHandler = new ClientHandler(latch);
+      Channel ch = getChannel(port, clientHandler);
+
+      URI uri = new URI(URL);
+      // Prepare the HTTP request.
+      HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, 
HttpMethod.GET, uri.getRawPath());
+      request.headers().set(HttpHeaderNames.HOST, "localhost");
+      StringBuilder foo = new StringBuilder();
+      for (int i = 0; i < defaultRequestHeaderSize + 1; i++) {
+         foo.append("a");
+      }
+      request.headers().set("foo", foo.toString());
+
+      // Send the HTTP request.
+      ch.writeAndFlush(request);
+      assertTrue(latch.await(5, TimeUnit.SECONDS));
+      assertEquals(fail, clientHandler.body.toString().contains("431"));
+   }
+
+   /* It's not clear how to create a functional test for the response header 
size so this test simply ensures the
+    * configuration is passed through as expected.
+    */
+   @Test
+   public void testLargeResponseHeaderConfiguration() throws Exception {
+      BindingDTO bindingDTO = new BindingDTO();
+      bindingDTO.uri = "http://localhost:0";;
+      WebServerDTO webServerDTO = new WebServerDTO();
+      webServerDTO.setBindings(Collections.singletonList(bindingDTO));
+      webServerDTO.path = "webapps";
+      webServerDTO.webContentEnabled = true;
+      webServerDTO.maxResponseHeaderSize = 123;
+      WebServerComponent webServerComponent = new WebServerComponent();
+      assertFalse(webServerComponent.isStarted());
+      webServerComponent.configure(webServerDTO, "./src/test/resources/", 
"./src/test/resources/");
+      testedComponents.add(webServerComponent);
+      webServerComponent.start();
+      assertEquals(123, 
((HttpConnectionFactory)webServerComponent.getWebServer().getConnectors()[0].getConnectionFactories().iterator().next()).getHttpConfiguration().getResponseHeaderSize());
+   }
+
    private Channel getChannel(int port, ClientHandler clientHandler) throws 
InterruptedException {
       EventLoopGroup group = new NioEventLoopGroup();
       Bootstrap bootstrap = new Bootstrap();


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact


Reply via email to