Skip to content

Commit 6858ded

Browse files
authored
Merge pull request #415 from apache/maintenance/FELIX-6774-IT-demonstrating-the-issue
FELIX-6774 `org.apache.felix.http.jetty.maxFormSize` not enforced: Unit test to demonstrate issue - Merging the IT, which now asserts the correct behavior of `org.apache.felix.http.jetty.maxFormSize`. context.setMaxFormContentSize(this.config.getMaxFormSize()); Only affects request.getParameter(), but does not apply to any other places. It does not affect a multipart file upload for example. For that purpose, one can add the SizeLimitHandler, which affects all incoming requests (including form data). It just operates on a different level. In that respect, this is not a bug, but a change request.
2 parents d8bce3a + ce1b5af commit 6858ded

File tree

4 files changed

+137
-0
lines changed

4 files changed

+137
-0
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.felix.http.jetty.it;
18+
19+
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertNotNull;
21+
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
22+
import static org.ops4j.pax.exam.cm.ConfigurationAdminOptions.newConfiguration;
23+
24+
import java.io.IOException;
25+
import java.net.URI;
26+
import java.util.Hashtable;
27+
import java.util.Map;
28+
29+
import javax.inject.Inject;
30+
import jakarta.servlet.Servlet;
31+
import jakarta.servlet.ServletException;
32+
import jakarta.servlet.http.HttpServlet;
33+
import jakarta.servlet.http.HttpServletRequest;
34+
import jakarta.servlet.http.HttpServletResponse;
35+
36+
import org.eclipse.jetty.client.ContentResponse;
37+
import org.eclipse.jetty.client.HttpClient;
38+
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
39+
import org.eclipse.jetty.util.Fields;
40+
import org.junit.Before;
41+
import org.junit.Test;
42+
import org.junit.runner.RunWith;
43+
import org.ops4j.pax.exam.Option;
44+
import org.ops4j.pax.exam.junit.PaxExam;
45+
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
46+
import org.ops4j.pax.exam.spi.reactors.PerClass;
47+
import org.osgi.framework.BundleContext;
48+
import org.osgi.service.http.HttpService;
49+
import org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants;
50+
51+
@RunWith(PaxExam.class)
52+
@ExamReactorStrategy(PerClass.class)
53+
public class JettyMaxFormSizeIT extends AbstractJettyTestSupport {
54+
private static final int LIMIT_IN_BYTES = 10;
55+
56+
57+
@Inject
58+
protected BundleContext bundleContext;
59+
60+
@Override
61+
protected Option[] additionalOptions() throws IOException {
62+
String jettyVersion = System.getProperty("jetty.version", JETTY_VERSION);
63+
return new Option[] {
64+
spifly(),
65+
66+
// bundles for the server side
67+
mavenBundle().groupId("org.eclipse.jetty.ee10").artifactId("jetty-ee10-webapp").version(jettyVersion),
68+
mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-ee").version(jettyVersion),
69+
mavenBundle().groupId("org.eclipse.jetty.ee10").artifactId("jetty-ee10-servlet").version(jettyVersion),
70+
mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-xml").version(jettyVersion),
71+
72+
// additional bundles for the client side
73+
mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-alpn-client").version(jettyVersion),
74+
mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-client").version(jettyVersion)
75+
};
76+
}
77+
78+
@Override
79+
protected Option felixHttpConfig(int httpPort) {
80+
return newConfiguration("org.apache.felix.http")
81+
.put("org.osgi.service.http.port", httpPort)
82+
.put("org.apache.felix.http.jetty.maxFormSize", LIMIT_IN_BYTES) // 10 bytes limit
83+
.asOption();
84+
}
85+
86+
@Before
87+
public void setup(){
88+
assertNotNull(bundleContext);
89+
bundleContext.registerService(Servlet.class, new HelloWorldServlet(), new Hashtable<>(Map.of(
90+
HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/*"
91+
)));
92+
}
93+
94+
95+
@Test
96+
public void testFormSizeLimit() throws Exception {
97+
HttpClientTransportOverHTTP transport = new HttpClientTransportOverHTTP();
98+
HttpClient httpClient = new HttpClient(transport);
99+
httpClient.start();
100+
101+
Object value = bundleContext.getServiceReference(HttpService.class).getProperty("org.osgi.service.http.port");
102+
int httpPort = Integer.parseInt((String) value);
103+
104+
URI uri = new URI(String.format("http://localhost:%d/endpoint", httpPort));
105+
106+
Fields formFields = new Fields();
107+
formFields.add(new Fields.Field("key", "value")); // under 10 bytes
108+
ContentResponse response = httpClient.FORM(uri, formFields);
109+
110+
assertEquals(200, response.getStatus());
111+
assertEquals("OK", response.getContentAsString());
112+
113+
Fields formFieldsLimitExceeded = new Fields();
114+
formFieldsLimitExceeded.add(new Fields.Field("key", "valueoverlimit")); // over limit of 10 bytes
115+
ContentResponse responseExceeded = httpClient.FORM(uri, formFieldsLimitExceeded);
116+
117+
// HTTP 500 thrown, because req.getParameter("key") throws an IOEx
118+
assertEquals(500, responseExceeded.getStatus());
119+
120+
httpClient.close();
121+
}
122+
123+
static final class HelloWorldServlet extends HttpServlet {
124+
@Override
125+
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
126+
req.getParameter("key"); // this triggers the maxFormSize check
127+
resp.setStatus(200);
128+
resp.getWriter().write("OK");
129+
}
130+
}
131+
}

http/jetty12/src/test/java/org/apache/felix/http/jetty/it/JettyUriComplianceModeDefaultIT.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ public void testUriCompliance() throws Exception {
103103

104104
// blocked with HTTP 400 by default
105105
assertEquals(400, httpClient.GET(destUriAmbigousPath).getStatus());
106+
107+
httpClient.close();
106108
}
107109

108110
static final class UriComplianceEndpoint extends HttpServlet {

http/jetty12/src/test/java/org/apache/felix/http/jetty/it/JettyUriComplianceModeLegacyIT.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,7 @@ public void testUriCompliance() throws Exception {
7979
ContentResponse response2 = httpClient.GET(destUriAmbigousPath);
8080
assertEquals(200, response2.getStatus());
8181
assertEquals("OK", response2.getContentAsString());
82+
83+
httpClient.close();
8284
}
8385
}

http/jetty12/src/test/java/org/apache/felix/http/jetty/it/JettyVirtualThreadsIT.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ public void testJettyRunningWithVirtualThreads() throws Exception {
105105
ContentResponse response = httpClient.GET(destUri);
106106
assertEquals(200, response.getStatus());
107107
assertEquals("OK", response.getContentAsString());
108+
109+
httpClient.close();
108110
}
109111

110112
static final class ExampleEndpoint extends HttpServlet {

0 commit comments

Comments
 (0)