You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pa...@apache.org on 2026/07/21 11:05:14 UTC
(felix-dev) 01/01: FELIX-6849 : Apply org.eclipse.jetty.UriComplianceMode to redirect URIs
This is an automated email from the ASF dual-hosted git repository.
paulrutter pushed a commit to branch FELIX-6849-redirect-uri-compliance
in repository https://gitbox.apache.org/repos/asf/felix-dev.git
commit d733f102f05aa481aae6a0c2497a1e7bed4f4f04
Author: Paul Rütter <pa...@blueconic.com>
AuthorDate: Tue Jul 21 13:04:14 2026 +0200
FELIX-6849 : Apply org.eclipse.jetty.UriComplianceMode to redirect URIs
Felix jetty12 mapped the org.eclipse.jetty.UriComplianceMode property to
HttpConfiguration.setUriCompliance() only, leaving redirect URI compliance
at Jetty's default. Since Jetty 12.1 that default rejects ambiguous encodings
(e.g. %2F) in the Location header, so a deployment relaxing request URI
compliance (e.g. LEGACY) still had its redirects rejected.
Apply the configured compliance to setRedirectUriCompliance() as well, so the
mode takes effect end-to-end. Behavior is unchanged when the property is unset
(Jetty defaults still apply).
Added redirect URI compliance coverage to the default and LEGACY integration
tests.
Co-Authored-By: Claude Opus 4.8 <no...@anthropic.com>
---
.../felix/http/jetty/internal/JettyService.java | 5 +++++
.../jetty/it/JettyUriComplianceModeDefaultIT.java | 23 ++++++++++++++++++++++
.../jetty/it/JettyUriComplianceModeLegacyIT.java | 19 ++++++++++++++++++
3 files changed, 47 insertions(+)
diff --git a/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java b/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
index b14504bab5..fd156328d8 100644
--- a/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
+++ b/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
@@ -784,6 +784,11 @@ public final class JettyService
try {
UriCompliance compliance = UriCompliance.valueOf(uriComplianceMode);
config.setUriCompliance(compliance);
+ // Apply the same compliance to redirect URIs (Location header). Since Jetty 12.1
+ // this defaults to UriCompliance.DEFAULT_REDIRECT, which - like the request URI
+ // default - rejects ambiguous encodings such as %2F. Differentiating the two makes
+ // no sense: if a deployment opts into a compliance mode it should apply end-to-end.
+ config.setRedirectUriCompliance(compliance);
if (LEGACY.equals(compliance) || UNSAFE.equals(compliance) || UNAMBIGUOUS.equals(compliance)) {
// See https://github.com/jetty/jetty.project/issues/11448#issuecomment-1969206031
diff --git a/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/JettyUriComplianceModeDefaultIT.java b/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/JettyUriComplianceModeDefaultIT.java
index 5d90217097..e3c34e86fc 100644
--- a/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/JettyUriComplianceModeDefaultIT.java
+++ b/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/JettyUriComplianceModeDefaultIT.java
@@ -115,9 +115,32 @@ public class JettyUriComplianceModeDefaultIT extends AbstractJettyTestSupport {
}
}
+ @Test
+ public void testRedirectUriCompliance() throws Exception {
+ try (HttpClient httpClient = new HttpClient()) {
+ httpClient.setFollowRedirects(false);
+ httpClient.start();
+ Object value = bundleContext.getServiceReference(HttpService.class).getProperty("org.osgi.service.http.port");
+ int httpPort = Integer.parseInt((String) value);
+
+ URI destUriRedirect = new URI(String.format("http://localhost:%d/endpoint/redirect", httpPort));
+
+ // The endpoint issues a redirect whose Location contains an ambiguous %2F.
+ // With the default redirect compliance (DEFAULT_REDIRECT) this is rejected,
+ // surfacing as an internal server error rather than a 302.
+ ContentResponse response = httpClient.GET(destUriRedirect);
+ assertEquals(500, response.getStatus());
+ }
+ }
+
static final class UriComplianceEndpoint extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ if (req.getRequestURI().contains("redirect")) {
+ // Location deliberately contains an ambiguous encoded separator (%2F)
+ resp.sendRedirect("/endpoint/redirected%2Ftarget");
+ return;
+ }
resp.setStatus(200);
resp.getWriter().write("OK");
}
diff --git a/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/JettyUriComplianceModeLegacyIT.java b/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/JettyUriComplianceModeLegacyIT.java
index 8b2944bc5d..31f9375530 100644
--- a/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/JettyUriComplianceModeLegacyIT.java
+++ b/http/jetty12/src/test/java/org/apache/felix/http/jetty/it/JettyUriComplianceModeLegacyIT.java
@@ -64,4 +64,23 @@ public class JettyUriComplianceModeLegacyIT extends JettyUriComplianceModeDefaul
assertEquals("OK", response2.getContentAsString());
}
}
+
+ @Test
+ @Override
+ public void testRedirectUriCompliance() throws Exception {
+ try (HttpClient httpClient = new HttpClient()) {
+ httpClient.setFollowRedirects(false);
+ httpClient.start();
+ Object value = bundleContext.getServiceReference(HttpService.class).getProperty("org.osgi.service.http.port");
+ int httpPort = Integer.parseInt((String) value);
+
+ URI destUriRedirect = new URI(String.format("http://localhost:%d/endpoint/redirect", httpPort));
+
+ // With LEGACY compliance the ambiguous %2F in the Location header is allowed,
+ // so the redirect is emitted normally instead of being rejected.
+ ContentResponse response = httpClient.GET(destUriRedirect);
+ assertEquals(302, response.getStatus());
+ assertEquals("/endpoint/redirected%2Ftarget", response.getHeaders().get("Location"));
+ }
+ }
}
\ No newline at end of file