Skip to content

Commit 8cff4d8

Browse files
authored
Merge pull request #534 from apache/FELIX-6849-redirect-uri-compliance
FELIX-6849 : Apply org.eclipse.jetty.UriComplianceMode to redirect URIs
2 parents 88d5e0c + 670a92d commit 8cff4d8

4 files changed

Lines changed: 49 additions & 2 deletions

File tree

http/itest/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<properties>
3434
<felix.java.version>17</felix.java.version>
3535
<http.servlet.api.version>6.1.0</http.servlet.api.version>
36-
<http.jetty.version>2.0.1-SNAPSHOT</http.jetty.version>
36+
<http.jetty.version>2.0.3-SNAPSHOT</http.jetty.version>
3737
<http.jetty.id>org.apache.felix.http.jetty12</http.jetty.id>
3838
<pax.exam.version>4.13.3</pax.exam.version>
3939
<pax.url.aether.version>2.6.14</pax.url.aether.version>
@@ -45,7 +45,7 @@
4545
<properties>
4646
<felix.java.version>11</felix.java.version>
4747
<http.servlet.api.version>6.1.0</http.servlet.api.version>
48-
<http.jetty.version>5.2.3-SNAPSHOT</http.jetty.version>
48+
<http.jetty.version>5.2.5-SNAPSHOT</http.jetty.version>
4949
<http.jetty.id>org.apache.felix.http.jetty</http.jetty.id>
5050
</properties>
5151
</profile>

http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,11 @@ private void configureHttpConnectionFactory(HttpConnectionFactory connFactory)
788788
try {
789789
UriCompliance compliance = UriCompliance.valueOf(uriComplianceMode);
790790
config.setUriCompliance(compliance);
791+
// Apply the same compliance to redirect URIs (Location header). Since Jetty 12.1
792+
// this defaults to UriCompliance.DEFAULT_REDIRECT, which - like the request URI
793+
// default - rejects ambiguous encodings such as %2F. Differentiating the two makes
794+
// no sense: if a deployment opts into a compliance mode it should apply end-to-end.
795+
config.setRedirectUriCompliance(compliance);
791796

792797
if (LEGACY.equals(compliance) || UNSAFE.equals(compliance) || UNAMBIGUOUS.equals(compliance)) {
793798
// See https://github.com/jetty/jetty.project/issues/11448#issuecomment-1969206031

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,32 @@ public void testUriCompliance() throws Exception {
115115
}
116116
}
117117

118+
@Test
119+
public void testRedirectUriCompliance() throws Exception {
120+
try (HttpClient httpClient = new HttpClient()) {
121+
httpClient.setFollowRedirects(false);
122+
httpClient.start();
123+
Object value = bundleContext.getServiceReference(HttpService.class).getProperty("org.osgi.service.http.port");
124+
int httpPort = Integer.parseInt((String) value);
125+
126+
URI destUriRedirect = new URI(String.format("http://localhost:%d/endpoint/redirect", httpPort));
127+
128+
// The endpoint issues a redirect whose Location contains an ambiguous %2F.
129+
// With the default redirect compliance (DEFAULT_REDIRECT) this is rejected,
130+
// surfacing as an internal server error rather than a 302.
131+
ContentResponse response = httpClient.GET(destUriRedirect);
132+
assertEquals(500, response.getStatus());
133+
}
134+
}
135+
118136
static final class UriComplianceEndpoint extends HttpServlet {
119137
@Override
120138
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
139+
if (req.getRequestURI().contains("redirect")) {
140+
// Location deliberately contains an ambiguous encoded separator (%2F)
141+
resp.sendRedirect("/endpoint/redirected%2Ftarget");
142+
return;
143+
}
121144
resp.setStatus(200);
122145
resp.getWriter().write("OK");
123146
}

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,23 @@ public void testUriCompliance() throws Exception {
6464
assertEquals("OK", response2.getContentAsString());
6565
}
6666
}
67+
68+
@Test
69+
@Override
70+
public void testRedirectUriCompliance() throws Exception {
71+
try (HttpClient httpClient = new HttpClient()) {
72+
httpClient.setFollowRedirects(false);
73+
httpClient.start();
74+
Object value = bundleContext.getServiceReference(HttpService.class).getProperty("org.osgi.service.http.port");
75+
int httpPort = Integer.parseInt((String) value);
76+
77+
URI destUriRedirect = new URI(String.format("http://localhost:%d/endpoint/redirect", httpPort));
78+
79+
// With LEGACY compliance the ambiguous %2F in the Location header is allowed,
80+
// so the redirect is emitted normally instead of being rejected.
81+
ContentResponse response = httpClient.GET(destUriRedirect);
82+
assertEquals(302, response.getStatus());
83+
assertEquals("/endpoint/redirected%2Ftarget", response.getHeaders().get("Location"));
84+
}
85+
}
6786
}

0 commit comments

Comments
 (0)