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

cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git


The following commit(s) were added to refs/heads/master by this push:
     new 76344a4f96 FELIX-6698 Ability to configure URI Compliance mode (#308)
76344a4f96 is described below

commit 76344a4f9681f46c7db43ef9b089f0fcbcbb3e79
Author: Paul <p...@blueconic.com>
AuthorDate: Mon Apr 29 07:19:54 2024 +0200

    FELIX-6698 Ability to configure URI Compliance mode (#308)
    
    * FELIX-6698 Ability to configure URI Compliance mode
    - Add `org.eclipse.jetty.UriComplianceMode` option
    - Possible values are: DEFAULT, LEGACY, RFC3986, UNAMBIGUOUS, UNSAFE
    - When UNSAFE or LEGACY is used, also apply workaround as suggested in 
https://github.com/jetty/jetty.project/issues/11448#issuecomment-1969206031. 
This is not Servlet API 6 compliant though, so use on your own risk.
    
    * FELIX-6698 Ability to configure URI Compliance mode
    - Add UNAMBIGUOUS
    
    * Code review comments
    
    * Code review comments
---
 http/README.md                                     |  1 +
 .../jetty/internal/ConfigMetaTypeProvider.java     |  6 ++++++
 .../felix/http/jetty/internal/JettyConfig.java     |  3 +++
 .../felix/http/jetty/internal/JettyService.java    | 23 ++++++++++++++++++++--
 4 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/http/README.md b/http/README.md
index be402ef77a..875fcce940 100644
--- a/http/README.md
+++ b/http/README.md
@@ -413,6 +413,7 @@ properties can be used (some legacy property names still 
exist but are not docum
 | `org.eclipse.jetty.servlet.SessionDomain` | Domain to set on the session 
cookie. The default is `null`. |
 | `org.eclipse.jetty.servlet.SessionPath` | The path to set on the session 
cookie. The default is the configured session context path ("/"). |
 | `org.eclipse.jetty.servlet.MaxAge` | The maximum age value to set on the 
cookie. The default is "-1". |
+| `org.eclipse.jetty.UriComplianceMode` | The URI compliance mode to set. The 
default is 
[DEFAULT](https://eclipse.dev/jetty/javadoc/jetty-12/org/eclipse/jetty/http/UriCompliance.html#DEFAULT).
 See 
[documentation](https://eclipse.dev/jetty/documentation/jetty-12/programming-guide/index.html#pg-server-compliance-uri.)
 and [possible 
modes](https://github.com/jetty/jetty.project/blob/jetty-12.0.x/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/UriCompliance.java#L186C107-L186C113).
 |
 | `org.apache.felix.proxy.load.balancer.connection.enable` | Set this to 
`true` when running Felix HTTP behind a (offloading) proxy or load balancer 
which rewrites the requests. The default is `false`. |
 | `org.apache.felix.http.runtime.init.` | Properties starting with this prefix 
are added as service registration properties to the HttpServiceRuntime service. 
The prefix is removed for the property name. |
 | `org.apache.felix.jetty.gziphandler.enable` | Whether the server should use 
a server-wide gzip handler. Default is false. |
diff --git 
a/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/ConfigMetaTypeProvider.java
 
b/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/ConfigMetaTypeProvider.java
index 03bd3cf02f..917e334132 100644
--- 
a/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/ConfigMetaTypeProvider.java
+++ 
b/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/ConfigMetaTypeProvider.java
@@ -284,6 +284,12 @@ class ConfigMetaTypeProvider implements MetaTypeProvider
                 false,
                 
bundle.getBundleContext().getProperty(JettyConfig.FELIX_JETTY_SESSION_COOKIE_SECURE)));
 
+        adList.add(new 
AttributeDefinitionImpl(JettyConfig.FELIX_JETTY_URI_COMPLIANCE_MODE,
+                "Jetty URI compliance mode",
+                "Jetty URI compliance mode (if not set, Jetty will configure a 
default)",
+                null,
+                
bundle.getBundleContext().getProperty(JettyConfig.FELIX_JETTY_URI_COMPLIANCE_MODE)));
+
         adList.add(new 
AttributeDefinitionImpl(JettyConfig.FELIX_JETTY_SERVLET_SESSION_ID_PATH_PARAMETER_NAME,
                 "Session Id path parameter",
                 "Defaults to jsessionid. If set to null or \"none\" no URL 
rewriting will be done.",
diff --git 
a/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
 
b/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
index ef336ea61c..05e6c7f941 100644
--- 
a/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
+++ 
b/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
@@ -166,6 +166,9 @@ public final class JettyConfig
     /**  Felix specific property to configure session max age */
     public static final String FELIX_JETTY_SERVLET_SESSION_MAX_AGE = 
"org.eclipse.jetty.servlet.MaxAge";
 
+    /**  Felix specific property to configure the uri compliance mode 
(https://eclipse.dev/jetty/documentation/jetty-12/programming-guide/index.html#pg-server-compliance-uri)
 */
+    public static final String FELIX_JETTY_URI_COMPLIANCE_MODE = 
"org.eclipse.jetty.UriComplianceMode";
+
     /** Felix specific property to configure session scavenging interval in 
Seconds */
     public static final String FELIX_JETTY_SESSION_SCAVENGING_INTERVAL = 
"org.eclipse.jetty.servlet.SessionScavengingInterval";
 
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 2d993fcb65..f75a6af3d8 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
@@ -34,7 +34,9 @@ import 
org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
 import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
 import org.eclipse.jetty.ee10.servlet.ServletHolder;
 import org.eclipse.jetty.ee10.servlet.SessionHandler;
+import org.eclipse.jetty.ee10.servlet.ServletHandler;
 import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.http.UriCompliance;
 import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
 import org.eclipse.jetty.io.ConnectionStatistics;
 import org.eclipse.jetty.security.HashLoginService;
@@ -251,9 +253,9 @@ public final class JettyService
             loginService.setUserStore(new UserStore());
             this.server.addBean(loginService);
 
-            ServletContextHandler context = new 
ServletContextHandler(this.config.getContextPath(),                    
+            ServletContextHandler context = new 
ServletContextHandler(this.config.getContextPath(),
                     ServletContextHandler.SESSIONS);
-            
+
             this.parent = new ContextHandlerCollection(context);
 
             configureSessionManager(context);
@@ -564,6 +566,23 @@ public final class JettyService
         config.setResponseHeaderSize(this.config.getHeaderSize());
         config.setOutputBufferSize(this.config.getResponseBufferSize());
 
+        String uriComplianceMode = 
this.config.getProperty(JettyConfig.FELIX_JETTY_URI_COMPLIANCE_MODE, null);
+        if (uriComplianceMode != null) {
+            try {
+                
config.setUriCompliance(UriCompliance.valueOf(uriComplianceMode));
+
+                if (UriCompliance.LEGACY.equals(uriComplianceMode)
+                        || UriCompliance.UNSAFE.equals(uriComplianceMode)
+                        || 
UriCompliance.UNAMBIGUOUS.equals(uriComplianceMode)) {
+                    // See 
https://github.com/jetty/jetty.project/issues/11448#issuecomment-1969206031
+                    this.server.getContainedBeans(ServletHandler.class)
+                            .forEach(handler -> 
handler.setDecodeAmbiguousURIs(true));
+                }
+            } catch (IllegalArgumentException e) {
+                SystemLogger.LOGGER.warn("Invalid URI compliance mode: {}", 
uriComplianceMode);
+            }
+        }
+
         // HTTP/1.1 requires Date header if possible (it is)
         config.setSendDateHeader(true);
         config.setSendServerVersion(this.config.isSendServerHeader());

Reply via email to