You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ozone.apache.org by "yandrey321 (via GitHub)" <gi...@apache.org> on 2026/09/30 05:23:19 UTC

[PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

yandrey321 opened a new pull request, #11367:
URL: https://github.com/apache/ozone/pull/11367

   ## What changes were proposed in this pull request?
   
   This patch upgrades Ozone from Jetty `9.4.58.v20250814` to Jetty `12.0.38`, targeting the
   **EE8** environment so that the `javax.servlet` namespace is retained.
   
   ### Why
   
   Jetty 9.x is out of community support and 9.4.x will never support JDK 17. Ozone server
   components already require JDK 17 (HDDS-14439). Staying on 9.4 blocks HDDS-8249 / HDDS-8250
   (JDK 17 crash fixes) and HDDS-16121 (Jetty `VirtualThreadPool`).
   
   Jetty 12's core no longer bundles a Servlet API. Servlet support moved into per-environment
   modules: `jetty-ee8-*` (`javax.servlet` 4.0), `jetty-ee9-*` (`jakarta.servlet` 5) and
   `jetty-ee10-*` (`jakarta.servlet` 6).
   
   ### Why EE8 rather than EE10
   
   Ozone depends on Hadoop 3.4.3, which is still `javax.servlet` 3.1. Targeting EE10 forces the
   entire web stack to `jakarta.*`: a `javax`→`jakarta` filter/listener bridge, forks of several
   hadoop-common servlet classes, and moving Jersey, Weld, CDI, Guice and JAXB to their jakarta
   lines. An earlier EE10 attempt on this Jira came to **357 changed files**, of which 265 were
   pure `javax.`→`jakarta.` import churn.
   
   EE8 reaches the same endpoint — one Jetty major and one `javax.servlet` provider on the
   classpath — in **48 files**. Jersey 2.48, Weld 3.x, Guice 6, CDI 2, JAXB 2.3.x and every
   `web.xml` / `beans.xml` descriptor namespace are untouched.
   
   ### Dependency shape
   
   | Item | From | To |
   |---|---|---|
   | `jetty.version` | `9.4.58.v20250814` | `12.0.38` |
   | BOMs | `jetty-bom` | `jetty-bom` + `org.eclipse.jetty.ee8:jetty-ee8-bom` |
   | `servlet-api.version` | `3.1.0` (`javax.servlet:javax.servlet-api`) | `4.0.9` (`org.eclipse.jetty.toolchain:jetty-servlet-api`) |
   | `jetty-servlet` / `-webapp` / `-proxy` | `org.eclipse.jetty` | `org.eclipse.jetty.ee8:jetty-ee8-*` |
   | `jetty-http` / `-server` / `-util` / `-client` | unchanged | unchanged (Jetty 12 core) |
   | Jersey, Weld, Guice, CDI, HK2, JAXB, `jakarta.*` | — | **unchanged** |
   
   `org.eclipse.jetty.toolchain:jetty-servlet-api` becomes the single `javax.servlet` provider and
   `javax.servlet:javax.servlet-api` is dropped. Only the toolchain jar ships the
   `javax/servlet/catalog.xml` + XSD tree that `jetty-ee8-webapp`'s
   `WebDescriptor.__nonValidatingStaticParser` — a **static** field — resolves against; a missing
   catalog entry throws rather than being tolerated, so keeping both jars risks a fatal
   class-initialization failure.
   
   Both managed `hadoop-common` entries (jar and test-jar) now exclude `javax.servlet:javax.servlet-api`
   and `org.eclipse.jetty:*`. The Jetty exclusion is mandatory independently of the EE choice:
   `jetty-servlet` and `jetty-webapp` do not exist at 12.x, so `jetty-bom` silently stops managing
   them and Maven would otherwise fall back to Hadoop's 9.4.x.
   
   ### Notable behavioral changes
   
   **Admin servlets.** hadoop-common's `org.apache.hadoop.conf.ConfServlet` and
   `org.apache.hadoop.jmx.JMXJsonServlet` both route their admin-access check through
   `org.apache.hadoop.http.HttpServer2`, which references `org.eclipse.jetty.servlet.ServletContextHandler`,
   `org.eclipse.jetty.webapp.WebAppContext` and `FilterHolder`/`FilterMapping` — all removed or moved
   in Jetty 12. Those classes cannot load at all on a Jetty 12 classpath, so `/jmx` and `/conf` would
   answer 500 with a `NoClassDefFoundError`. This is unrelated to the EE environment. `/conf` is
   switched to Ozone's existing `HddsConfServlet`, and a new `HddsJMXJsonServlet` covers `/jmx`.
   
   **URI compliance.** Jetty 12 rejects ambiguous URIs (empty `//` segments, `%25`, encoded path
   separators, suspicious path characters) that 9.4 passed through. S3 object keys and WebHDFS paths
   need them. A new opt-in `Builder.allowAmbiguousUri(boolean)` installs an `OZONE` `UriCompliance`
   mode allowing exactly those four violations — and, unlike Jetty's `LEGACY` mode, **not**
   `%2e%2e` path traversal, UTF-16 `%u` encodings, truncated UTF-8 or userinfo. S3 Gateway and
   httpfs opt in; every other endpoint keeps Jetty's strict default.
   
   **XML content type.** EE8's `Response.setContentType` appends `;charset=` once `_encodingFrom`
   has moved past `NOT_SET`, and `QuotingInputFilter` promotes it on every request, whereas 9.4
   reset it — so a bare `application/xml` would ship as `application/xml;charset=utf-8`. A new
   `S3ContentTypeFilter` resets the encoding to `NOT_SET` to preserve the S3 wire format.
   
   **Reason phrases.** Jetty 12 discards custom HTTP reason phrases at the core level, so
   `S3SecretManagementEndpoint` moves its error code into a `text/plain` entity body.
   
   **TLS SNI.** Jetty 12 defaults `SecureRequestCustomizer#sniHostCheck` to true, which breaks
   Ozone's hostname-agnostic TLS endpoints; it is constructed with `false`.
   
   **Base resources.** Core `ContextHandler.doStart()` now throws for a missing base directory,
   where 9.4 tolerated it. The log directory is created best-effort and `/logs` is skipped rather
   than failing startup if unavailable; `/static` is served only when its base resource exists.
   
   **Weld / CDI.** Weld 3.1.9's `JettyLegacyContainer` detects on `org.eclipse.jetty.util.Decorator`,
   which still exists in jetty-util 12, so it is selected — then `LegacyWeldDecorator.process()`
   touches the deleted `org.eclipse.jetty.servlet.ServletContextHandler` and throws
   `NoClassDefFoundError`. Because that is an `Error`, Weld's `catch (Exception)` does not catch it
   and S3 Gateway context startup fails. Fixed with Jetty's canonical `jetty-ee8-cdi` module and a
   `CdiDecoratingListener`, which makes Weld's probe match `JettyContainer` first.
   
   The listener is installed on each of the three S3 Gateway contexts that register the Weld listener
   in their descriptor, guarded by `isEnabled()`: `BaseHttpServer` builds no `HttpServer2` at all for a
   disabled server, and `ozone.s3g.sts.http.enabled` is `false` by default, so an unguarded call would
   NPE and kill the whole gateway at startup. `BaseHttpServer.isEnabled()` is widened from private to
   protected for that check.
   
   **httpfs descriptors.** `<url-pattern>*</url-pattern>` is illegal per the Servlet spec and is
   corrected to `/*` (5 filter-mappings in each of the two descriptors).
   
   **hadoop-kms removed from integration-test.** `MiniKMS` embeds an unshaded Jetty 9 `Server` and
   cannot coexist with a Jetty 12 runtime. `TestOzoneAtRestEncryption` and `TestOzoneShellHA` now
   pre-seed a `JavaKeyStoreProvider` jceks before cluster start instead. The native secure-KMS path
   is followed up in HDDS-16424.
   
   ### New dist artifacts
   
   Beyond the expected EE8 set, the `jetty-ee8-cdi` choice pulls in `jetty-ee8-annotations`,
   `jetty-ee8-plus`, `jetty-plus`, `jetty-jndi` and — worth calling out explicitly —
   **`jakarta.transaction:jakarta.transaction-api`, a new third-party artifact in the
   distribution** (1.3.3, whose artifact name is literally "javax.transaction API"; EPL-2.0 +
   GPL2-w/-CPE, the same pairing as the `jakarta.annotation-api` already shipped).
   
   `jar-report.txt` and `bin/LICENSE.txt` are updated accordingly: `javax.servlet-api.jar`,
   `jetty-servlet.jar` and `jetty-webapp.jar` are removed; `jetty-servlet-api.jar`, `jetty-ee.jar`,
   `jetty-session.jar`, `jetty-jndi.jar`, `jetty-plus.jar`, `jakarta.transaction-api.jar` and the
   seven `jetty-ee8-*.jar` are added. `license.sh` reports no disallowed licenses and needs no
   `license.exceptions` entry.
   
   ### Known residuals (pre-existing, out of scope)
   
   - `org.eclipse.jetty.websocket:websocket-{api,client,common}:9.4.57` remain at **`test`** scope
     under `ozone-integration-test`. Not on any runtime or dist classpath.
   - `javax.servlet:servlet-api:2.5` reaches `ozone-filesystem-hadoop2` at **`provided`** scope via
     `hadoop-common:2.10.2`. This is the old Servlet 2.5 coordinate from the Hadoop 2.x
     compatibility module, absent from the distribution.
   
   Generated-by: Claude Code (claude-opus-5)
   
   ## What is the link to the Apache JIRA
   
   https://issues.apache.org/jira/browse/HDDS-8280
   
   ## How was this patch tested?
   
   CI: https://github.com/yandrey321/ozone/actions/runs/36659484942/job/109713286666
   
   Unit tests:
   
   - `hdds-server-framework`: `TestHttpServer2` (16), `TestHttpServer2SSL` (10), `TestBaseHttpServer` (7),
     `TestHttpServer2Metrics`, `TestHtmlQuoting`, `TestPrometheusServletAuthorization` — 43 tests, green.
     New coverage: URI-compliance admission at the wire level (including that `%2e%2e` and `%u` stay
     rejected under the relaxed mode), the base-resource/log-dir guards, and a
     `testDefaultServletsAnswer` that drives `/jmx`, `/conf`, `/stacks` and `/logLevel` over HTTP.
   - `ozone-s3gateway`: `TestS3ContentTypeFilter` (7, new), `TestS3GatewayHttpServers` (2, new),
     `TestGateway`, `TestSecretGenerate`, `TestSecretRevoke` — 17 tests, green. The new class asserts
     that an enabled context carries Jetty's `org.eclipse.jetty.cdi` attribute and that a disabled STS
     server is constructed without one.
   
   Integration tests:
   
   - `TestOzoneManagerHttpServer`, `TestEDEKCacheLoader` (new) — green.
   - `TestCpuMetrics`, `TestOzoneManagerRestInterface` — green.
   - `ProxyServerIntegrationTest` — green.
   - `TestS3SDK` (AWS SDK v1 + v2 against a live S3 Gateway) — 210 tests, green.
   - `TestS3GatewayHealthCheck` — 3 tests, green; starts a real `Gateway`, so it covers the CDI
     install path end to end in-process.
   - `TestOzoneAtRestEncryption` — 36 tests green.
   - `TestOzoneShellHA` — green.
   
   Build and checks: full reactor build and a wider `-Pdist` build (all 58 modules, shade + Recon +
   docs enabled) with `dependency:analyze-only` **enabled** — no "Used undeclared", "Unused declared"
   or "Non-test scoped" findings. `checkstyle.sh` clean, `rat.sh` clean, no `@author` tags.
   `dependency.sh`'s jar-report comparison is empty against a clean `-Pdist` build.
   
   Classpath assertions over the reactor: every `org.eclipse.jetty*` coordinate resolves to `12.0.38`
   (`4.0.9` for `jetty-servlet-api`); no `ee9`/`ee10`; `org.eclipse.jetty:jetty-servlet`,
   `jetty-webapp` and `jetty-proxy` resolve to nothing.
   
   Compose robot smoketests, against a dist built from this branch: `ozone` (369 assertions, 18
   suites) and `ozonesecure` (450 assertions) both pass with zero failures, covering Recon, httpfs, the
   S3 and secret suites and secure-mode SPNEGO.
   
   `ozone-om-ha` ships `disabled-test.sh` upstream, so `ozone-ha` is run in its place: 461 assertions
   pass, 15 fail. All 15 trace to a single datanode container dying mid-run in this local 13-container
   environment, not to the upgrade — each failure is an `AnnotatedNoRouteToHostException` against that
   datanode's address, its container log stops abruptly four minutes before the first failure with no
   shutdown sequence or exception, and `ozone-ha` never stops a datanode itself. The two multipart-upload
   tests among them had already passed twice earlier in the same run under the `OBJECT_STORE` and
   `LEGACY` layouts. Re-running the affected `FILE_SYSTEM_OPTIMIZED` s3 block against a fresh cluster
   passes 149/149, including all 13 `Buckettagging` tests and both multipart-upload tests.
   
   The admin endpoints were also swept directly against a running cluster. `/conf`, `/jmx`, `/prom`,
   `/logLevel`, `/stacks` and `/logs/` answer 200 on OM, SCM, Recon and the S3 Gateway web admin
   server, and on httpfs with `?user.name=`. `/static/` answers 403 because directory listing stays
   disabled, while a real asset under it (`/static/ozone.css`) answers 200. The S3 Gateway returns
   `Content-Type: application/xml` with no appended charset, confirming `S3ContentTypeFilter` at the
   wire level.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "adoroszlai (via GitHub)" <gi...@apache.org>.
adoroszlai merged PR #11367:
URL: https://github.com/apache/ozone/pull/11367


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "jojochuang (via GitHub)" <gi...@apache.org>.
jojochuang commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4141418856


##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/S3ContentTypeFilter.java:
##########
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.ozone.s3;
+
+import java.io.IOException;
+import java.util.Locale;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+/**
+ * Preserve the S3 Content-Type verbatim, without an auto-appended charset.
+ *
+ * <p>AWS S3 (and Ozone before the Jetty 12 upgrade) returns the Content-Type
+ * exactly as the gateway set it: the stored object type for GET/HEAD and a bare
+ * {@code application/xml} for the XML API/error responses, in both cases without
+ * a charset parameter unless one was explicitly stored.
+ *
+ * <p>On Jetty 12 the servlet response tracks a response character encoding
+ * ({@code _encodingFrom}). HttpServer2's global {@code QuotingInputFilter} runs
+ * first on every request and, for a request URI with no known extension (most
+ * object keys), defaults the response to {@code text/plain; charset=utf-8},
+ * promoting that encoding away from {@code NOT_SET}. Jetty then appends the
+ * tracked charset to any later <em>bare</em> Content-Type, so a stored
+ * {@code binary/octet-stream} or a bare {@code application/xml} goes out as
+ * {@code ...;charset=utf-8}. Stripping the charset from the header value does
+ * not help, because Jetty re-appends it from the tracked encoding after the
+ * wrapper runs.
+ *
+ * <p>This wrapper resets the tracked encoding back to {@code NOT_SET} (via
+ * {@code setCharacterEncoding(null)}) right before it writes a Content-Type
+ * that carries no {@code charset} parameter, so Jetty keeps that value bare. A
+ * Content-Type that already carries an explicit {@code charset} is written
+ * unchanged. In all cases the value itself is passed through verbatim, so the
+ * media type and any explicit charset are preserved.
+ */
+public class S3ContentTypeFilter implements Filter {
+
+  private static final String CONTENT_TYPE = "Content-Type";
+
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {
+  }
+
+  @Override
+  public void doFilter(
+      ServletRequest request, ServletResponse response, FilterChain chain
+  ) throws IOException, ServletException {
+    if (response instanceof HttpServletResponse) {
+      chain.doFilter(request, new VerbatimContentTypeResponse((HttpServletResponse) response));
+    } else {
+      chain.doFilter(request, response);
+    }
+  }
+
+  @Override
+  public void destroy() {
+  }
+
+  private static boolean hasCharset(String contentType) {
+    return contentType != null
+        && contentType.toLowerCase(Locale.ROOT).contains("charset=");

Review Comment:
   [P3] Check for an actual charset parameter
   
   `contains("charset=")` can match text inside another parameter's quoted value. For example, this valid Content-Type has a `name` parameter but no charset parameter:
   
   ```text
   application/octet-stream; name="charset=example"
   ```
   
   The filter incorrectly treats it as having an explicit charset and skips the encoding reset. Jetty then appends the UTF-8 encoding established by `QuotingInputFilter`:
   
   ```text
   application/octet-stream; name="charset=example";charset=utf-8
   ```
   
   I reproduced this with real servlet responses: Jetty 9 preserves the original header, while Jetty 12 with this filter returns the modified value. This changes the Content-Type returned for a stored S3 object. The reproduction used a servlet harness matching the encoding setup and this filter, rather than a full Ozone round-trip test.
   
   Could we parse the media-type parameters to detect an actual `charset` parameter, while forwarding the original header unchanged, and add a test for this quoted-value case?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "yandrey321 (via GitHub)" <gi...@apache.org>.
yandrey321 commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4146428634


##########
hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/TestS3GatewayHttpServers.java:
##########
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.ozone.s3;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.ozone.OzoneConfigKeys;
+import org.apache.hadoop.ozone.s3sts.S3STSConfigKeys;
+import org.apache.ozone.test.GenericTestUtils.PortAllocator;
+import org.eclipse.jetty.ee8.webapp.WebAppContext;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+/**
+ * Tests the CDI wiring of the S3 Gateway HTTP servers.
+ */
+class TestS3GatewayHttpServers {
+
+  /**
+   * Attribute Weld's JettyContainer probes for, set by CdiDecoratingListener.
+   */
+  private static final String CDI_ATTRIBUTE = "org.eclipse.jetty.cdi";
+  private static final String CDI_MODE = "CdiDecoratingListener";
+
+  @TempDir
+  private Path tempDir;
+
+  /**
+   * An enabled server gets Jetty's CDI integration attribute, without which
+   * Weld falls through to its legacy Jetty container and fails to start the
+   * context on Jetty 12.
+   */
+  @Test
+  void enabledServerInstallsCdiIntegrationAttribute() throws Exception {
+    OzoneConfiguration conf = newConf();
+    conf.set(S3GatewayConfigKeys.OZONE_S3G_HTTP_ADDRESS_KEY,
+        "127.0.0.1:" + PortAllocator.getFreePort());

Review Comment:
   fixed



##########
hadoop-hdds/docs/content/security/SecuringS3.md:
##########
@@ -68,6 +68,17 @@ the AWS credentials. The values will be printed out on the screen. You can
 set these values up in your _.aws_ file for automatic access while working
 against Ozone S3 buckets.
 
+If a secret already exists for the user, the endpoint responds with HTTP
+`400 Bad Request` and the error code `S3_SECRET_ALREADY_EXISTS` in the
+plain-text response body. The error code is carried in the body, not in the
+HTTP status line (reason phrase), so clients must read the body rather than
+parse the status message:
+```bash
+curl -X PUT --negotiate -u : -v https://localhost:9879/secret
+# < HTTP/1.1 400 Bad Request
+# S3_SECRET_ALREADY_EXISTS
+```
+

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "adoroszlai (via GitHub)" <gi...@apache.org>.
adoroszlai commented on PR #11367:
URL: https://github.com/apache/ozone/pull/11367#issuecomment-5934140540

   Thanks @yandrey321 for the patch, @ivandika3, @jojochuang, @peterxcli for the review.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "yandrey321 (via GitHub)" <gi...@apache.org>.
yandrey321 commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4147236765


##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3secret/S3SecretManagementEndpoint.java:
##########
@@ -76,7 +77,13 @@ private Response generateInternal(@Nullable String username) throws IOException
       AUDIT.logWriteFailure(buildAuditMessageForFailure(
           S3GAction.GENERATE_SECRET, getAuditParameters(), e));
       if (e.getResult() == OMException.ResultCodes.S3_SECRET_ALREADY_EXISTS) {
-        return Response.status(BAD_REQUEST.getStatusCode(), e.getResult().toString()).build();
+        // Jetty 12 no longer emits custom HTTP reason phrases, so convey the

Review Comment:
   How do we capture things that need to be added to the release notes for the next release?
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "yandrey321 (via GitHub)" <gi...@apache.org>.
yandrey321 commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4146426984


##########
hadoop-ozone/s3gateway/src/main/resources/webapps/s3gateway/WEB-INF/web.xml:
##########
@@ -36,6 +36,15 @@
     <filter-name>optional-content-type</filter-name>
     <url-pattern>/*</url-pattern>
   </filter-mapping>
+  <filter>
+    <filter-name>xml-content-type</filter-name>
+    <filter-class>org.apache.hadoop.ozone.s3.S3ContentTypeFilter
+    </filter-class>

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "yandrey321 (via GitHub)" <gi...@apache.org>.
yandrey321 commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4146431922


##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/S3ContentTypeFilter.java:
##########
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.ozone.s3;
+
+import java.io.IOException;
+import java.util.Locale;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+/**
+ * Preserve the S3 Content-Type verbatim, without an auto-appended charset.
+ *
+ * <p>AWS S3 (and Ozone before the Jetty 12 upgrade) returns the Content-Type
+ * exactly as the gateway set it: the stored object type for GET/HEAD and a bare
+ * {@code application/xml} for the XML API/error responses, in both cases without
+ * a charset parameter unless one was explicitly stored.
+ *
+ * <p>On Jetty 12 the servlet response tracks a response character encoding
+ * ({@code _encodingFrom}). HttpServer2's global {@code QuotingInputFilter} runs
+ * first on every request and, for a request URI with no known extension (most
+ * object keys), defaults the response to {@code text/plain; charset=utf-8},
+ * promoting that encoding away from {@code NOT_SET}. Jetty then appends the
+ * tracked charset to any later <em>bare</em> Content-Type, so a stored
+ * {@code binary/octet-stream} or a bare {@code application/xml} goes out as
+ * {@code ...;charset=utf-8}. Stripping the charset from the header value does
+ * not help, because Jetty re-appends it from the tracked encoding after the
+ * wrapper runs.
+ *
+ * <p>This wrapper resets the tracked encoding back to {@code NOT_SET} (via
+ * {@code setCharacterEncoding(null)}) right before it writes a Content-Type
+ * that carries no {@code charset} parameter, so Jetty keeps that value bare. A
+ * Content-Type that already carries an explicit {@code charset} is written
+ * unchanged. In all cases the value itself is passed through verbatim, so the
+ * media type and any explicit charset are preserved.
+ */
+public class S3ContentTypeFilter implements Filter {
+
+  private static final String CONTENT_TYPE = "Content-Type";
+
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {
+  }
+
+  @Override
+  public void doFilter(
+      ServletRequest request, ServletResponse response, FilterChain chain
+  ) throws IOException, ServletException {
+    if (response instanceof HttpServletResponse) {
+      chain.doFilter(request, new VerbatimContentTypeResponse((HttpServletResponse) response));
+    } else {
+      chain.doFilter(request, response);
+    }
+  }
+
+  @Override
+  public void destroy() {
+  }
+
+  private static boolean hasCharset(String contentType) {
+    return contentType != null
+        && contentType.toLowerCase(Locale.ROOT).contains("charset=");

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "yandrey321 (via GitHub)" <gi...@apache.org>.
yandrey321 commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4145390888


##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/HttpServer2.java:
##########
@@ -549,7 +587,14 @@ private ServerConnector createHttpChannelConnector(
     private ServerConnector createHttpsChannelConnector(
         Server server, HttpConfiguration httpConfig) {
       httpConfig.setSecureScheme(HTTPS_SCHEME);
-      httpConfig.addCustomizer(new SecureRequestCustomizer());
+      // Jetty 12's SecureRequestCustomizer defaults to sniHostCheck=true, which
+      // rejects every HTTPS request whose Host (or SNI) is not carried by the
+      // served certificate with a 400 "Invalid SNI" -- including requests to an
+      // IP literal (which send no SNI) or to localhost/VIP/alias names absent
+      // from the keystore certificate. Jetty 9.4 only ran that check when the
+      // client's SNI matched a certificate, so such requests were served with
+      // the default certificate. Disable the check to preserve that behaviour.
+      httpConfig.addCustomizer(new SecureRequestCustomizer(false));

Review Comment:
   I can pick up https://issues.apache.org/jira/browse/HDDS-9878 and add make it configurable.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "adoroszlai (via GitHub)" <gi...@apache.org>.
adoroszlai commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4143782421


##########
hadoop-hdds/docs/content/security/SecuringS3.md:
##########
@@ -68,6 +68,17 @@ the AWS credentials. The values will be printed out on the screen. You can
 set these values up in your _.aws_ file for automatic access while working
 against Ozone S3 buckets.
 
+If a secret already exists for the user, the endpoint responds with HTTP
+`400 Bad Request` and the error code `S3_SECRET_ALREADY_EXISTS` in the
+plain-text response body. The error code is carried in the body, not in the
+HTTP status line (reason phrase), so clients must read the body rather than
+parse the status message:
+```bash
+curl -X PUT --negotiate -u : -v https://localhost:9879/secret
+# < HTTP/1.1 400 Bad Request
+# S3_SECRET_ALREADY_EXISTS
+```
+

Review Comment:
   Please don't update docs here, they are being removed in #10829.  Update it, if needed, in `ozone-site` repo.



##########
hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/TestS3GatewayHttpServers.java:
##########
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.ozone.s3;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.ozone.OzoneConfigKeys;
+import org.apache.hadoop.ozone.s3sts.S3STSConfigKeys;
+import org.apache.ozone.test.GenericTestUtils.PortAllocator;
+import org.eclipse.jetty.ee8.webapp.WebAppContext;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+/**
+ * Tests the CDI wiring of the S3 Gateway HTTP servers.
+ */
+class TestS3GatewayHttpServers {
+
+  /**
+   * Attribute Weld's JettyContainer probes for, set by CdiDecoratingListener.
+   */
+  private static final String CDI_ATTRIBUTE = "org.eclipse.jetty.cdi";
+  private static final String CDI_MODE = "CdiDecoratingListener";
+
+  @TempDir
+  private Path tempDir;
+
+  /**
+   * An enabled server gets Jetty's CDI integration attribute, without which
+   * Weld falls through to its legacy Jetty container and fails to start the
+   * context on Jetty 12.
+   */
+  @Test
+  void enabledServerInstallsCdiIntegrationAttribute() throws Exception {
+    OzoneConfiguration conf = newConf();
+    conf.set(S3GatewayConfigKeys.OZONE_S3G_HTTP_ADDRESS_KEY,
+        "127.0.0.1:" + PortAllocator.getFreePort());

Review Comment:
   ```suggestion
           PortAllocator.localhostWithFreePort());
   ```



##########
hadoop-ozone/s3gateway/src/main/resources/webapps/s3gateway/WEB-INF/web.xml:
##########
@@ -36,6 +36,15 @@
     <filter-name>optional-content-type</filter-name>
     <url-pattern>/*</url-pattern>
   </filter-mapping>
+  <filter>
+    <filter-name>xml-content-type</filter-name>
+    <filter-class>org.apache.hadoop.ozone.s3.S3ContentTypeFilter
+    </filter-class>

Review Comment:
   nit:
   
   ```suggestion
       <filter-class>org.apache.hadoop.ozone.s3.S3ContentTypeFilter</filter-class>
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "jojochuang (via GitHub)" <gi...@apache.org>.
jojochuang commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4147178343


##########
hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3secret/S3SecretManagementEndpoint.java:
##########
@@ -76,7 +77,13 @@ private Response generateInternal(@Nullable String username) throws IOException
       AUDIT.logWriteFailure(buildAuditMessageForFailure(
           S3GAction.GENERATE_SECRET, getAuditParameters(), e));
       if (e.getResult() == OMException.ResultCodes.S3_SECRET_ALREADY_EXISTS) {
-        return Response.status(BAD_REQUEST.getStatusCode(), e.getResult().toString()).build();
+        // Jetty 12 no longer emits custom HTTP reason phrases, so convey the

Review Comment:
   this needs a release note.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "yandrey321 (via GitHub)" <gi...@apache.org>.
yandrey321 commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4147242325


##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/BaseHttpServer.java:
##########
@@ -191,15 +192,33 @@ public BaseHttpServer(MutableConfigurationSource conf, String name)
         baseDir = getOzoneMetaDirPath(conf) + SERVER_DIR;
       }
       createDir(baseDir);
-      httpServer.getWebAppContext().setAttribute(JETTY_BASETMPDIR, baseDir);
+      WebAppContext webAppContext = httpServer.getWebAppContext();
+      // Jetty 9 used the "basetempdir" attribute, so each WebAppContext got its

Review Comment:
   File a follow up JIRA?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "yandrey321 (via GitHub)" <gi...@apache.org>.
yandrey321 commented on PR #11367:
URL: https://github.com/apache/ozone/pull/11367#issuecomment-5920039369

   Acceptance test failed on pulling artifact from the repository, need to re-run.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "adoroszlai (via GitHub)" <gi...@apache.org>.
adoroszlai commented on PR #11367:
URL: https://github.com/apache/ozone/pull/11367#issuecomment-5927224689

   @ivandika3 @peterxcli would you like to take a look?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "jojochuang (via GitHub)" <gi...@apache.org>.
jojochuang commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4147000460


##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/BaseHttpServer.java:
##########
@@ -191,15 +192,33 @@ public BaseHttpServer(MutableConfigurationSource conf, String name)
         baseDir = getOzoneMetaDirPath(conf) + SERVER_DIR;
       }
       createDir(baseDir);
-      httpServer.getWebAppContext().setAttribute(JETTY_BASETMPDIR, baseDir);
+      WebAppContext webAppContext = httpServer.getWebAppContext();
+      // Jetty 9 used the "basetempdir" attribute, so each WebAppContext got its

Review Comment:
   It might cause problem for users with high security requirement, where they configure directories to be noexec. nonexec dir becomes trouble when Jetty loads native lib into it (required for openssl, for example).
   
   Not totally sure about that. We can look into it later.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "yandrey321 (via GitHub)" <gi...@apache.org>.
yandrey321 commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4146434425


##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/HttpServer2.java:
##########
@@ -172,6 +172,29 @@ public final class HttpServer2 implements FilterContainer {
   private static final int HTTP_IDLE_TIMEOUT_MS_DEFAULT = 60000;
   private static final String HTTP_TEMP_DIR_KEY = "hadoop.http.temp.dir";
 
+  /**
+   * URI compliance mode used when {@code allowAmbiguousUri} is set. S3 object
+   * keys and WebHDFS paths legitimately contain empty path segments ("//"),
+   * percent encodings ("%25"), encoded path separators, and after decoding a
+   * backslash or other suspicious character (DEL and C0 controls), all of which
+   * Jetty 12 rejects with 400 by default. Jetty 9.4 (pre-migration) had no such
+   * check and passed these through, so relax those four violations to keep that
+   * behavior; a decoded backslash or control byte is opaque key/path data in
+   * Ozone (which uses only "/" as a separator), so it does not open path
+   * traversal. Rather than Jetty's broad LEGACY mode -- which would also
+   * re-admit %2e/%2e%2e path traversal, UTF-16 and truncated UTF-8 encodings and
+   * userinfo on the internet-facing S3 Gateway and HttpFS -- relax only those
+   * violations the use case needs. Genuinely illegal (unencoded) URI characters
+   * such as "[" and "]" remain rejected, since conforming clients percent-encode
+   * them.
+   */
+  private static final UriCompliance OZONE_AMBIGUOUS_URI_COMPLIANCE =
+      UriCompliance.DEFAULT.with("OZONE",
+          UriCompliance.Violation.AMBIGUOUS_EMPTY_SEGMENT,
+          UriCompliance.Violation.AMBIGUOUS_PATH_ENCODING,
+          UriCompliance.Violation.AMBIGUOUS_PATH_SEPARATOR,
+          UriCompliance.Violation.SUSPICIOUS_PATH_CHARACTERS);

Review Comment:
   fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "jojochuang (via GitHub)" <gi...@apache.org>.
jojochuang commented on PR #11367:
URL: https://github.com/apache/ozone/pull/11367#issuecomment-5904969529

   Thanks a lot for the work!! One test we should run after merge is s3 compatibility test. Make sure s3 is backward compatible.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "jojochuang (via GitHub)" <gi...@apache.org>.
jojochuang commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4141294822


##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/HttpServer2.java:
##########
@@ -172,6 +172,29 @@ public final class HttpServer2 implements FilterContainer {
   private static final int HTTP_IDLE_TIMEOUT_MS_DEFAULT = 60000;
   private static final String HTTP_TEMP_DIR_KEY = "hadoop.http.temp.dir";
 
+  /**
+   * URI compliance mode used when {@code allowAmbiguousUri} is set. S3 object
+   * keys and WebHDFS paths legitimately contain empty path segments ("//"),
+   * percent encodings ("%25"), encoded path separators, and after decoding a
+   * backslash or other suspicious character (DEL and C0 controls), all of which
+   * Jetty 12 rejects with 400 by default. Jetty 9.4 (pre-migration) had no such
+   * check and passed these through, so relax those four violations to keep that
+   * behavior; a decoded backslash or control byte is opaque key/path data in
+   * Ozone (which uses only "/" as a separator), so it does not open path
+   * traversal. Rather than Jetty's broad LEGACY mode -- which would also
+   * re-admit %2e/%2e%2e path traversal, UTF-16 and truncated UTF-8 encodings and
+   * userinfo on the internet-facing S3 Gateway and HttpFS -- relax only those
+   * violations the use case needs. Genuinely illegal (unencoded) URI characters
+   * such as "[" and "]" remain rejected, since conforming clients percent-encode
+   * them.
+   */
+  private static final UriCompliance OZONE_AMBIGUOUS_URI_COMPLIANCE =
+      UriCompliance.DEFAULT.with("OZONE",
+          UriCompliance.Violation.AMBIGUOUS_EMPTY_SEGMENT,
+          UriCompliance.Violation.AMBIGUOUS_PATH_ENCODING,
+          UriCompliance.Violation.AMBIGUOUS_PATH_SEPARATOR,
+          UriCompliance.Violation.SUSPICIOUS_PATH_CHARACTERS);

Review Comment:
   [P2] Preserve encoded dot segments in S3 object keys
   
   `shouldAllowAmbiguousUri()` returning true selects the four explicitly allowed violations here; it does not allow every ambiguity type. `AMBIGUOUS_PATH_SEGMENT` is still excluded, so a request for key `dir/./file.txt` encoded as `/bucket/dir/%2e/file.txt` receives HTTP 400 before reaching the S3 endpoint. OBS buckets preserve these segments as part of the key. AWS documents period-only segments and qualifying relative segments as valid key components: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html
   
   I reproduced the connector behavior with isolated JDK 21 wire probes: Jetty 9.4.58 accepts `/bucket/dir/%2e/file` and `/bucket/dir/%2e%2e/file` and preserves their request URIs, whereas Jetty 12.0.38 with this patch's exact relaxed compliance configuration returns 400. This was a connector-level reproduction, not a full Ozone round-trip test.
   
   Suggested fix: allow `UriCompliance.Violation.AMBIGUOUS_PATH_SEGMENT` in a separate S3-specific compliance mode. Since the current relaxed mode is shared with HttpFS, adding it directly to this constant would also change HttpFS behavior; retain HttpFS's existing restrictions.
   
   Please add PUT/GET/DELETE round-trip coverage through a backend gateway directly, bypassing the test proxy, for encoded dot segments in keys such as `dir/./file.txt` and `dir/../file.txt`. Verify that these remain distinct from `dir/file.txt` and `file.txt`, respectively. This validates that admitting the requests also preserves the key through Jetty/Jersey rather than normalizing it during dispatch.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org


Re: [PR] HDDS-8280. Upgrade Jetty 9.4 to 12.0.38 (EE8) [ozone]

Posted by "jojochuang (via GitHub)" <gi...@apache.org>.
jojochuang commented on code in PR #11367:
URL: https://github.com/apache/ozone/pull/11367#discussion_r4141366813


##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/HttpServer2.java:
##########
@@ -549,7 +587,14 @@ private ServerConnector createHttpChannelConnector(
     private ServerConnector createHttpsChannelConnector(
         Server server, HttpConfiguration httpConfig) {
       httpConfig.setSecureScheme(HTTPS_SCHEME);
-      httpConfig.addCustomizer(new SecureRequestCustomizer());
+      // Jetty 12's SecureRequestCustomizer defaults to sniHostCheck=true, which
+      // rejects every HTTPS request whose Host (or SNI) is not carried by the
+      // served certificate with a 400 "Invalid SNI" -- including requests to an
+      // IP literal (which send no SNI) or to localhost/VIP/alias names absent
+      // from the keystore certificate. Jetty 9.4 only ran that check when the
+      // client's SNI matched a certificate, so such requests were served with
+      // the default certificate. Disable the check to preserve that behaviour.
+      httpConfig.addCustomizer(new SecureRequestCustomizer(false));

Review Comment:
   We might want to make this configurable
   See: https://issues.apache.org/jira/browse/HADOOP-16718
   https://issues.apache.org/jira/browse/HDDS-9878



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org