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