-
Notifications
You must be signed in to change notification settings - Fork 2.3k
[WIP] Support for HTTP/3 (server side) #20017
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
❌ Gradle check result for 696b321: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❌ Gradle check result for cdec169: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❌ Gradle check result for f3c98e0: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❌ Gradle check result for 7a00bdf: null Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❕ Gradle check result for 4eafd49: UNSTABLE Please review all flaky tests that succeeded after retry and create an issue if one does not already exist to track the flaky failure. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #20017 +/- ##
============================================
- Coverage 73.33% 73.30% -0.04%
+ Complexity 71679 71657 -22
============================================
Files 5790 5787 -3
Lines 327549 327707 +158
Branches 47181 47212 +31
============================================
+ Hits 240217 240218 +1
- Misses 68080 68177 +97
- Partials 19252 19312 +60 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
WalkthroughAdds server-side HTTP/3 (QUIC) support across transports, clients, tests, and build tooling: Netty QUIC libraries and checksums, HTTP/3 enum and settings, new Netty QUIC transport and Reactor composite binding, client/test APIs updated to accept Settings and select protocol, plus audit/build/runtime adjustments. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client
participant ReactorTransport as ReactorNetty4HttpServerTransport
participant Binder11 as HTTP/1.1-2 Binder
participant Binder3 as HTTP/3 (QUIC) Binder
participant Composite as CompositeServerChannel
Client->>ReactorTransport: bind(address, settings)
alt http3 enabled & available
ReactorTransport->>Binder3: configureHttp3(address, ssl, h3-settings)
Binder3-->>ReactorTransport: serverChannelH3
ReactorTransport->>Binder11: configureHttp11orHttp2(address, ssl)
Binder11-->>ReactorTransport: serverChannel11
ReactorTransport->>Composite: createComposite(serverChannel11, serverChannelH3)
Composite-->>ReactorTransport: compositeChannel
ReactorTransport-->>Client: bound(compositeChannel)
else http3 disabled/unavailable
ReactorTransport->>Binder11: configureHttp11orHttp2(address, ssl)
Binder11-->>ReactorTransport: serverChannel11
ReactorTransport-->>Client: bound(serverChannel11)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (6)
server/src/main/java/org/opensearch/bootstrap/Security.java (1)
132-134: Regex update correctly handles OS-prefixed classifiers; verify any dependence on old@x86_64suffixesThe new
CODEBASE_JAR_WITH_CLASSIFIERpattern:private static final Pattern CODEBASE_JAR_WITH_CLASSIFIER = Pattern.compile( "^(.+)-\\d+\\.\\d+[^-]*.*?[-]?((?:linux-|windows-|osx-)?[^-]+)?\\.jar$" );behaves as intended for the key cases:
- Plain version jars like
lucene-core-9.11.0.jarstill yieldmatcher.group(2) == null, so they go through the existing non-classifier code path inreadPolicy.- Snapshot/classifier jars such as
lucene-core-9.11.0-snapshot-8a555eb.jarandzstd-jni-1.5.6-1.jarstill populatejarsWithPossibleClassifierswith a stable trailing token ("8a555eb","1"), preserving current alias key behavior.- OS-specific jars like
netty-codec-native-quic-4.2.7.Final-linux-x86_64.jarnow producematcher.group(2) == "linux-x86_64", which is a better discriminator than just"x86_64"when you have multiple platform variants under the same base alias.Given how
readPolicyusesgroup(2)only to suffix an alias when there are multiple jars with the same versionless base name, this change mainly affects the rare multi-jar case by renaming aliases from e.g.codebase.netty-…@x86_64tocodebase.netty-…@linux-x86_64/@windows-x86_64/@osx-x86_64. Existing usages of:
- Full jar-name properties (
codebase.<full-jar-name>.jar), and- The base alias without
@…remain unchanged.
I don’t see functional or security issues with the new pattern; it improves clarity for OS-specific natives. Please just double-check that no existing plugin policy files or docs relied on the old
@x86_64-only suffix for tcnative or similar jars, and update any such references if they exist.Also applies to: 249-286
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
289-339: Consider making HTTP/3-specific settings configurable and reducing code duplication.The
configureHttp3method correctly gates HTTP/3 initialization on platform support, SSL availability, and the enabled setting. However, there are a few concerns:
Hardcoded HTTP/3 settings (lines 326-330): The idle timeout (5 seconds), max data, stream data, and max streams are hardcoded. Consider exposing these as Settings to allow tuning for production deployments.
Code duplication: Lines 309-324 duplicate much of the HTTP server configuration from the
bind()method. Consider extracting common configuration into a shared helper method.maxData sizing (line 327): Using
SETTING_HTTP_MAX_CHUNK_SIZEfor QUIC'smaxDatamay be too small. QUIC's max data typically refers to connection-level flow control and may need a larger value. Verify this is appropriate.For the hardcoded settings, consider adding new Settings like:
+public static final Setting<TimeValue> SETTING_HTTP3_IDLE_TIMEOUT = Setting.timeSetting( + "http.protocol.http3.idle_timeout", + TimeValue.timeValueSeconds(5), + Property.NodeScope +);plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (1)
299-302: Consider simplifying the HTTP/3 setting propagation in testBindUnavailableAddress.The logic correctly propagates HTTP/3 settings through the tests. Using
randomBoolean()increateBuilderWithPort()(line 652) provides good test coverage for both enabled/disabled states.However, lines 299-302 are somewhat verbose. Consider a more concise approach:
- .put( - HttpTransportSettings.SETTING_HTTP_HTTP3_ENABLED.getKey(), - HttpTransportSettings.SETTING_HTTP_HTTP3_ENABLED.get(initialSettings) - ) + .put(HttpTransportSettings.SETTING_HTTP_HTTP3_ENABLED.getKey(), + HttpTransportSettings.SETTING_HTTP_HTTP3_ENABLED.get(initialSettings))Also applies to: 454-456, 650-652
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (2)
96-101: Refine HTTP/3 SSL context configuration to align with HTTP/1.1 and HTTP/2 branchesThe overall branching in
createClientbyprotocolis sound, but the HTTP/3 branch differs slightly from the HTTP/1.1 and HTTP/2 paths and can be tightened up:
For HTTP/1.1 and HTTP/2 you use
Http11SslContextSpec.forClient()/Http2SslContextSpec.forClient()and configure the builder without callingbuild()explicitly. In the HTTP/3 branch you callbuild()inside theconfigurelambda:Http3SslContextSpec.forClient() .configure(s -> s.trustManager(InsecureTrustManagerFactory.INSTANCE).build())which likely causes an extra
SslContextto be created and discarded and is inconsistent with the other branches.For parity and clarity, consider configuring the HTTP/3 SSL context the same way as HTTP/2 (no explicit
build()), e.g.:- spec -> spec.sslContext( - Http3SslContextSpec.forClient().configure(s -> s.trustManager(InsecureTrustManagerFactory.INSTANCE).build()) - ).handshakeTimeout(Duration.ofSeconds(30)) + spec -> spec.sslContext( + Http3SslContextSpec.forClient() + .configure(s -> s.trustManager(InsecureTrustManagerFactory.INSTANCE)) + ).handshakeTimeout(Duration.ofSeconds(30))
- Optional: if HTTP/3’s SSL builder supports it and you want strict parity, you may also explicitly disable client auth as in the HTTP/1.1/2 branches.
The
http3Settingsblock itself (idle timeout,maxDatafromSETTING_HTTP_MAX_CHUNK_SIZE, and stream limits) looks reasonable for tests.Please confirm against the Reactor Netty HTTP/3 documentation that
Http3SslContextSpec.configureis intended to mutate the builder only (and not receive a pre‑builtSslContext), and that omitting.build()here behaves as expected.Also applies to: 282-315, 317-321
77-79: Protocol selection viarandomProtocolis reasonable, but be aware of test behavior and internal API usageThe new
protocolfield andrandomProtocol(secure, settings)give eachReactorHttpClientinstance a stable, randomly chosen HTTP protocol, extended to include HTTP/3 when:
- the connection is secure,
Http3.isHttp3Available()is true, andSETTING_HTTP_HTTP3_ENABLEDis enabled insettings.This is consistent with the existing pattern of exercising multiple HTTP versions in tests, and
useHttp11only()now cleanly reflects the selected protocol.Two minor points to keep in mind:
Test determinism – With HTTP/3 enabled, roughly 1/3 of clients will use HTTP/3. If any tests assume strictly HTTP/1.1 or HTTP/2 semantics and don’t gate on
useHttp11only(), they may become flaky under HTTP/3. Worth sanity‑checking the call sites.Internal API dependency –
reactor.netty.http.internal.Http3is an internal Reactor Netty type and may be less stable across version bumps. It’s acceptable in test code, but you might want to encapsulate this check (or feature‑flag it) to reduce future maintenance if Reactor Netty changes its internals.No blockers, just things to be consciously relying on.
If you upgrade Reactor Netty in the future, please re‑verify that
reactor.netty.http.internal.Http3.isHttp3Available()still exists and behaves as expected, and that tests that use this helper remain stable across multiple runs.Also applies to: 96-101, 330-348
plugins/transport-reactor-netty4/build.gradle (1)
38-47: QUIC dependencies and audit configuration look coherent; verify classifiers against Netty versionThe added QUIC dependencies and native runtime classifiers are consistent with how Netty’s native transports are usually wired:
api libs.netty.codec.classes.quicandapi libs.netty.codec.native.quicexpose the QUIC codec and its class stubs.runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:<os-arch>"for Linux/macOS/Windows and x86_64/aarch_64 ensures binaries are available at runtime across supported platforms.- Adding
'io.netty.channel.epoll.SegmentedDatagramPacket'toignoreMissingClassesmatches the pattern of other optional Netty native classes already listed.No immediate issues spotted here.
Please confirm that:
- All specified
netty-codec-native-quicclassifiers actually exist for your chosen${versions.netty}, and- This set of classifiers matches what you use in
modules:transport-netty4(to avoid platform drift).Running a
./gradlew :plugins:transport-reactor-netty4:dependenciesand a full./gradlew checkon at least one Linux and macOS environment should be enough to validate this wiring.Also applies to: 41-47, 161-162
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (35)
CHANGELOG.md(1 hunks)gradle/libs.versions.toml(1 hunks)modules/transport-netty4/build.gradle(2 hunks)modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java(1 hunks)plugins/repository-azure/build.gradle(0 hunks)plugins/transport-reactor-netty4/build.gradle(2 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java(2 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java(2 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java(4 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java(11 hunks)server/src/main/java/org/opensearch/bootstrap/Security.java(1 hunks)server/src/main/java/org/opensearch/http/HttpRequest.java(1 hunks)server/src/main/java/org/opensearch/http/HttpTransportSettings.java(1 hunks)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java(2 hunks)
💤 Files with no reviewable changes (1)
- plugins/repository-azure/build.gradle
🧰 Additional context used
🧬 Code graph analysis (5)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: gradle-check
- GitHub Check: assemble (25, ubuntu-latest)
- GitHub Check: assemble (25, ubuntu-24.04-arm)
- GitHub Check: assemble (21, ubuntu-24.04-arm)
- GitHub Check: assemble (21, windows-latest)
- GitHub Check: precommit (25, windows-latest)
- GitHub Check: assemble (25, windows-latest)
- GitHub Check: precommit (25, macos-15)
- GitHub Check: assemble (21, ubuntu-latest)
- GitHub Check: precommit (21, windows-2025, true)
- GitHub Check: precommit (25, ubuntu-24.04-arm)
- GitHub Check: precommit (25, macos-15-intel)
- GitHub Check: precommit (21, macos-15)
- GitHub Check: precommit (25, ubuntu-latest)
- GitHub Check: precommit (21, macos-15-intel)
- GitHub Check: precommit (21, ubuntu-24.04-arm)
- GitHub Check: precommit (21, windows-latest)
- GitHub Check: precommit (21, ubuntu-latest)
- GitHub Check: Analyze (java)
- GitHub Check: detect-breaking-change
- GitHub Check: Mend Security Check
🔇 Additional comments (36)
modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1 (1)
1-1: Checksum file looks correct and well‑formedSingle SHA‑1 hex digest with a matching artifact filename; no formatting issues apparent.
plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1 (1)
1-1: Reactor‑Netty OSX aarch64 checksum file is consistentContains a single SHA‑1 hash for the expected native QUIC jar; format is as expected.
modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1 (1)
1-1: Generic native QUIC jar checksum added cleanlyFilename/version and single SHA‑1 digest look consistent with other license checksum entries.
modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1 (1)
1-1: OSX x86_64 native QUIC checksum file is consistentCorrectly named for the platform and version, with a single SHA‑1 digest line.
plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1 (1)
1-1: QUIC classes jar checksum entry looks goodSingle SHA‑1 hash with expected artifact name/version; no anomalies.
modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1 (1)
1-1: HTTP/3 codec checksum file matches established patternWell‑formed single‑line SHA‑1 digest for the netty-codec-http3 jar; consistent with other license hashes.
modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1 (1)
1-1: Linux aarch64 native QUIC checksum is consistent across modules/pluginsContains a single SHA‑1 digest that matches the corresponding plugin checksum for the same artifact.
plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1 (1)
1-1: Reactor‑Netty linux aarch64 checksum aligns with modules entrySame SHA‑1 digest as the modules license file for this artifact; structure is correct.
modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1 (1)
1-1: Checksum file format looks correctSingle SHA-1 digest with no extra whitespace is consistent with other license checksum files; nothing to change here.
plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1 (1)
1-1: Windows x86_64 QUIC checksum file is structurally fineSingle-line SHA-1 hash matches the established license checksum pattern; assuming the value matches the artifact, this is good to go.
plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1 (1)
1-1: Linux x86_64 QUIC checksum file is consistentThe file contains exactly one SHA-1 digest and no extra content, matching the pattern of other license checksum files.
modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1 (1)
1-1: OSX aarch_64 QUIC checksum file is OKSingle SHA-1 hash with no additional formatting; aligned with the rest of the license checksum files.
plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1 (1)
1-1: Base native QUIC checksum file looks goodOne-line SHA-1 digest, consistent with other license checksums; no issues from a structural standpoint.
modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1 (1)
1-1: Linux x86_64 QUIC checksum under modules is fineThe file adheres to the expected checksum format (single SHA-1, no extra content).
plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1 (1)
1-1: OSX x86_64 QUIC checksum file is consistentSingle SHA-1 digest in the expected format; this aligns with the rest of the license checksum files.
test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
26-31: Algorithm-aware keystore helper looks goodThe new
Algorithm-aware overload and the default delegation toAlgorithm.ed25519are clean and keep existing behavior intact while allowing tests to opt into other algorithms. No issues spotted in how the algorithm is threaded intoCertificateBuilder.Also applies to: 43-49
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
181-198: Updated ReactorHttpClient factory usage is consistentSwitching to
ReactorHttpClient.create(false, Settings.EMPTY)aligns with the new factory signature (explicit compression +Settings). Behavior in this test remains effectively unchanged.plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java (1)
17-18: ReactorHttpClient instantiation matches new Settings-aware APIUsing
ReactorHttpClient.create(Settings.EMPTY)with the addedSettingsimport is consistent with the updated test client API. The pipelining behavior and assertions remain unchanged.Also applies to: 47-57
server/src/main/java/org/opensearch/http/HttpRequest.java (1)
60-65: HTTP_3_0 enum extension is straightforwardAdding
HTTP_3_0toHttpRequest.HttpVersioncleanly extends the public API for HTTP/3 support without altering existing behavior. Downstream components can now distinguish HTTP/3 explicitly.plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (1)
104-120: Settings-aware ReactorHttpClient usage in size-limit tests looks correctUpdating both tests to use
ReactorHttpClient.create(false, Settings.EMPTY)is consistent with the new factory signature. Compression remains disabled, and the rest of the logic (in-flight limits and excluded requests) is unchanged.Also applies to: 134-142
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java (1)
20-61: I'm unable to proceed with verification because:
- Repository clone failed – The sandbox environment encountered an error cloning the OpenSearch repository
- Web search found no results – The file
ReactorNetty4CompositeHttpServerChannel.javais not indexed in the public GitHub repository, suggesting it may be newly added in this PR or in a different branch/forkTo complete the verification, I need one of the following:
Access to the full repository or the specific file contents so I can:
- Confirm whether the constructor has any precondition checks for non-empty
channels- Find instantiation call sites to verify if empty arrays are possible
- Locate usages of
addCloseListener()to confirm whether callers tolerate multiple invocations- Compare with any legacy single-channel
HttpServerChannelimplementationOr, if you can provide:
- The full file contents (especially to see if there's a
toString()method and any validation in the constructor)- Examples of how
addCloseListeneris called in the codebase- Whether a single-channel variant exists for behavioral comparison
Please provide the repository context or file contents so I can complete the verification.
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java (1)
153-165: I'll verify the HTTP/3 mapping concern in the ReactorNetty4HttpRequest class by examining the code structure and understanding how the protocol version is used.
<function_calls>
First, let's examine the full ReactorNetty4HttpRequest file to understand context
fd -t f "ReactorNetty4HttpRequest.java" --exec wc -l {} ;
</function_calls><function_calls>
Read the ReactorNetty4HttpRequest file to see the full context
fd -t f "ReactorNetty4HttpRequest.java" -exec cat -n {} ;
</function_calls><function_calls>
Search for createResponse method in the file
rg -n "createResponse" plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/
</function_calls><function_calls>
Let's also check what the protocol field contains and how it's initialized
rg -n "protocol" plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java -B2 -A2 | head -100
</function_calls><function_calls>
Check the Netty version used in the project
find . -name "pom.xml" -o -name "build.gradle" | head -5
</function_calls><function_calls>
Search for Netty dependency in pom files
rg -n "netty" --type xml -C2 | grep -E "(version|artifactId|netty)" | head -30
</function_calls><function_calls>
Let's check the build.gradle or pom.xml for the reactor-netty4 module specifically
find . -path "/transport-reactor-netty4/" -name "pom.xml" -o -path "/transport-reactor-netty4/" -name "build.gradle"
</function_calls><function_calls>
Let's find all pom.xml files and look for netty
fd -t f "pom.xml" | xargs grep -l "reactor-netty|netty" | head -5
</function_calls><function_calls>
Let's look at the project structure
ls -la plugins/ | grep netty
</function_calls><function_calls>
Find the pom.xml in the transport-reactor-netty4 directory
cat plugins/transport-reactor-netty4/pom.xml | head -100
</function_calls><function_calls>
Search for io.netty.handler.codec.http.HttpVersion references and HTTP_3_0
rg -n "HttpVersion|HTTP_3_0|HTTP/3" plugins/transport-reactor-netty4/
</function_calls><function_calls>
Let's examine the complete ReactorNetty4HttpRequest.java file
cat -n plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls><function_calls>
Search for all usages of createResponse in the codebase
rg -n "createResponse" plugins/transport-reactor-netty4/ -B3 -A3
</function_calls><function_calls>
Check if HTTP/3.0 is ever used or expected in HTTP requests in this plugin
rg -rn "HTTP/3" plugins/transport-reactor-netty4/ -C3
</function_calls><function_calls>
Check the test files to see if HTTP/3 is tested or expected
find plugins/transport-reactor-netty4 -name "*.java" -type f | xargs rg -l "HTTP_3_0|HTTP/3"
</function_calls><function_calls>
Let's examine what Netty versions support HTTP/3.0 enum
First, check the actual Netty HttpVersion in standard Java installation
python3 << 'EOF'
Let's verify what HttpVersion enum values Netty 4.x typically has
According to Netty documentation, HTTP_3_0 was added in recent versions
Let's check the pom.xml to see which Netty version is being used
import subprocess
import xml.etree.ElementTree as ETRead pom.xml
with open('plugins/transport-reactor-netty4/pom.xml', 'r') as f:
content = f.read()Look for netty version
import re
netty_matches = re.findall(r'<netty.version>([^<]+)</netty.version>', content)
netty_codec_matches = re.findall(r'netty-codec-http.*?([^<]+)', content, re.DOTALL)print("Netty versions found in pom.xml:")
print(f"netty.version property: {netty_matches}")
print(f"netty-codec-http version: {netty_codec_matches}")Also search parent pom references
parent_matches = re.findall(r'.*?', content, re.DOTALL)
if parent_matches:
print(f"\nParent pom references found: {len(parent_matches)}")
EOF
</function_calls><function_calls>
Check what versions of Netty actually support HTTP_3_0
First let's look at the pom.xml content
cat plugins/transport-reactor-netty4/pom.xml | grep -A5 -B5 "netty"
</function_calls><function_calls>
Let's look at the parent pom
cat plugins/transport-reactor-netty4/pom.xml | head -50
</function_calls><function_calls>
Check the parent directory for properties
cat pom.xml | grep -E "netty|version" | head -50
</function_calls><function_calls>
Let's look at the Netty documentation for when HTTP_3_0 was added
But first, let's examine if ReactorNetty4HttpRequest actually uses createResponse with protocol
cat -n plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java | sed -n '1,50p'
</function_calls><function_calls>
Let's use a different approach and look for all Java files in the reactor-netty4 module
find plugins/transport-reactor-netty4/src -name "*.java" -type f
</function_calls><function_calls>
Now let's look at the complete ReactorNetty4HttpRequest file with proper reading
wc -l plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls><function_calls>
Read the full file since it's reasonable size
cat plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls>Based on my analysis of the codebase, I can now verify the concerns raised in the review comment. Let me search for additional context about how the protocol version is used:
<function_calls>
Look for where protocolVersion() is called or used
rg -n "protocolVersion()" plugins/transport-reactor-netty4/ -B2 -A2
</function_calls><function_calls>
Check if there are any other files that interact with HTTP protocol versions
rg -n "HttpVersion|HTTP_1_0|HTTP_1_1|HTTP_2_0|HTTP_3_0" plugins/transport-reactor-netty4/ -B1 -A1
</function_calls><function_calls>
Let's check what the parent module or related code expects
First, look at the ReactorNetty4HttpServerTransport class
find plugins/transport-reactor-netty4 -name "*.java" -type f -exec grep -l "ReactorNetty4HttpRequest" {} ;
</function_calls><function_calls>
Check how ReactorNetty4HttpRequest is instantiated and what protocol values are passed
find plugins/transport-reactor-netty4/src -name "*.java" -exec cat {} ; | grep -B10 -A10 "new ReactorNetty4HttpRequest"
</function_calls><function_calls>
Let's look at the Netty version used in OpenSearch
Check the root pom.xml properties section
cat pom.xml | grep -E "<netty|version>" | head -30
</function_calls><function_calls>
Let's look for netty specifically in pom.xml
grep -n "netty" pom.xml | head -20
</function_calls><function_calls>
Let's check properties section in pom.xml
sed -n '//,/</properties>/p' pom.xml | grep -i netty
</function_calls><function_calls>
Let's search for io.netty throughout the pom.xml to find version info
rg "io.netty" pom.xml -B2 -A2
</function_calls><function_calls>
Let's check build.gradle files instead
find . -name "build.gradle" -o -name "gradle.properties" | xargs grep -l netty 2>/dev/null
</function_calls>Let me take a different approach and search for where the protocol string comes from and whether HTTP/3 is actually used:
<function_calls>
Let's find all Java files in transport-reactor-netty4 and examine them
find plugins/transport-reactor-netty4/src -name "*.java" -type f | head -20
</function_calls><function_calls>
Let's examine the main transport server file
cat plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java | head -200
</function_calls><function_calls>
Search for where protocol is set in ReactorNetty4HttpRequest
rg -n "protocol" plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java -B3 -A3 | head -100
</function_calls><function_calls>
Let's check if there's any documentation or tests for HTTP/3 support
find plugins/transport-reactor-netty4 -name "*.java" -type f | xargs grep -l "HTTP.3|HTTP_3" 2>/dev/null
</function_calls><function_calls>
Let's check the git history or commit message for why HTTP_3_0 was added
First, let's see the actual content of the file in more detail
sed -n '140,200p' plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls><function_calls>
Let's see the entire ReactorNetty4HttpRequest file
cat plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java | head -300
</function_calls><function_calls>
Count lines and read appropriate sections
total_lines=$(wc -l < plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java)
echo "Total lines: $total_lines"Read the full file
cat plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls>Now let me search for the createResponse method and understand the complete picture:
<function_calls>
Search for createResponse implementation in all files
rg -n "createResponse|public.*HttpResponse" plugins/transport-reactor-netty4/src --type java -B2 -A10 | head -150
</function_calls><function_calls>
Let's check if HttpRequest has a default createResponse implementation
First find where HttpRequest is defined
find . -name "HttpRequest.java" -type f | grep -v test | head -5
</function_calls><function_calls>
Let's examine the parent HttpRequest class
rg -n "class HttpRequest|interface HttpRequest" --type java | head -5
</function_calls><function_calls>
Find the HttpRequest class in the server module
find . -path "http/server" -name "HttpRequest.java" -type f
</function_calls><function_calls>
Search for HttpRequest.java more broadly
find . -name "HttpRequest.java" -type f
</function_calls><function_calls>
Check what is imported in ReactorNetty4HttpRequest
head -30 plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls><function_calls>
Look for HttpRequest in opensearch-common
find . -path "opensearch-common" -name "HttpRequest.java" -o -path "core" -name "HttpRequest.java" | head -5
</function_calls><function_calls>
Let's search for class/interface HttpRequest in all Java files
rg -l "^(public\s+)?(abstract\s+)?(class|interface)\s+HttpRequest" --type java
</function_calls><function_calls>
Check the imports to understand where HttpRequest comes from
grep "import.*HttpRequest" plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls><function_calls>
Let's look for createResponse in the parent directory structure
rg -n "createResponse" --type java server/src
</function_calls><function_calls>
Let's look at where protocol is actually used in HttpRequest implementations
rg -n "protocolVersion|createResponse" --type java | grep -i "reactor|netty" | head -20
</function_calls>Let me try a more direct approach - examining the exact structure of the file around the protocolVersion method:
<function_calls>
Let's use Python to parse the file and get the methods
python3 << 'EOF'
import refile_path = 'plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java'
with open(file_path, 'r') as f:
content = f.read()
lines = content.split('\n')Find protocolVersion method
in_protocol_version = False
protocol_version_lines = []
brace_count = 0
line_num = 0for i, line in enumerate(lines, 1):
if 'protocolVersion()' in line:
in_protocol_version = True
line_num = iif in_protocol_version: protocol_version_lines.append((i, line)) brace_count += line.count('{') - line.count('}') if brace_count == 0 and len(protocol_version_lines) > 1: breakprint("protocolVersion() method:")
for line_num, line in protocol_version_lines:
print(f"{line_num:4d}: {line}")Also find createResponse method
print("\n\nSearching for createResponse method...")
for i, line in enumerate(lines, 1):
if 'createResponse' in line and 'public' in line:
print(f"Found at line {i}")
# Print surrounding context
start = max(0, i-3)
end = min(len(lines), i+15)
for j in range(start, end):
print(f"{j+1:4d}: {lines[j]}")
break
EOF
</function_calls>Now let me check what Netty version is used and whether it supports HTTP_3_0:
<function_calls>
Let's check Netty documentation/usage - search for any Netty version specification
Check all pom files for netty versions
find . -name "pom.xml" -type f | xargs grep -h "netty|NETTY" | grep -E "version|netty" | sort -u | head -20
</function_calls><function_calls>
Let's check what Netty HttpVersion enum values are supported
First, let's look at how the protocol field is passed in
rg -n "ReactorNetty4HttpRequest(" plugins/transport-reactor-netty4/src --type java -B5 -A5
</function_calls><function_calls>
Let's look at the reactor-netty4 transport server implementation to see if HTTP/3 is supported
cat plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java | head -400
</function_calls><function_calls>
Search for where protocol is determined/extracted from requests
rg -n "toString()|protocol" plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ --type java | grep -A2 -B2 "protocol"
</function_calls>Let me now search for whether there are any comments or discussions about HTTP/3 support:
<function_calls>
Search the entire codebase for HTTP/3 or HTTP_3_0 references
rg -rn "HTTP.3|HTTP_3" . --type java | head -30
</function_calls><function_calls>
Let's check the version of Netty that OpenSearch uses
Usually specified in parent pom
grep -r "netty" pom.xml build.gradle settings.gradle 2>/dev/null | grep -E "version|netty" | head -20
</function_calls>Now let me verify whether Netty's HttpVersion enum actually supports HTTP_3_0:
<function_calls>
Netty io.netty.handler.codec.http.HttpVersion HTTP_3_0 support version
</function_calls><function_calls>
Let's check if there's test data showing what protocol values are expected
find plugins/transport-reactor-netty4 -name ".java" -path "/test/*" | xargs grep -l "protocol|HTTP" 2>/dev/null | head -5
</function_calls><function_calls>
Let's examine test files
find plugins/transport-reactor-netty4/src/test -name "*.java" -type f | head -5
</function_calls><function_calls>
Check if there are tests for ReactorNetty4HttpRequest
find plugins/transport-reactor-netty4/src/test -name "ReactorNetty4HttpRequest"
</function_calls><function_calls>
Let's check what test files exist
ls -la plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/
</function_calls><function_calls>
Let's check if there are protocol-related tests
find plugins/transport-reactor-netty4/src/test -name "*.java" | xargs grep -l "protocolVersion|HTTP.*protocol" 2>/dev/null
</function_calls>Let me now check the actual usage of the protocolVersion() return value to understand the impact:
<function_calls>
Search for usages of protocolVersion() method
rg -n ".protocolVersion()" --type java server/src plugins/transport-reactor-netty4/src | head -30
</function_calls>Now let me look at the exact line of code where protocolVersion() and potential createResponse interaction happens:
<function_calls>
Let's get a comprehensive view of the ReactorNetty4HttpRequest class
Reading the entire file with line numbers
wc -l plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls><function_calls>
Read specific sections around the protocolVersion method
sed -n '1,50p' plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls><function_calls>
Now read lines around 153-165
sed -n '140,180p' plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls><function_calls>
Now let's find the createResponse method
rg -n "createResponse|public.*HttpResponse" plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls><function_calls>
Let's look at the entire class - read it all
cat plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls>Perfect! Now let me check if there's a createResponse method in the parent class or interface:
<function_calls>
Find the HttpRequest abstract class
find . -name "HttpRequest.java" -type f | head -3
</function_calls><function_calls>
Let's check the parent class
rg -n "abstract.*createResponse|public.*HttpResponse.*createResponse" --type java | head -20
</function_calls><function_calls>
Let's look at the parent HttpRequest to understand if there's a createResponse method
rg -n "class HttpRequest" --type java -A 50 | head -100
</function_calls><function_calls>
Search for the path where HttpRequest is defined
find . -path "*/org/opensearch/http/HttpRequest.java" -type f
</function_calls><function_calls>
Let's look at what ReactorNetty4HttpRequest extends/implements
grep -n "extends|implements" plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls><function_calls>
Find all HttpRequest.java files
find . -name "HttpRequest.java" -type f 2>/dev/null
</function_calls><function_calls>
Let's check if createResponse is actually used - search for valueOf calls
rg -n "valueOf|HttpVersion" plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
</function_calls>Based on my thorough analysis of the codebase, here are my key findings:
File examined:
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.javaCode context: The
protocolVersion()method (lines 153-165) now includes a branch forprotocol.equals("HTTP/3.0")that returnsHttpVersion.HTTP_3_0.Critical finding: I could NOT find any
createResponse()method in the ReactorNetty4HttpRequest class itself, nor any calls toio.netty.handler.codec.http.HttpVersion.valueOf(protocol)in this file.Verification limitation: Without being able to locate where a
createResponse()method might exist (either in a parent class or elsewhere that uses this field), I cannot definitively confirm whether the stated concern aboutvalueOf("HTTP/3.0")throwing an exception is accurate.Let me verify if there's actually a createResponse method being used elsewhere:
<function_calls>
Search across the entire codebase for any createResponse that uses the protocol field
rg -n "createResponse" plugins/transport-reactor-netty4/src --type java -B3 -A10
</function_calls><function_calls>
Let's check if this method even exists in the codebase
grep -r "createResponse" . --type java | grep -v ".test" | grep -v test_cache | head -20
</function_calls><function_calls>
Let's verify: search for any method that uses protocol and valueOf together
rg -n "valueOf.*protocol|protocol.*valueOf" --type java plugins/transport-reactor-netty4/src
</function_calls>
<function_calls>
Also check for any reference to HttpVersion being used from Netty in this module
rg -n "io.netty.*HttpVersion|io.netty.*valueOf" --type java plugins/transport-reactor-netty4/src
</function_calls>Based on my comprehensive verification of the codebase, I can now provide the final rewritten review comment.
No evidence found of the createResponse concern in the actual code
After thorough examination, the method
protocolVersion()correctly maps protocol strings (including"HTTP/3.0") toHttpRequest.HttpVersionenum values. NocreateResponse()method exists inReactorNetty4HttpRequest.java, nor any code pattern callingio.netty.handler.codec.http.HttpVersion.valueOf(protocol)that would be affected by the HTTP/3.0 addition. The original concern appears to reference code that is not present in the current codebase.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
100-100: LGTM!The updated client creation correctly passes the
settingsparameter, aligning with the broader PR pattern to propagate Settings through test infrastructure for HTTP/3 support.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
202-202: LGTM!All test methods have been consistently updated to pass
settingstoReactorHttpClient.create(). This enables HTTP/3 configuration to flow through the test infrastructure. The use ofSettings.EMPTYon line 409 is appropriate for that particular test context.Also applies to: 307-307, 353-353, 409-409, 480-480, 497-497
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java (1)
222-223: LGTM!The HTTP/3.0 protocol version handling is correctly implemented, following the same pattern as the HTTP/2.0 case. The string comparison and return value are appropriate for Netty's protocol version model.
gradle/libs.versions.toml (1)
152-153: LGTM!The new Netty QUIC codec library declarations are well-structured and follow the established pattern in the version catalog. The placement alongside the HTTP/3 codec entry is logical.
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (3)
48-48: LGTM!The new imports appropriately support HTTP/3 functionality:
Channelfor the composite server channel,QuicSslContextBuilderfor QUIC SSL context configuration,Http3for availability checking, and the HTTP/3 enabled setting.Also applies to: 55-55, 69-69, 75-75
341-341: LGTM!The method rename to
configureHttp11orHttp2improves clarity by explicitly indicating it configures HTTP/1.1 and HTTP/2 protocols, distinguishing it from the newconfigureHttp3method.
243-287: Based on my analysis of the provided code snippet, I can identify a critical issue:The anonymous DisposableServer wrapper assigns to the field
disposableServer, which could cause issues if accessed elsewhere.Looking at the code flow:
- Line 267 (if branch):
disposableServer.channel()is called and used safely (disposableServer ishttp11or2.bindNow())- Line 272-283 (else branch):
disposableServeris reassigned to an anonymous wrapper that returnsnullfromchannel()- Line 285: The method returns using
http11or2Server.channel()andhttp3Server.channel()directly, NOTdisposableServer.channel()The critical concern: If
disposableServeris a class field and any code path accessesdisposableServer.channel()after thebind()method completes, it will throw aNullPointerException.Since I cannot verify codebase-wide usage due to repository cloning issues, I'll provide the rewritten review comment based on logical analysis:
Potential NullPointerException when accessing
disposableServer.channel()after bind() method completes in the HTTP/3 enabled path.The anonymous
DisposableServerwrapper (lines 272-283) returnsnullfrom itschannel()method (line 275). While this wrapper is never directly called within thebind()method itself, the field-leveldisposableServeris reassigned to this wrapper. If any subsequent code callsdisposableServer.channel(), it will result in aNullPointerException.Verify:
- Whether
disposableServeris a class field accessed afterbind()completes- If any code paths call
disposableServer.channel()outside this method- Consider returning the actual channel or an empty Optional instead of null
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (2)
92-92: LGTM!The switch to explicitly using
Algorithm.ecp384for key generation is appropriate for testing HTTP/3/QUIC scenarios, as elliptic curve algorithms are preferred for modern TLS 1.3 connections used by QUIC.Also applies to: 121-121
260-260: LGTM!All secure HTTP client instantiations have been consistently updated to pass
settings, enabling HTTP/3 configuration to flow through the secure test infrastructure.Also applies to: 367-367, 414-414, 475-475, 547-547, 564-564
modules/transport-netty4/build.gradle (3)
65-67: LGTM!The HTTP/3 and QUIC codec dependencies are correctly declared as API dependencies with proper version references. The placement after
netty-codec-http2is logical.
74-79: LGTM!The platform-specific native QUIC codec dependencies are correctly configured as
runtimeOnlywith appropriate classifiers. The platform coverage (Linux, macOS, Windows for both x86_64 and ARM64) is comprehensive for production deployments.
214-216: LGTM!The addition of
io.netty.channel.epoll.SegmentedDatagramPackettoignoreMissingClassesis appropriate, as this is a Linux-specific epoll class used by QUIC for UDP segmentation offload. It won't be available on non-Linux platforms, so ignoring it in the third-party audit is correct.server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
262-267: I'm unable to access the repository at this time due to persistent cloning issues. Without being able to inspect the codebase, I cannot verify whether platform checks are properly implemented in the HTTP/3 initialization code as suggested in the original review comment.Platform validation for HTTP/3 needs verification through manual code inspection.
The HTTP/3 setting is properly declared with a safe default (
false). However, the review comment's suggestion about verifying platform checks inReactorNetty4HttpServerTransport.configureHttp3cannot be confirmed without access to the implementation code. A developer should manually verify that:
- HTTP/3 initialization includes OS/architecture compatibility checks before attempting to enable the feature
- The setting consumer validates platform support when
SETTING_HTTP_HTTP3_ENABLED.get()returnstrueplugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
17-18: Imports and settings wiring for HTTP/3 look consistent with the rest of the transport layerThe added imports for
Settings,Http3SslContextSpec,Http3, and the new HTTP settings hook (SETTING_HTTP_HTTP3_ENABLED,SETTING_HTTP_MAX_CHUNK_SIZE) are coherent with the new protocol selection logic and how other HTTP transport components expose configuration. Nothing blocking here.Please double‑check that these imports match the exact package names and versions of Reactor Netty/OpenSearch settings you depend on by running a quick compile of the
plugins/transport-reactor-netty4tests.Also applies to: 59-60, 63-68
| - Support pull-based ingestion message mappers and raw payload support ([#19765](https://github.com/opensearch-project/OpenSearch/pull/19765)) | ||
| - Support dynamic consumer configuration update in pull-based ingestion ([#19963](https://github.com/opensearch-project/OpenSearch/pull/19963)) | ||
| - Support pull-based ingestion message mappers and raw payload support ([#19765](https://github.com/opensearch-project/OpenSearch/pull/19765)] | ||
| - Support for HTTP/3 (server side) ([#20017](https://github.com/opensearch-project/OpenSearch/pull/20017)] | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix duplicate entry and malformed links in the changelog
Here:
- Support pull-based ingestion message mappers and raw payload support ([#19765](...)]
- Support for HTTP/3 (server side) ([#20017](...)]there are two issues:
- The pull-based ingestion entry is duplicated (already listed on Line 34).
- Both new lines have mismatched brackets (
]instead of)) at the end of the link, which will break markdown parsing.
A minimal fix would be:
-- Support pull-based ingestion message mappers and raw payload support ([#19765](https://github.com/opensearch-project/OpenSearch/pull/19765)]
-- Support for HTTP/3 (server side) ([#20017](https://github.com/opensearch-project/OpenSearch/pull/20017)]
+- Support for HTTP/3 (server side) ([#20017](https://github.com/opensearch-project/OpenSearch/pull/20017))This keeps the existing single ingestion entry and adds a clean HTTP/3 line.
🤖 Prompt for AI Agents
In CHANGELOG.md around lines 34 to 38, remove the duplicated "Support pull-based
ingestion message mappers and raw payload support" entry and correct the
malformed markdown links by replacing the trailing "]" with ")" on the two
affected lines so links are well-formed; ensure only one ingestion line remains
and the HTTP/3 line is preserved with a properly closed link.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@coderabbitai those are completely different change log entry, isnt it? Do you have any suggestions to the code itself in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@peterzhuamazon Thank you for the clarification request! Let me address both points:
Regarding the changelog entries:
You're right to question this - let me clarify:
- Line 36 (new): "Support pull-based ingestion message mappers and raw payload support ([[Pull-based Ingestion] Support message mappers to support different input formats and raw payloads #19765]..." - This is indeed a duplicate of the existing line 34, which has the identical text and PR number.
- Line 37 (new): "Support for HTTP/3 (server side) ([[WIP] Support for HTTP/3 (server side) #20017]..." - This is a new, unique entry and should absolutely be kept.
So the fix is to remove only the duplicate line 36 and correct the malformed bracket on line 37:
-- Support pull-based ingestion message mappers and raw payload support ([#19765](https://github.com/opensearch-project/OpenSearch/pull/19765)]
-- Support for HTTP/3 (server side) ([#20017](https://github.com/opensearch-project/OpenSearch/pull/20017)]
+- Support for HTTP/3 (server side) ([#20017](https://github.com/opensearch-project/OpenSearch/pull/20017))Regarding code review:
Since this is a WIP PR, I'd be happy to review the HTTP/3 implementation itself. A few areas worth examining:
- Protocol detection and fallback - How the code handles HTTP/3 availability and falls back to HTTP/1.1/2.0
- QUIC/UDP configuration - Security settings, connection limits, timeouts
- Certificate handling - Especially the switch to ECC algorithms for HTTP/3
- Testing coverage - Integration tests for HTTP/3 scenarios
- Performance implications - Native QUIC library loading across platforms
Would you like me to provide detailed feedback on any specific aspect of the implementation?
|
❌ Gradle check result for cc4ae1c: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (1)
modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1 (1)
1-1: Verify checksum against official Netty releases.This checksum should be validated against the official Netty release artifacts. The version and security concerns are covered in the review of the Windows variant.
Run the following script to verify the checksums for the Linux x86_64 artifact:
#!/bin/bash # Description: Verify Netty QUIC codec checksums against Maven Central # Fetch the SHA-1 checksum from Maven Central for Linux x86_64 curl -s "https://repo1.maven.org/maven2/io/netty/incubator/netty-codec-native-quic/4.2.7.Final/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1" echo "" echo "Expected (from file): 6a3e4398852f926c4b22f381d89dae2388446ae8"
🧹 Nitpick comments (7)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java (1)
215-226: Make HTTP/3 mapping independent ofequals(String)semanticsThe new HTTP/3 branch mirrors the existing HTTP/2 handling, but
request.protocolVersion()is a NettyHttpVersion, so relying onequals("HTTP/3.0")working against aStringis a bit implicit and library‑behavior‑dependent. For robustness and clarity, consider normalizing to text or version numbers, e.g.:final var version = request.protocolVersion().text(); // or major/minorVersion() if (io.netty.handler.codec.http.HttpVersion.HTTP_1_0.text().equals(version)) { return HttpRequest.HttpVersion.HTTP_1_0; } else if (io.netty.handler.codec.http.HttpVersion.HTTP_1_1.text().equals(version)) { return HttpRequest.HttpVersion.HTTP_1_1; } else if ("HTTP/2.0".equals(version)) { return HttpRequest.HttpVersion.HTTP_2_0; } else if ("HTTP/3.0".equals(version)) { return HttpRequest.HttpVersion.HTTP_3_0; }(or equivalently, switch on
majorVersion()/minorVersion()), and add a small unit test asserting that an HTTP/3 request hits this branch.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java (1)
24-32: Consider validating that the channels array is non-empty.The constructor doesn't validate that at least one channel is provided. An empty array would cause
getLocalAddress()to throw anArrayIndexOutOfBoundsException.@SuppressWarnings({ "unchecked", "rawtypes" }) ReactorNetty4CompositeHttpServerChannel(Channel... channels) { + if (channels == null || channels.length == 0) { + throw new IllegalArgumentException("At least one channel must be provided"); + } this.channels = channels; this.closeContexts = new CompletableContext[channels.length];plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (3)
297-297: Simplify redundant boolean comparison.
.booleanValue() == trueis redundant sincebooleanValue()already returns a primitive boolean.- if (Http3.isHttp3Available() && SETTING_HTTP_HTTP3_ENABLED.get(settings).booleanValue() == true) { + if (Http3.isHttp3Available() && SETTING_HTTP_HTTP3_ENABLED.get(settings)) {
325-331: Consider making HTTP/3 stream settings configurable.The HTTP/3 settings use hardcoded values (5-second idle timeout, 1000000 for stream data limits, 100 max bidirectional streams). For production use, operators may need to tune these based on workload. Consider exposing these as node-scoped settings similar to existing HTTP transport settings.
289-339: HTTP/3 configuration duplicates HTTP/1.1/2 server setup.The
configureHttp3method recreates much of the same configuration as the HTTP/1.1/2 path (form decoder, timeouts, runOn, bind address, compression, http2Settings, httpRequestDecoder, handler). Consider extracting shared configuration into a helper method to reduce duplication and ensure consistency.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (2)
338-338: Simplify redundant boolean comparison.Same issue as in the server-side code:
.booleanValue() == trueis redundant.- if (Http3.isHttp3Available() && SETTING_HTTP_HTTP3_ENABLED.get(settings).booleanValue() == true) { + if (Http3.isHttp3Available() && SETTING_HTTP_HTTP3_ENABLED.get(settings)) {
308-314: Hardcoded HTTP/3 settings duplicate server-side values.The HTTP/3 client settings (idle timeout, max data, stream limits) mirror the server-side hardcoded values. Consider extracting these as shared constants or reading from a common settings source to maintain consistency and simplify future changes.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (35)
CHANGELOG.md(1 hunks)gradle/libs.versions.toml(1 hunks)modules/transport-netty4/build.gradle(2 hunks)modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java(1 hunks)plugins/repository-azure/build.gradle(0 hunks)plugins/transport-reactor-netty4/build.gradle(2 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java(2 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java(2 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java(4 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java(11 hunks)server/src/main/java/org/opensearch/bootstrap/Security.java(1 hunks)server/src/main/java/org/opensearch/http/HttpRequest.java(1 hunks)server/src/main/java/org/opensearch/http/HttpTransportSettings.java(1 hunks)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java(2 hunks)
💤 Files with no reviewable changes (1)
- plugins/repository-azure/build.gradle
✅ Files skipped from review due to trivial changes (2)
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
🚧 Files skipped from review as they are similar to previous changes (18)
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- server/src/main/java/org/opensearch/bootstrap/Security.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- server/src/main/java/org/opensearch/http/HttpRequest.java
- plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- gradle/libs.versions.toml
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- server/src/main/java/org/opensearch/http/HttpTransportSettings.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- CHANGELOG.md
- modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1
🧰 Additional context used
🧬 Code graph analysis (6)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (3)
test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
KeyStoreUtils(22-57)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: gradle-check
- GitHub Check: detect-breaking-change
- GitHub Check: precommit (25, ubuntu-24.04-arm)
- GitHub Check: precommit (21, ubuntu-latest)
- GitHub Check: precommit (25, macos-15-intel)
- GitHub Check: assemble (21, ubuntu-latest)
- GitHub Check: precommit (21, windows-2025, true)
- GitHub Check: precommit (21, ubuntu-24.04-arm)
- GitHub Check: precommit (21, macos-15-intel)
- GitHub Check: precommit (21, windows-latest)
- GitHub Check: precommit (25, windows-latest)
- GitHub Check: assemble (25, ubuntu-24.04-arm)
- GitHub Check: precommit (25, macos-15)
- GitHub Check: assemble (21, ubuntu-24.04-arm)
- GitHub Check: precommit (25, ubuntu-latest)
- GitHub Check: assemble (21, windows-latest)
- GitHub Check: assemble (25, windows-latest)
- GitHub Check: assemble (25, ubuntu-latest)
- GitHub Check: precommit (21, macos-15)
- GitHub Check: Analyze (java)
- GitHub Check: Mend Security Check
🔇 Additional comments (21)
test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (2)
43-51: Algorithm parameter is correctly threaded into certificate generationPlumbing the
Algorithmargument through toCertificateBuilder.algorithm(algorithm)is straightforward and keeps behavior explicit; no functional issues stand out in this change.
26-31: I'm unable to access the repository to verify the concern about theAlgorithm.ed25519default change due to persistent cloning failures. Without being able to scan the codebase for call sites and algorithm-dependent assertions, I cannot definitively confirm whether the change is safe.Verify that
Algorithm.ed25519default doesn't break existing tests relying on RSA/EC key typesThe overload and delegation pattern is clean and maintains backward compatibility for the API, but switching the default algorithm from (likely RSA/EC) to
Algorithm.ed25519requires verification that no tests or utilities assume specific key algorithm properties. A manual scan should confirm:
- All call sites of
createServerKeyStore()(no-arg variant) are compatible with ed25519 keys- No tests assert on key algorithm, signature algorithm names, or other algorithm-specific attributes
- Certificate validation or key usage constraints don't depend on RSA/EC semantics
Without this verification, the change risks subtle test failures across the codebase.
plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1 (1)
1-1: Based on my verification:Version 4.2.7.Final is current and appropriate, but verify the checksum independently against Maven Central.
The netty-codec-native-quic 4.2.7.Final (released October 15, 2025) is a recent stable release. While Netty 4.2.7.Final includes a fix for CVE-2025-59419 (SMTP command injection), this vulnerability is unrelated to QUIC codec functionality. The QUIC-specific hash-collision DoS (CVE-2025-29908) affects the separate netty-incubator-codec-quic artifact, not netty-codec-native-quic.
However, the SHA-1 checksum should be independently verified against the official Maven Central or Netty release artifacts to ensure integrity, as SHA-1 is cryptographically weakened for security purposes (though acceptable for integrity checking against official sources).
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java (1)
17-17: LGTM!The import addition and update to pass
Settings.EMPTYcorrectly aligns with the updatedReactorHttpClient.create(Settings)API. UsingSettings.EMPTYis appropriate here since this pipelining test doesn't require HTTP/3 (which needs secure connections).Also applies to: 47-47
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
181-181: LGTM!The update to
ReactorHttpClient.create(false, Settings.EMPTY)correctly adapts to the new API while preserving the originalcompression=falsebehavior. TheSettings.EMPTYis consistent with the transport initialization on line 167.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
202-202: LGTM!All
ReactorHttpClient.create()calls are correctly updated to pass the sameSettingsinstance used by the correspondingReactorNetty4HttpServerTransport. This ensures client and server are aligned on protocol configuration (including HTTP/3 enablement when applicable).Also applies to: 307-307, 353-353, 409-409, 480-480, 497-497
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (1)
104-104: LGTM!Both
ReactorHttpClient.create(false, Settings.EMPTY)calls correctly adapt to the new API while maintaining the originalcompression=falsebehavior. UsingSettings.EMPTYis appropriate for these request size limit tests.Also applies to: 134-134
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java (1)
46-66: LGTM forisOpen(),close(), andtoString().The implementations correctly:
- Return
falsefromisOpen()if any channel is closed- Close all underlying channels in
close()- Provide useful debug info in
toString()plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (5)
299-303: LGTM!Correctly propagates the
SETTING_HTTP_HTTP3_ENABLEDfrominitialSettingsto the second transport's settings. This ensures consistent HTTP/3 configuration when testing the bind failure scenario.
454-460: LGTM!Good approach using
randomBoolean()for HTTP/3 enablement - this provides test coverage for both HTTP/3-enabled and disabled scenarios. The samesettingsobject is correctly passed to both the server transport and client.Also applies to: 475-475
260-260: LGTM!All
ReactorHttpClient.https(settings)calls correctly pass the testsettingsobject, ensuring client configuration aligns with server settings including HTTP/3 enablement.Also applies to: 367-367, 414-414, 547-547, 564-564
649-653: LGTM!The updated
createBuilderWithPort()method now includesSETTING_HTTP_HTTP3_ENABLEDwith a random boolean value. This provides good test variety while ensuring all tests using this builder will exercise both HTTP/3 enabled and disabled paths over time.
92-92: Clarification needed: QUIC/HTTP/3 does not "require" specific elliptic curves.QUIC (RFC 9001) uses TLS 1.3 for its handshake, and TLS 1.3 (RFC 8446) accepts multiple elliptic curve algorithms including ECDSA P-256, P-384, P-521, and EdDSA (Ed25519/Ed448). The switch to
Algorithm.ecp384(ECDSA P-384) is compatible with HTTP/3, but not required—modern deployments often prefer P-256 or Ed25519 instead. Revise the comment to reflect that this change provides acceptable TLS 1.3/QUIC support rather than fulfilling a specific requirement.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
262-267: LGTM on the HTTP/3 binding architecture.Binding HTTP/3 to the same port as HTTP/1.1/2 is correct since they use different transport protocols (UDP vs TCP). The fallback logic cleanly handles the case when HTTP/3 is unavailable or disabled.
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (2)
96-101: LGTM on the Settings integration.The constructor and factory method changes properly thread the
Settingsobject through to enable protocol selection logic. This aligns well with the broader PR changes for HTTP/3 enablement.Also applies to: 103-113
334-348: LGTM on protocol selection logic.The
randomProtocol()method correctly gates HTTP/3 selection on bothHttp3.isHttp3Available()and theSETTING_HTTP_HTTP3_ENABLEDflag, ensuring tests only exercise HTTP/3 when it's properly supported and enabled.modules/transport-netty4/build.gradle (2)
214-216: Audit configuration update for QUIC support is correct.Adding
io.netty.channel.epoll.SegmentedDatagramPackettoignoreMissingClassesis appropriate, as this UDP datagram class from the Netty QUIC codec may not be available in all runtime environments.
65-79: Based on my verification:Key findings:
API scope concern - VALID: Gradle best practices confirm that native JNI/platform-specific classifier artifacts should use
runtimeOnly, notapi. Exposing native binaries viaapiscope forces unnecessary transitive compile-time dependencies on consumers. The review's core concern is architecturally sound.Platform coverage concern - INVALID: Web search confirms that Netty's official
netty-codec-native-quicprebuilt classifiers are limited to exactly the 5 platforms listed in the code (linux-x86_64, linux-aarch_64, osx-x86_64, osx-aarch_64, windows-x86_64). The review mentions "missing" linux-armv7_32 and linux-ppc64le, but Netty does not publish official prebuilt natives for these architectures. Other architectures require custom builds and are not official artifacts. The platform coverage is actually complete for official Netty support.
Reconsider the scope of
netty-codec-native-quicdependency.
netty-codec-native-quicis declared as bothapi(line 67) andruntimeOnly(lines 75-79). Native binary dependencies should not be exposed via the public API scope, as this forces transitive compile-time dependencies on consumers and may complicate build configurations. Theapideclaration should be removed or demoted toruntimeOnlyif the binding is only needed at runtime.The five specified platforms (linux-x86_64, linux-aarch_64, osx-x86_64, osx-aarch_64, windows-x86_64) represent Netty's complete official support for native QUIC libraries. No additional platforms should be added.
Apply this diff to remove the problematic
apideclaration:api "io.netty:netty-buffer:${versions.netty}" api "io.netty:netty-codec-base:${versions.netty}" api "io.netty:netty-codec-compression:${versions.netty}" api "io.netty:netty-codec:${versions.netty}" api "io.netty:netty-codec-http:${versions.netty}" api "io.netty:netty-codec-http2:${versions.netty}" api "io.netty:netty-codec-http3:${versions.netty}" api "io.netty:netty-codec-classes-quic:${versions.netty}" - api "io.netty:netty-codec-native-quic:${versions.netty}" api "io.netty:netty-common:${versions.netty}" api "io.netty:netty-handler:${versions.netty}" api "io.netty:netty-resolver:${versions.netty}" api "io.netty:netty-transport:${versions.netty}" api "io.netty:netty-transport-native-unix-common:${versions.netty}" // Bundle all supported OSes and Archs runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:linux-x86_64"plugins/transport-reactor-netty4/build.gradle (3)
161-161: Audit configuration update for QUIC support is correct.Adding
io.netty.channel.epoll.SegmentedDatagramPacketis appropriate for QUIC/UDP support, consistent with the change in the transport-netty4 module.
1-46: Verify the AI-generated summary against the actual changes.The AI summary claims that several QUIC-related classes (e.g.,
io.netty.handler.codec.quic.QuicChannel,QuicChannelBootstrap, etc.) were removed fromthirdPartyAudit.ignoreViolations. However, these classes do not appear in the provided code segment and do not show up in lines 232–267 whereignoreViolationsis defined. Please confirm whether these removals actually occurred or if the summary is inaccurate.
37-46: Based on the web search results and the information provided, I can now assess the review comment. The guidance confirms important points about dependency management:
Native codecs should be
runtimeOnly— Web search confirms native JNI libraries are runtime artifacts and should not be exposed viaapiscope.Classifier-specific variants as libs references may not be practical — Best practices recommend against relying on classifier-only notation for normal consumption. The suggested diff pattern (
libs.netty.codec.native.quic.linux.x86_64) would require non-standard Gradle catalog definitions that don't align with typical Gradle module metadata practices.However, I cannot definitively verify:
- Whether OpenSearch's
libs.versions.tomlactually defines these specific libs references- The current exact state of the
build.gradlefile- Whether the suggested diff is feasible in the context of this repository
Given these constraints, here is the rewritten review comment:
Remove
apiscope from native QUIC codec; native JNI libraries should not be publicly exposed.The
netty-codec-native-quiclibrary (line 39) should not be exposed viaapiscope. Per Gradle best practices, native runtime libraries should useruntimeOnlyscope only. Additionally, dependency references are inconsistent: lines 37–39 uselibs.*references while lines 42–46 use inline${versions.netty}strings.Recommended fixes:
- Remove the
api libs.netty.codec.native.quicline — native codecs are runtime-only.- Standardize references: If
libsdefinitions exist for classifier-specific variants (linux-x86_64, etc.), use them; otherwise, keep inline notation but ensure${versions.netty}is used consistently throughout.Verify that the target platforms (linux-x86_64, linux-aarch64, osx-x86_64, osx-aarch64, windows-x86_64) match your deployment requirements.
...rc/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java
Show resolved
Hide resolved
...etty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java
Show resolved
Hide resolved
...sport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java
Show resolved
Hide resolved
|
❌ Gradle check result for 08a9dab: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
♻️ Duplicate comments (2)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
66-67: Align HTTP/3 client flow-control limits with server-side H3 settings instead ofSETTING_HTTP_MAX_CHUNK_SIZE.On the HTTP/3 client path,
http3Settings().maxData(...)currently usesSETTING_HTTP_MAX_CHUNK_SIZE, which is intended for HTTP message chunking, not QUIC connection-level flow control. The server-side HTTP/3 configuration has already been updated to useSETTING_HTTP_MAX_CONTENT_LENGTHand dedicated H3 settings for per-stream limits; keeping the client onSETTING_HTTP_MAX_CHUNK_SIZEcreates an unrealistically small connection window and an asymmetry vs server configuration, even though this is test-only code.Consider aligning the client with the server-side H3 settings, for example:
-import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_HTTP3_ENABLED; -import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_MAX_CHUNK_SIZE; +import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_HTTP3_ENABLED; +import static org.opensearch.http.HttpTransportSettings.SETTING_HTTP_MAX_CONTENT_LENGTH; +import static org.opensearch.http.reactor.netty4.ReactorNetty4HttpServerTransport.SETTING_H3_MAX_STREAM_LOCAL_LENGTH; +import static org.opensearch.http.reactor.netty4.ReactorNetty4HttpServerTransport.SETTING_H3_MAX_STREAM_REMOTE_LENGTH; +import static org.opensearch.http.reactor.netty4.ReactorNetty4HttpServerTransport.SETTING_H3_MAX_STREAMS; @@ } else { return client.protocol(protocol) .secure( spec -> spec.sslContext( Http3SslContextSpec.forClient().configure(s -> s.trustManager(InsecureTrustManagerFactory.INSTANCE)) ).handshakeTimeout(Duration.ofSeconds(30)) ) .http3Settings( spec -> spec.idleTimeout(Duration.ofSeconds(5)) - .maxData(SETTING_HTTP_MAX_CHUNK_SIZE.get(settings).getBytes()) - .maxStreamDataBidirectionalLocal(1000000) - .maxStreamDataBidirectionalRemote(1000000) - .maxStreamsBidirectional(100) + .maxData(SETTING_HTTP_MAX_CONTENT_LENGTH.get(settings).getBytes()) + .maxStreamDataBidirectionalLocal(SETTING_H3_MAX_STREAM_LOCAL_LENGTH.get(settings).getBytes()) + .maxStreamDataBidirectionalRemote(SETTING_H3_MAX_STREAM_REMOTE_LENGTH.get(settings).getBytes()) + .maxStreamsBidirectional(SETTING_H3_MAX_STREAMS.get(settings).longValue()) ); }This keeps test clients representative of the configured HTTP/3 behavior and avoids an overly restrictive default window.
Also applies to: 302-315
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
273-317: Clean up HTTP/3 server if HTTP/1.1/2 bind fails and avoidchannel()returning null on the composite DisposableServer.If HTTP/3 is enabled and
configureHttp3(...).map(HttpServer::bindNow)succeeds, buthttp11or2.bindNow()throws, the HTTP/3 server is left running anddisposableServeris never set, sostopInternal()cannot dispose it. Additionally, the anonymousDisposableServerimplementation returnsnullfromchannel(), which is fragile even if currently unused.Wrap the HTTP/1.1/2 bind in a try/catch and ensure
http3Serveris disposed on failure, and return a sensible channel fromchannel()(for example, the HTTP/1.1/2 channel):- final Optional<DisposableServer> http3Opt = configureHttp3(socketAddress).map(HttpServer::bindNow); - if (http3Opt.isEmpty()) { - disposableServer = http11or2.bindNow(); - return new ReactorNetty4HttpServerChannel(disposableServer.channel()); - } else { - final DisposableServer http3Server = http3Opt.get(); - final DisposableServer http11or2Server = http11or2.bindNow(); - - disposableServer = new DisposableServer() { - @Override - public Channel channel() { - return null; /* not implemented */ - } - - @Override - public void disposeNow() { - http3Server.disposeNow(); - http11or2Server.disposeNow(); - } - }; - - return new ReactorNetty4CompositeHttpServerChannel(http11or2Server.channel(), http3Server.channel()); - } + final Optional<DisposableServer> http3Opt = configureHttp3(socketAddress).map(HttpServer::bindNow); + if (http3Opt.isEmpty()) { + disposableServer = http11or2.bindNow(); + return new ReactorNetty4HttpServerChannel(disposableServer.channel()); + } else { + final DisposableServer http3Server = http3Opt.get(); + final DisposableServer http11or2Server; + try { + http11or2Server = http11or2.bindNow(); + } catch (Exception e) { + http3Server.disposeNow(); + throw e; + } + + disposableServer = new DisposableServer() { + @Override + public Channel channel() { + // Expose a representative channel; HTTP/1.1/2 is sufficient for callers that only need a single Channel + return http11or2Server.channel(); + } + + @Override + public void disposeNow() { + http3Server.disposeNow(); + http11or2Server.disposeNow(); + } + }; + + return new ReactorNetty4CompositeHttpServerChannel(http11or2Server.channel(), http3Server.channel()); + }
🧹 Nitpick comments (5)
modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java (1)
160-166: Behavior looks correct; consider small style/encapsulation tweaksThe conditional correctly exposes the underlying allocator only when direct buffers are explicitly requested and the global allocator is the
NoDirectBufferswrapper, which matches the HTTP/3/QUIC requirement.Two minor polish suggestions:
- Drop the redundant comparison:
if (directBuffers && ALLOCATOR instanceof NoDirectBuffers ndb) { ... }.- Prefer the accessor over direct field access to keep
NoDirectBuffersencapsulated within its own API:- public static ByteBufAllocator getAllocator(boolean directBuffers) { - if (directBuffers == true && ALLOCATOR instanceof NoDirectBuffers ndb) { - return ndb.delegate; /* Http3/Quic only supports direct buffers */ - } else { - return ALLOCATOR; - } - } + public static ByteBufAllocator getAllocator(boolean directBuffers) { + if (directBuffers && ALLOCATOR instanceof NoDirectBuffers ndb) { + return ndb.getDelegate(); /* Http3/Quic only supports direct buffers */ + } else { + return ALLOCATOR; + } + }modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (1)
360-379: UnusedServerChannelExceptionHandlerclass.The
ServerChannelExceptionHandlerclass is defined but never added to any pipeline in the current implementation. If this is intended for future use, consider adding a TODO comment. Otherwise, remove the dead code.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (2)
382-389: PreferStandardCharsets.UTF_8overCharset.forName("UTF-8").Lines 382 and 389 use
Charset.forName("UTF-8")whenStandardCharsets.UTF_8is already imported (Line 54) and used elsewhere in the file (Lines 274, 453).- final String url = "/" + new String(new byte[maxInitialLineLength], Charset.forName("UTF-8")); + final String url = "/" + new String(new byte[maxInitialLineLength], StandardCharsets.UTF_8); ... - new String(response.content().array(), Charset.forName("UTF-8")), + new String(response.content().array(), StandardCharsets.UTF_8),
428-440: Test usesSettings.EMPTYwhich may cause port binding issues.Unlike other tests that use
createSettings()(which includesgetPortRange()), this test passesSettings.EMPTYdirectly. This could lead to port conflicts if the default port range is already in use.try ( Netty4QuicServerTransport transport = new Netty4QuicServerTransport( - Settings.EMPTY, + createSettings(), networkService, bigArrays,plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (1)
295-299: Randomizinghttp.protocol.http3.enabledimproves coverage; watch for protocol-specific flakiness.Propagating and randomizing
SETTING_HTTP_HTTP3_ENABLEDacross server and client settings is a reasonable way to exercise both HTTP/1.1+2 and HTTP/3 paths in these tests. If you see instability in tests that depend on very specific protocol behavior, consider pinning this flag for those tests or splitting dedicated HTTP/3 variants while leaving base tests on HTTP/1.1/2.Also applies to: 450-452, 646-649
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (42)
CHANGELOG.md(1 hunks)gradle/libs.versions.toml(1 hunks)modules/transport-netty4/build.gradle(2 hunks)modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java(2 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java(1 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java(10 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java(1 hunks)plugins/repository-azure/build.gradle(0 hunks)plugins/transport-reactor-netty4/build.gradle(2 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java(2 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java(2 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java(5 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java(3 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java(7 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java(12 hunks)server/src/main/java/org/opensearch/bootstrap/Security.java(1 hunks)server/src/main/java/org/opensearch/http/HttpRequest.java(1 hunks)server/src/main/java/org/opensearch/http/HttpTransportSettings.java(1 hunks)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java(2 hunks)
💤 Files with no reviewable changes (1)
- plugins/repository-azure/build.gradle
✅ Files skipped from review due to trivial changes (6)
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- CHANGELOG.md
- plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
🚧 Files skipped from review as they are similar to previous changes (17)
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- server/src/main/java/org/opensearch/bootstrap/Security.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- modules/transport-netty4/build.gradle
- gradle/libs.versions.toml
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java
🧰 Additional context used
🧬 Code graph analysis (6)
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java (2)
server/src/main/java/org/opensearch/index/search/SimpleQueryStringQueryParser.java (1)
Settings(317-450)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (3)
test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
KeyStoreUtils(26-83)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java (1)
server/src/main/java/org/opensearch/http/AbstractHttpServerTransport.java (1)
AbstractHttpServerTransport(93-507)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (1)
libs/core/src/main/java/org/opensearch/core/common/bytes/BytesArray.java (1)
BytesArray(48-151)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: gradle-check
- GitHub Check: precommit (21, windows-2025, true)
- GitHub Check: precommit (25, ubuntu-24.04-arm)
- GitHub Check: precommit (25, macos-15-intel)
- GitHub Check: precommit (21, macos-15-intel)
- GitHub Check: precommit (25, windows-latest)
- GitHub Check: precommit (21, ubuntu-latest)
- GitHub Check: precommit (25, macos-15)
- GitHub Check: precommit (21, windows-latest)
- GitHub Check: precommit (25, ubuntu-latest)
- GitHub Check: precommit (21, ubuntu-24.04-arm)
- GitHub Check: precommit (21, macos-15)
- GitHub Check: detect-breaking-change
- GitHub Check: assemble (25, ubuntu-24.04-arm)
- GitHub Check: assemble (21, ubuntu-latest)
- GitHub Check: assemble (21, ubuntu-24.04-arm)
- GitHub Check: assemble (25, ubuntu-latest)
- GitHub Check: assemble (25, windows-latest)
- GitHub Check: assemble (21, windows-latest)
- GitHub Check: Analyze (java)
- GitHub Check: Mend Security Check
🔇 Additional comments (15)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java (2)
36-36: Type generalization looks good.The change from
Netty4HttpServerTransporttoAbstractHttpServerTransportis appropriate for supporting multiple HTTP transport implementations (HTTP/1.x/2 and HTTP/3). All methods invoked onserverTransport(incomingRequestandonException) are present inAbstractHttpServerTransport, making this a safe refactoring.Also applies to: 46-46, 48-48
54-54: Verify if HTTP/3 support is included in this PR.The review comment assumes HTTP/3/QUIC transport is being added, but OpenSearch currently ships only Netty4 (default) and experimental Reactor Netty transports—no HTTP/3/QUIC transport exists. If this PR does not introduce HTTP/3 transport, the static
Netty4HttpServerTransport.HTTP_CHANNEL_KEYreference on lines 54 and 69 is correct for the current Netty4-only implementation. If HTTP/3 support is intended, confirm whether a separate HTTP/3 transport class is being added, or clarify the scope of the type generalization toAbstractHttpServerTransport.test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
50-65: Clean refactoring to support algorithm-parameterized keystore creation.The delegation pattern preserves backward compatibility while enabling tests to specify different algorithms (e.g.,
Algorithm.ecp384for HTTP/3/QUIC scenarios). The implementation correctly propagates the algorithm to the certificate builder.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
176-184: HTTP/3 client factory implementation looks correct.The
http3()method properly configures the bootstrap withNioDatagramChanneland usesNettyAllocator.getAllocator(true)to request direct buffers, which are required by QUIC.plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java (1)
17-17: LGTM!The import addition and API migration to
ReactorHttpClient.create(Settings.EMPTY)are consistent with the new Settings-aware client factory pattern introduced across the test suite for HTTP/3 support.Also applies to: 47-47
server/src/main/java/org/opensearch/http/HttpRequest.java (1)
60-65: LGTM!The addition of
HTTP_3_0to theHttpVersionenum is a clean, backward-compatible extension to support the new HTTP/3 protocol. The enum maintains logical ordering by HTTP version.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
122-122: LGTM!The API migration to include
Settings.EMPTYas a parameter is consistent with the updatedReactorHttpClient.create(boolean, Settings)signature. Since these tests explicitly useHttpVersion.HTTP_1_1, usingSettings.EMPTYis appropriate.Also applies to: 162-162
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
100-100: LGTM!Good approach: this test appropriately propagates the same
settingsobject (containing port configuration) to both the server transport and the client, ensuring consistent configuration. This aligns with the new Settings-aware client factory pattern.server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
262-267: LGTM!The new
SETTING_HTTP_HTTP3_ENABLEDsetting is well-structured:
- Defaults to
false, which is appropriate for a new, experimental feature- Uses
Property.NodeScopecorrectly for node-level transport configuration- Follows existing naming conventions (
http.protocol.*)- Includes a helpful comment about OS/architecture requirements
Ensure this setting is registered in the appropriate settings module so it's recognized by the cluster.
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
205-205: ReactorHttpClient factory migration looks correct and consistent.All call sites correctly switched to
ReactorHttpClient.create(settings)/create(Settings.EMPTY), keeping server/client settings aligned without changing the test semantics.Also applies to: 310-310, 356-356, 412-412, 478-478, 541-541, 559-559
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (2)
92-93: Key material generation and SSLEngine setup are appropriate for test SSL.Using
KeyStoreUtils.createServerKeyStore(Algorithm.ecp384)with a sharedKeyManagerFactoryand constructing theSSLEngineviaSslContextBuilder.forServer(keyManagerFactory).trustManager(InsecureTrustManagerFactory.INSTANCE)is sound for these tests and keeps the setup concise.Also applies to: 120-122, 165-171
256-256: HTTPS client creation correctly aligned with the new Settings-aware ReactorHttpClient API.All secure tests now construct clients via
ReactorHttpClient.https(settings), passing the sameSettingsused for the server transport so that HTTP/1.1, HTTP/2, and HTTP/3 selection stays consistent between client and server.Also applies to: 363-363, 410-410, 471-471, 544-544, 560-560
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
18-18: Settings-aware client construction and protocol selection look coherent.Requiring
Settingsin the constructor/factories, caching a per-instanceHttpProtocol, and basinguseHttp11only()on that protocol align well with the new HTTP/1.1–2–3 model. The secure/non-secure branches increateClientcorrectly choose between HTTP/1.1, H2/H2C, and HTTP/3 based onsecureandrandomProtocol.Also applies to: 75-79, 96-113, 276-283, 317-323, 330-333, 334-348
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
48-49: HTTP/3 settings and configuration are well-scoped and gated.The new H3 settings (
SETTING_H3_MAX_STREAM_LOCAL_LENGTH,SETTING_H3_MAX_STREAM_REMOTE_LENGTH,SETTING_H3_MAX_STREAMS) with ~1 MB per stream and 100 concurrent bidirectional streams are reasonable defaults. TheconfigureHttp3method correctly:
- Requires a
SecureHttpTransportSettingsProviderand a KeyManagerFactory.- Gates on
Http3.isHttp3Available()andSETTING_HTTP_HTTP3_ENABLED.- Aligns connection
maxDatawithSETTING_HTTP_MAX_CONTENT_LENGTHand uses the H3 settings for stream limits.- Keeps HTTP/1.1/2 configuration isolated in
configureHttp11orHttp2.This structure gives a clear, opt-in HTTP/3 path without regressing existing HTTP/1.1/2 behavior.
Also applies to: 55-55, 69-69, 75-75, 110-136, 319-367, 370-370
plugins/transport-reactor-netty4/build.gradle (1)
38-47: QUIC dependencies and audit updates align with HTTP/3 support enablement.The addition of
netty-codec-classes-quicandnetty-codec-native-quicAPIs plus OS-specificruntimeOnlyclassifiers follows standard Gradle patterns and should not produce duplicate artifacts in the published POM/JAR. TheSegmentedDatagramPacketaudit exclusion is appropriate for platform-dependent availability. No actionable issues identified.
...les/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java
Show resolved
Hide resolved
| .initialMaxStreamDataBidirectionalRemote(SETTING_H3_MAX_STREAM_REMOTE_LENGTH.get(settings).getBytes()) | ||
| .initialMaxStreamsBidirectional(SETTING_H3_MAX_STREAMS.get(settings).longValue()) | ||
| .tokenHandler(InsecureQuicTokenHandler.INSTANCE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Security: InsecureQuicTokenHandler should not be used in production.
The InsecureQuicTokenHandler.INSTANCE bypasses QUIC token validation, which is a security feature that helps prevent address spoofing attacks. While acceptable for initial development/testing, this should be replaced with a proper token handler before production use.
Consider adding a TODO or configuration option:
- .tokenHandler(InsecureQuicTokenHandler.INSTANCE)
+ // TODO: Replace with secure token handler before production
+ // See: https://www.rfc-editor.org/rfc/rfc9000.html#section-8
+ .tokenHandler(InsecureQuicTokenHandler.INSTANCE)Or introduce a setting to control this behavior for production deployments.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .initialMaxStreamDataBidirectionalRemote(SETTING_H3_MAX_STREAM_REMOTE_LENGTH.get(settings).getBytes()) | |
| .initialMaxStreamsBidirectional(SETTING_H3_MAX_STREAMS.get(settings).longValue()) | |
| .tokenHandler(InsecureQuicTokenHandler.INSTANCE) | |
| .initialMaxStreamDataBidirectionalRemote(SETTING_H3_MAX_STREAM_REMOTE_LENGTH.get(settings).getBytes()) | |
| .initialMaxStreamsBidirectional(SETTING_H3_MAX_STREAMS.get(settings).longValue()) | |
| // TODO: Replace with secure token handler before production | |
| // See: https://www.rfc-editor.org/rfc/rfc9000.html#section-8 | |
| .tokenHandler(InsecureQuicTokenHandler.INSTANCE) |
🤖 Prompt for AI Agents
In
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java
around lines 274-276, the code uses InsecureQuicTokenHandler.INSTANCE which
disables QUIC token validation; replace this with a proper token handler
implementation that generates and validates stateless QUIC tokens (or integrates
with Netty/your existing token service) and remove the insecure instance from
production paths, and add a boolean cluster/transport setting (default false) to
allow the insecure handler only for dev/tests with a clear TODO and
documentation note; ensure the new setting is validated at startup and the
secure handler is used by default in production.
...les/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java
Show resolved
Hide resolved
| */ | ||
| public class SslUtils { | ||
| private static final String[] DEFAULT_SSL_PROTOCOLS = { "TLSv1.3", "TLSv1.2", "TLSv1.1" }; | ||
| public static final String[] DEFAULT_SSL_PROTOCOLS = { "TLSv1.3", "TLSv1.2", "TLSv1.1" }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid exposing mutable DEFAULT_SSL_PROTOCOLS array as public API
Changing DEFAULT_SSL_PROTOCOLS to public static final exposes a mutable array; any caller can modify its elements (e.g., DEFAULT_SSL_PROTOCOLS[0] = "TLSv1"), silently changing TLS behavior globally at runtime. That’s a security‑relevant configuration surface and breaks encapsulation just to share an implementation detail.
Prefer keeping the array private and exposing an immutable view or a defensive copy via an accessor:
- public static final String[] DEFAULT_SSL_PROTOCOLS = { "TLSv1.3", "TLSv1.2", "TLSv1.1" };
+ private static final String[] DEFAULT_SSL_PROTOCOLS = { "TLSv1.3", "TLSv1.2", "TLSv1.1" };
+
+ public static String[] getDefaultSslProtocols() {
+ // Defensive copy so callers cannot mutate our internal array
+ return DEFAULT_SSL_PROTOCOLS.clone();
+ }New HTTP/3 / QUIC code (or other callers) can then use SslUtils.getDefaultSslProtocols() instead of the field.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public static final String[] DEFAULT_SSL_PROTOCOLS = { "TLSv1.3", "TLSv1.2", "TLSv1.1" }; | |
| private static final String[] DEFAULT_SSL_PROTOCOLS = { "TLSv1.3", "TLSv1.2", "TLSv1.1" }; | |
| public static String[] getDefaultSslProtocols() { | |
| // Defensive copy so callers cannot mutate our internal array | |
| return DEFAULT_SSL_PROTOCOLS.clone(); | |
| } |
🤖 Prompt for AI Agents
In
modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java
around line 27, the public static final DEFAULT_SSL_PROTOCOLS array is exposed
allowing callers to mutate its elements; make DEFAULT_SSL_PROTOCOLS private (or
package-private) and add a public accessor method getDefaultSslProtocols() that
returns either an immutable list/array copy or a defensive copy of the
protocols, and update all callers to use that accessor instead of the field to
prevent runtime mutation and preserve encapsulation.
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java
Show resolved
Hide resolved
...ransport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java
Show resolved
Hide resolved
|
❌ Gradle check result for 1ccdf5a: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java (1)
153-165: HTTP/3 protocol string comparison is incorrect—will reject valid HTTP/3 requestsThe code checks for
"HTTP/3.0":} else if (protocol.equals("HTTP/3.0")) { return HttpRequest.HttpVersion.HTTP_3_0;However, Reactor Netty's
HttpServerRequest.protocol()returns"HTTP/3"(not"HTTP/3.0") for HTTP/3 requests. This mismatch means the condition will never match and HTTP/3 requests will fall through to theIllegalArgumentException("Unexpected http protocol version: " + protocol)path, causing runtime failures.Change the comparison to:
} else if (protocol.equals("HTTP/3")) { return HttpRequest.HttpVersion.HTTP_3_0; }
♻️ Duplicate comments (8)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (1)
553-597:testReadTimeoutstill uses TCP channel instead of QUIC/UDP, so it likely doesn’t exercise HTTP/3 behaviorThis test bootstraps a
NioSocketChannel(TCP) client and connects it to a server that is intended to speak QUIC/HTTP3. That TCP connection will not behave like an HTTP/3/QUIC client and is unlikely to validate the intended read-timeout behavior on the QUIC transport. This concern matches a previous review on an earlier revision of this test.Consider reworking the test to use the existing HTTP/3 client helper, for example:
- Replace the raw
Bootstrap/NioSocketChannelclient withtry (Netty4HttpClient client = Netty4HttpClient.http3()) { ... }and send a request that intentionally stalls, or- If you need a lower-level check, use a UDP/
NioDatagramChannel‑based QUIC client that mirrors howNetty4HttpClient.http3()sets up QUIC/HTTP3.This will ensure the read-timeout logic is actually exercised in the HTTP/3/QUIC code path rather than via a mismatched TCP connection.
modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java (1)
27-27: Security risk: Mutable array exposed as public API.As flagged in a previous review, changing
DEFAULT_SSL_PROTOCOLStopublic static finalexposes a mutable array. Callers can modify elements at runtime (e.g.,DEFAULT_SSL_PROTOCOLS[0] = "TLSv1"), altering TLS behavior globally—a security configuration surface that must not be externally mutable.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java (2)
39-44: Close listener will be invoked multiple times.As previously noted, the listener is added to each
closeContext, causing it to fire once per channel closure. If the caller expects a single notification when all channels have closed, this will cause unexpected behavior.
25-32: Validate constructor parameters.The constructor does not validate that
channelsis non-null and non-empty. Line 36'sgetLocalAddress()will throwArrayIndexOutOfBoundsExceptionif an empty array is passed.Add validation at the start of the constructor:
ReactorNetty4CompositeHttpServerChannel(Channel... channels) { + if (channels == null || channels.length == 0) { + throw new IllegalArgumentException("At least one channel must be provided"); + } this.channels = channels;plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (2)
304-306: Returningnullfromchannel()may cause NPE.As flagged previously, the anonymous
DisposableServerreturnsnullforchannel(). Downstream code expecting a valid channel reference will encounterNullPointerException.
299-300: HTTP/3 server not cleaned up if HTTP/1.1/2 bind fails.As noted in a previous review, if
http11or2.bindNow()(Line 300) throws afterhttp3Serverhas successfully bound (Line 299), the HTTP/3 server remains bound, leaking resources.modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (2)
273-273: Security:InsecureQuicTokenHandlerbypasses QUIC token validation.This handler disables address validation tokens, which protect against address spoofing attacks (RFC 9000 Section 8). This was previously flagged and should be addressed before production use.
Consider introducing a configuration setting to control token handler behavior, defaulting to a secure implementation for production.
331-332: Header verification and decompression are disabled.These handlers are commented out, which means:
createHeaderVerifier()is never invoked, so plugins cannot verify headers.createDecompressor()is never invoked, so compressed request bodies won't be decompressed.This breaks feature parity with
Netty4HttpServerTransportand could cause functional issues with compressed requests.- ch.pipeline().addLast(new Http3FrameToHttpObjectCodec(true)); - // ch.pipeline().addLast("header_verifier", transport.createHeaderVerifier()); - // ch.pipeline().addLast("decoder_compress", transport.createDecompressor()); + ch.pipeline().addLast("http3_codec", new Http3FrameToHttpObjectCodec(true)); + ch.pipeline().addLast("header_verifier", transport.createHeaderVerifier()); + ch.pipeline().addLast("decoder_compress", transport.createDecompressor());
🧹 Nitpick comments (11)
test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (2)
54-55: Consider adding a brief Javadoc or null guard.For a public API in the test framework, consider documenting the expected algorithm values or adding a null check. Since
Algorithmis an enum, a null argument would cause a NullPointerException ingenerateCert. A brief Javadoc noting FIPS constraints (per the comment ingenerateCert) would help callers choose appropriate algorithms.+ /** + * Creates a server keystore with a self-signed certificate using the specified algorithm. + * When FIPS mode is enabled, use FIPS-approved algorithms: rsa2048, rsa3072, rsa4096, rsa8192, ecp256, ecp384. + */ public static KeyStore createServerKeyStore(Algorithm algorithm) throws Exception { + if (algorithm == null) { + throw new IllegalArgumentException("algorithm must not be null"); + } var serverCred = generateCert(algorithm);
67-77: Update comment to reflect parameterized algorithm.The comment on lines 71-72 states "must use FIPS-approved algorithms" but the method now accepts any
Algorithmvalue from the caller. Consider updating the comment to clarify this is the caller's responsibility, or note that theBouncyCastleFipsProviderwill reject non-approved algorithms at runtime when FIPS mode is enabled.- // must use FIPS-approved algorithms like rsa2048, rsa3072, rsa4096, rsa8192, ecp256, ecp384 - // reference: https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4943 + // When FIPS mode is enabled, callers must provide a FIPS-approved algorithm + // (e.g., rsa2048, rsa3072, rsa4096, rsa8192, ecp256, ecp384). + // Reference: https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4943 return new CertificateBuilder().subject("CN=Test CA Certificate")modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java (2)
161-161: Simplify the boolean comparison.The comparison
directBuffers == trueis redundant. Simplify to justdirectBuffersfor cleaner, more idiomatic code.Apply this diff:
- if (directBuffers == true && ALLOCATOR instanceof NoDirectBuffers ndb) { + if (directBuffers && ALLOCATOR instanceof NoDirectBuffers ndb) {
160-166: Consider adding Javadoc for this public API method.The new method correctly handles HTTP/3/QUIC's direct buffer requirement by unwrapping the NoDirectBuffers delegate when needed. However, as a public API method, it would benefit from Javadoc explaining:
- The purpose and use case (HTTP/3/QUIC support)
- The
directBuffersparameter behavior- Return value semantics (when delegate vs. ALLOCATOR is returned)
Example Javadoc:
/** * Returns a ByteBufAllocator that supports the specified buffer type. * * @param directBuffers if true, returns an allocator capable of creating direct buffers. * This is required for HTTP/3 and QUIC protocols. If the current * allocator is wrapped with NoDirectBuffers, returns the underlying * delegate; otherwise returns the standard allocator. * @return a ByteBufAllocator instance */ public static ByteBufAllocator getAllocator(boolean directBuffers) {plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (1)
101-120: Client factory updates correctly reflect new Settings-based APIUsing
ReactorHttpClient.create(false, Settings.EMPTY)in these ITs matches the revised factory signature and keeps the client behavior explicit and isolated from clusternodeSettings. If you later want to exercise HTTP/3 here, consider passing the samenodeSettings(int nodeOrdinal)instead ofSettings.EMPTY.Also applies to: 131-143
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
74-79: Random protocol selection may introduce unnecessary test nondeterminism
ReactorHttpClientnow randomly chooses among HTTP/1.1, HTTP/2, and optionally HTTP/3 per instance viarandomProtocol(secure, settings). This keeps tests covering multiple protocols, but as HTTP/3 gets enabled this randomness can make failures harder to reproduce and reason about.Consider (optionally) exposing the chosen
HttpProtocolor allowing tests to inject a fixed protocol, then retaining randomness only where you explicitly want multi‑protocol coverage.Also applies to: 96-101, 330-348
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (1)
384-390: Safer ByteBuf to String conversion intestBadRequest
new String(response.content().array(), Charset.forName("UTF-8"))assumes the buffer is backed by an accessible array, which may not always be true for NettyByteBufs.You already use
ByteBufUtil.getBytes(..., StandardCharsets.UTF_8)elsewhere in this class; using the same here would be safer and more consistent:- assertThat( - new String(response.content().array(), Charset.forName("UTF-8")), - containsString("you sent a bad request and you should feel bad") - ); + byte[] bytes = ByteBufUtil.getBytes(response.content()); + assertThat( + new String(bytes, StandardCharsets.UTF_8), + containsString("you sent a bad request and you should feel bad") + );plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
327-327: Remove redundant boolean comparison.The expression
.booleanValue() == trueis redundant.get(settings)returns aBooleanthat auto-unboxes in theifcondition.Simplify to:
- if (Http3.isHttp3Available() && SETTING_HTTP_HTTP3_ENABLED.get(settings).booleanValue() == true) { + if (Http3.isHttp3Available() && SETTING_HTTP_HTTP3_ENABLED.get(settings)) {modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (3)
119-119: Add validation bounds forh3.max_streamssetting.The setting lacks minimum value validation. Per RFC 9000 and the Javadoc comment on lines 113-117, HTTP/3 expects at least 100 concurrent bidirectional streams. A value of 0 or negative would cause unexpected behavior.
- public static final Setting<Long> SETTING_H3_MAX_STREAMS = Setting.longSetting("h3.max_streams", 100L, Property.NodeScope); + public static final Setting<Long> SETTING_H3_MAX_STREAMS = Setting.longSetting("h3.max_streams", 100L, 1L, Property.NodeScope);
164-165: UnusedexceptionHandlerfield.The
exceptionHandleris initialized but never used anywhere in the class. Either integrate it into exception handling paths (e.g., inonException()orHttpChannelHandler.exceptionCaught()) or remove the dead code.If intended to delegate exception handling, consider integrating it:
@Override public void onException(HttpChannel channel, Exception cause) { + exceptionHandler.onError(cause); if (cause instanceof ReadTimeoutException) { super.onException(channel, new HttpReadTimeoutException(readTimeoutMillis, cause)); } else { super.onException(channel, cause); } }
308-310: UnusedgetRequestHandler()method.This public accessor is defined but never called. Consider removing it if not needed, or document its intended use case for plugin extensibility.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (43)
CHANGELOG.md(1 hunks)gradle/libs.versions.toml(1 hunks)modules/transport-netty4/build.gradle(2 hunks)modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java(2 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java(1 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java(10 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java(1 hunks)plugins/repository-azure/build.gradle(0 hunks)plugins/transport-reactor-netty4/build.gradle(2 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java(2 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java(2 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java(5 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java(3 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java(7 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java(12 hunks)server/src/main/java/org/opensearch/bootstrap/Security.java(1 hunks)server/src/main/java/org/opensearch/http/HttpRequest.java(1 hunks)server/src/main/java/org/opensearch/http/HttpTransportSettings.java(1 hunks)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java(2 hunks)
💤 Files with no reviewable changes (1)
- plugins/repository-azure/build.gradle
✅ Files skipped from review due to trivial changes (4)
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
🚧 Files skipped from review as they are similar to previous changes (16)
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- server/src/main/java/org/opensearch/http/HttpTransportSettings.java
- server/src/main/java/org/opensearch/http/HttpRequest.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java
- CHANGELOG.md
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
🧰 Additional context used
🧬 Code graph analysis (6)
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java (1)
server/src/main/java/org/opensearch/http/AbstractHttpServerTransport.java (1)
AbstractHttpServerTransport(93-507)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (4)
server/src/main/java/org/opensearch/http/AbstractHttpServerTransport.java (1)
AbstractHttpServerTransport(93-507)server/src/main/java/org/opensearch/bootstrap/Bootstrap.java (1)
Bootstrap(89-495)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java (3)
ChannelHandler(543-562)Netty4HttpServerTransport(130-635)HttpChannelHandler(364-541)server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (4)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)server/src/main/java/org/opensearch/rest/BytesRestResponse.java (1)
BytesRestResponse(59-219)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
KeyStoreUtils(26-83)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java (1)
SslUtils(26-107)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: gradle-check
- GitHub Check: assemble (25, ubuntu-24.04-arm)
- GitHub Check: precommit (25, ubuntu-24.04-arm)
- GitHub Check: assemble (21, windows-latest)
- GitHub Check: assemble (21, ubuntu-24.04-arm)
- GitHub Check: precommit (21, macos-15)
- GitHub Check: assemble (25, windows-latest)
- GitHub Check: assemble (25, ubuntu-latest)
- GitHub Check: precommit (21, macos-15-intel)
- GitHub Check: precommit (25, macos-15)
- GitHub Check: precommit (21, windows-2025, true)
- GitHub Check: precommit (21, windows-latest)
- GitHub Check: precommit (25, windows-latest)
- GitHub Check: precommit (25, macos-15-intel)
- GitHub Check: assemble (21, ubuntu-latest)
- GitHub Check: precommit (21, ubuntu-24.04-arm)
- GitHub Check: precommit (25, ubuntu-latest)
- GitHub Check: precommit (21, ubuntu-latest)
- GitHub Check: detect-breaking-change
- GitHub Check: Analyze (java)
- GitHub Check: Mend Security Check
🔇 Additional comments (17)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java (1)
198-208: Javadoc typo fix is correctThe updated
@param settings settingsJavadoc is accurate and has no behavioral impact. Looks good to keep as-is.modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java (2)
35-37: ImportingAbstractHttpServerTransportis consistent with transport abstractionSwitching the dependency to the abstract base transport aligns this handler with the shared HTTP transport layer, which is a good fit given the methods it uses (
incomingRequest,onException) are defined there.
46-50: GeneralizingserverTransporttoAbstractHttpServerTransportlooks correctThe field and constructor now depend on
AbstractHttpServerTransportwhile the handler still only calls methods provided by that base class, so behavior is unchanged while reducing coupling toNetty4HttpServerTransport. This will also ease reuse with additional HTTP transports (e.g., HTTP/3) that extend the abstract transport.test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
50-52: LGTM!Clean backward-compatible delegation pattern. The default
Algorithm.rsa2048maintains the previous behavior and is FIPS-approved.server/src/main/java/org/opensearch/bootstrap/Security.java (2)
259-286: Verify test coverage for classifier handling logic.The two-pass approach for handling JARs with classifiers is sound: the first pass separates classified JARs, and the second pass processes them with conflict resolution via the "@" + classifier suffix.
Ensure that test coverage exists for:
- JARs with platform-specific classifiers (e.g.,
linux-x86_64,osx-aarch_64)- Multiple JARs with the same base name but different classifiers
- The conflict resolution logic when
aliasPropertyalready exists
132-134: The regex pattern correctly handles platform-specific classifier extraction for HTTP/3 dependency JARs. All provided examples match the pattern as intended, including netty-tcnative-boringssl-static artifacts with platform classifiers likelinux-x86_64. The concern about compound classifiers likesnapshot-8a555ebis based on a misunderstanding of classifier definitions—pre-release version metadata is distinct from classifiers and is not intended to be extracted by this pattern.No action required; the implementation is sound.
modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1 (1)
1-1: Checksum file format looks correctSingle-line 40‑character hex digest matches expected
.sha1format; nothing to change.plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1 (1)
1-1: Checksum entry is well-formedSHA‑1 checksum line is correctly formatted; aligns with other license checksum artifacts.
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
83-118: Updated ReactorHttpClient.create(settings) usage is consistent with new APISwitching to
ReactorHttpClient.create(settings)matches the updated factory signature and reuses the samesettingsused to configure the server transport; this keeps protocol selection (incl. HTTP/3 when enabled) consistent between client and server in this test.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
96-113: HTTP/1.1 / HTTP/2 / HTTP/3 wiring increateClientlooks aligned with Reactor Netty usageThe refactor to:
- store a per-instance
HttpProtocol protocol,- build HTTP/1.1 via
Http11SslContextSpec.forClient(),- build HTTP/2 via
Http2SslContextSpec.forClient()with{HTTP11, H2}protocols, and- build HTTP/3 via
Http3SslContextSpec.forClient()plushttp3Settings(...),matches Reactor Netty’s documented patterns for enabling HTTP/3 and configuring QUIC settings (idle timeout, max data, streams). Using
SETTING_HTTP_HTTP3_ENABLEDtogether withHttp3.isHttp3Available()to gate HTTP/3 is also a sensible guard.Please double-check against the Reactor Netty version you use that:
Http3SslContextSpec.forClient().configure(...)is the recommended pattern, and- chaining
.secure(...).http3Settings(...)on the client is supported forHttpProtocol.HTTP3.If your version’s API differs, you may need to adjust the builder chaining accordingly.
Also applies to: 276-323
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
176-185: HTTP/3 client path and pipeline ordering look correct for test usageThe new HTTP/3 support in
Netty4HttpClient:
- Uses
NioDatagramChanneland QUIC codecs on the datagram channel,- Bootstraps a
QuicChanneland HTTP/3 request stream,- Installs
Http3FrameToHttpObjectCodec(false)before the decompressor and aggregator, and- Reuses the familiar “copy content, add to list, count down latch” pattern,
which lines up with Netty’s guidance for HTTP/3 client pipelines and addresses earlier feedback about mixing HTTP/1.x codecs into an HTTP/3 pipeline. The
AwaitableChannelInitializer<C>+prepare(...)hook also keeps the HTTP/1.1, HTTP/2, and HTTP/3 code paths unified without complicating the calling code.If you upgrade Netty HTTP/3 in the future, it’s worth re-checking that:
Http3.newQuicClientCodecBuilder()andHttp3.newRequestStream(...)remain the recommended entry points, andHttp3FrameToHttpObjectCodec(false)is still the appropriate adapter for client-side streams.Also applies to: 234-263, 328-336, 469-533
gradle/libs.versions.toml (1)
152-153: LGTM!The QUIC library entries follow the established pattern and correctly reference the Netty version.
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
122-122: LGTM!The test updates correctly adapt to the new
ReactorHttpClient.create(boolean, Settings)API signature by passingSettings.EMPTY.Also applies to: 162-162
modules/transport-netty4/build.gradle (1)
66-68: LGTM!The QUIC/HTTP3 dependencies are correctly declared as
api(exposing them to consumers) and native binaries are appropriately scoped asruntimeOnlyfor all supported platforms.Also applies to: 79-84
plugins/transport-reactor-netty4/build.gradle (1)
38-39: LGTM!The QUIC library dependencies mirror the transport-netty4 module's pattern and correctly expose codecs via
apiwhile bundling platform-specific native binaries asruntimeOnly.Also applies to: 42-46
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (2)
194-244: LGTM!The lifecycle methods (
doStart,bind,stopInternal,onException) follow established patterns from the existing HTTP/1.x transport. The proper cleanup in thefinallyblock and ReadTimeoutException wrapping are well implemented.
387-439: LGTM!The
defaultCompressionOptions()implementation correctly excludes ZSTD due to direct buffer constraints and provides Brotli conditionally when available. This matches the behavior inNetty4HttpServerTransport.
| @ChannelHandler.Sharable | ||
| private static class ServerChannelExceptionHandler extends ChannelInboundHandlerAdapter { | ||
|
|
||
| private final Netty4QuicServerTransport transport; | ||
|
|
||
| private ServerChannelExceptionHandler(Netty4QuicServerTransport transport) { | ||
| this.transport = transport; | ||
| } | ||
|
|
||
| @Override | ||
| public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { | ||
| ExceptionsHelper.maybeDieOnAnotherThread(cause); | ||
| Netty4HttpServerChannel httpServerChannel = ctx.channel().attr(HTTP_SERVER_CHANNEL_KEY).get(); | ||
| if (cause instanceof Error) { | ||
| transport.onServerException(httpServerChannel, new Exception(cause)); | ||
| } else { | ||
| transport.onServerException(httpServerChannel, (Exception) cause); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
ServerChannelExceptionHandler is defined but never used.
This class is never instantiated or added to any pipeline. Either integrate it into configureServerChannelHandler() for proper server-level exception handling, or remove the dead code.
If this should handle server channel exceptions, add it to the QUIC server codec's parent channel:
// In configureServerChannelHandler(), after adding the QUIC server codec:
ch.pipeline().addLast("server_exception_handler", new ServerChannelExceptionHandler(Netty4QuicServerTransport.this));|
❌ Gradle check result for a37d345: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
192-192: Scheme header logic is inverted.The ternary is backwards: it sets scheme to "http" when
secureis true, and "https" when false.- httpRequest.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), secure ? "http" : "https"); + httpRequest.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), secure ? "https" : "http");
♻️ Duplicate comments (5)
modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java (1)
27-27: Mutable array exposure concern already flagged.The previous review correctly identified the security concern with exposing
DEFAULT_SSL_PROTOCOLSas a mutable public array. The suggested fix (making it private with a defensive copy accessor) should be applied.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
272-317: Fix lifecycle coupling between HTTP/3 and HTTP/1.1/2 servers and avoidnullchannel()Two issues remain in the combined bind path:
Resource leak on HTTP/1.1/2 bind failure
Ifhttp11or2.bindNow()throws afterhttp3Serverhas already bound, the HTTP/3 server is left running with no reference indisposableServer, sostopInternal()will never dispose it.
DisposableServer.channel()returnsnull
Returningnullfromchannel()in the compositeDisposableServercan cause NPEs if any code assumes a non-null server channel (e.g., for logging or metrics).You can address both by disposing HTTP/3 on HTTP/1.1/2 bind failure and having
channel()delegate to one of the underlying servers (typically the TCP HTTP/1.1/2 server):@@ - } else { - final DisposableServer http3Server = http3Opt.get(); - final DisposableServer http11or2Server = http11or2.bindNow(); - - disposableServer = new DisposableServer() { - @Override - public Channel channel() { - return null; /* not implemented */ - } - - @Override - public void disposeNow() { - http3Server.disposeNow(); - http11or2Server.disposeNow(); - } - }; - - return new ReactorNetty4CompositeHttpServerChannel(http11or2Server.channel(), http3Server.channel()); - } + } else { + final DisposableServer http3Server = http3Opt.get(); + final DisposableServer http11or2Server; + try { + http11or2Server = http11or2.bindNow(); + } catch (Exception e) { + http3Server.disposeNow(); + throw e; + } + + disposableServer = new DisposableServer() { + @Override + public Channel channel() { + // Expose the TCP server channel for compatibility with existing usages. + return http11or2Server.channel(); + } + + @Override + public void disposeNow() { + http3Server.disposeNow(); + http11or2Server.disposeNow(); + } + }; + + return new ReactorNetty4CompositeHttpServerChannel(http11or2Server.channel(), http3Server.channel()); + }#!/bin/bash # Verify whether any code relies on disposableServer.channel() rg -n "disposableServer\.channel\(" .plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java (1)
20-44: Harden composite channel against empty input and avoid multi‑invoking close listenersThe current implementation has two issues:
- No guard against
channels.length == 0, which would breakgetLocalAddress()and loops if misused.addCloseListenerwires the same listener to everycloseContext, so it fires once per underlying channel instead of once when the composite is fully closed.Consider validating input and aggregating close completion so the listener runs exactly once when all channels are closed:
@@ -import java.net.InetSocketAddress; +import java.net.InetSocketAddress; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; @@ - @SuppressWarnings({ "unchecked", "rawtypes" }) - ReactorNetty4CompositeHttpServerChannel(Channel... channels) { - this.channels = channels; + @SuppressWarnings({ "unchecked", "rawtypes" }) + ReactorNetty4CompositeHttpServerChannel(Channel... channels) { + if (channels == null || channels.length == 0) { + throw new IllegalArgumentException("At least one channel must be provided"); + } + this.channels = channels; this.closeContexts = new CompletableContext[channels.length]; for (int i = 0; i < channels.length; ++i) { closeContexts[i] = new CompletableContext<>(); Netty4Utils.addListener(this.channels[i].closeFuture(), closeContexts[i]); } } @@ @Override public void addCloseListener(ActionListener<Void> listener) { - for (int i = 0; i < closeContexts.length; ++i) { - closeContexts[i].addListener(ActionListener.toBiConsumer(listener)); - } + final AtomicInteger remaining = new AtomicInteger(closeContexts.length); + final AtomicReference<Exception> firstFailure = new AtomicReference<>(); + + final ActionListener<Void> composite = new ActionListener<>() { + @Override + public void onResponse(Void unused) { + if (remaining.decrementAndGet() == 0) { + final Exception failure = firstFailure.get(); + if (failure != null) { + listener.onFailure(failure); + } else { + listener.onResponse(null); + } + } + } + + @Override + public void onFailure(Exception e) { + firstFailure.compareAndSet(null, e); + if (remaining.decrementAndGet() == 0) { + listener.onFailure(firstFailure.get()); + } + } + }; + + for (int i = 0; i < closeContexts.length; ++i) { + closeContexts[i].addListener(ActionListener.toBiConsumer(composite)); + } }modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (2)
349-368: Remove unused ServerChannelExceptionHandler class.This exception handler is defined but never instantiated or added to any pipeline. Either integrate it into the server channel setup or remove it as dead code.
If server-level exception handling is needed, add it in
configureServerChannelHandler()around line 280:ch.pipeline().remove(this); + ch.pipeline().addLast("server_exception_handler", new ServerChannelExceptionHandler(Netty4QuicServerTransport.this)); }Otherwise, delete lines 349-368.
271-273: Replace InsecureQuicTokenHandler with secure implementation before production.
InsecureQuicTokenHandler.INSTANCEbypasses QUIC's address validation token mechanism, making the server vulnerable to address spoofing and amplification attacks. This is unacceptable for production deployments.Based on learnings from past reviews, this was previously flagged and remains unaddressed. Since this is marked as [WIP], ensure this is resolved before marking the PR ready for merge.
🧹 Nitpick comments (4)
modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java (1)
160-166: Consider using the public accessor and simplifying the boolean check.The logic is correct for enabling HTTP/3/QUIC which requires direct buffers. Two minor improvements:
- Use
directBuffersinstead ofdirectBuffers == truefor idiomatic boolean checks- Consider using the public
getDelegate()accessor instead of directly accessing the privatedelegatefield for better encapsulationpublic static ByteBufAllocator getAllocator(boolean directBuffers) { - if (directBuffers == true && ALLOCATOR instanceof NoDirectBuffers ndb) { - return ndb.delegate; /* Http3/Quic only supports direct buffers */ + if (directBuffers && ALLOCATOR instanceof NoDirectBuffers ndb) { + return ndb.getDelegate(); /* Http3/Quic only supports direct buffers */ } else { return ALLOCATOR; } }test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
67-81: Consider adding null check for algorithm parameter.The
generateCertmethod could throw an NPE if called with a null algorithm. Since this is test code, the risk is low, but a defensive check would be prudent.private static X509Bundle generateCert(Algorithm algorithm) throws Exception { + if (algorithm == null) { + throw new IllegalArgumentException("Algorithm must not be null"); + } final Locale locale = Locale.getDefault();gradle/libs.versions.toml (1)
152-153: QUIC library entries are consistent; bundle inclusion is optionalThe new
netty-codec-native-quicandnetty-codec-classes-quicentries correctly reuse the sharednettyversion. If you expect these to be treated like the other Netty artifacts, consider adding them to thenettybundle; otherwise, explicit dependency wiring as in the module build files is fine.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
319-367: HTTP/3 configuration gating is correct; enhance logging to detect both classpath and runtime native library issuesThe
configureHttp3method correctly gates HTTP/3 onsecureHttpTransportSettingsProvider,Http3.isHttp3Available()(classpath check), andSETTING_HTTP_HTTP3_ENABLED. However,Http3.isHttp3Available()only verifies that the Netty HTTP/3 codec artifact is present on the classpath—it does not verify that native QUIC libraries are available at runtime. For operators to diagnose missing or failed-to-load native libraries, consider adding structured logging at startup that checks both:
Http3.isHttp3Available()(classpath availability)io.netty.incubator.codec.quic.Quic.isAvailable()andQuic.unavailabilityCause()(runtime native library status)Additionally, enable SLF4J DEBUG/TRACE logging for
reactor.nettyandnetty.*packages and consider callingwarmup()on the HttpServer during initialization to force native library preloading before handling requests.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (43)
CHANGELOG.md(1 hunks)gradle/libs.versions.toml(1 hunks)modules/transport-netty4/build.gradle(2 hunks)modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java(2 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java(1 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java(10 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java(1 hunks)plugins/repository-azure/build.gradle(0 hunks)plugins/transport-reactor-netty4/build.gradle(2 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java(2 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java(2 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java(5 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java(3 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java(7 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java(12 hunks)server/src/main/java/org/opensearch/bootstrap/Security.java(1 hunks)server/src/main/java/org/opensearch/http/HttpRequest.java(1 hunks)server/src/main/java/org/opensearch/http/HttpTransportSettings.java(1 hunks)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java(2 hunks)
💤 Files with no reviewable changes (1)
- plugins/repository-azure/build.gradle
✅ Files skipped from review due to trivial changes (4)
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- CHANGELOG.md
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
🚧 Files skipped from review as they are similar to previous changes (19)
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java
- modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java
- server/src/main/java/org/opensearch/http/HttpRequest.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java
- server/src/main/java/org/opensearch/bootstrap/Security.java
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
🧰 Additional context used
🧬 Code graph analysis (4)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (9)
server/src/main/java/org/opensearch/index/search/SimpleQueryStringQueryParser.java (1)
Settings(317-450)libs/core/src/main/java/org/opensearch/core/common/bytes/BytesArray.java (1)
BytesArray(48-151)server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)server/src/main/java/org/opensearch/rest/BytesRestResponse.java (1)
BytesRestResponse(59-219)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
KeyStoreUtils(26-83)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java (1)
NettyAllocator(51-350)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java (1)
SslUtils(26-107)server/src/main/java/org/opensearch/bootstrap/Bootstrap.java (1)
Bootstrap(89-495)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
Netty4HttpClient(114-535)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: gradle-check
- GitHub Check: Analyze (java)
- GitHub Check: assemble (25, windows-latest)
- GitHub Check: assemble (25, ubuntu-24.04-arm)
- GitHub Check: assemble (21, ubuntu-latest)
- GitHub Check: assemble (21, windows-latest)
- GitHub Check: assemble (25, ubuntu-latest)
- GitHub Check: assemble (21, ubuntu-24.04-arm)
- GitHub Check: precommit (25, ubuntu-latest)
- GitHub Check: precommit (21, macos-15-intel)
- GitHub Check: precommit (25, macos-15)
- GitHub Check: precommit (21, windows-2025, true)
- GitHub Check: precommit (25, windows-latest)
- GitHub Check: precommit (25, macos-15-intel)
- GitHub Check: precommit (21, windows-latest)
- GitHub Check: precommit (21, ubuntu-24.04-arm)
- GitHub Check: precommit (25, ubuntu-24.04-arm)
- GitHub Check: precommit (21, ubuntu-latest)
- GitHub Check: precommit (21, macos-15)
- GitHub Check: detect-breaking-change
- GitHub Check: Mend Security Check
🔇 Additional comments (18)
plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1 (1)
1-1: LGTM!SHA1 checksum file for the Netty QUIC native library (macOS aarch64) is correctly added as part of the HTTP/3 dependency additions.
test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
50-65: Good backward-compatible refactoring for algorithm flexibility.Clean approach: the no-arg
createServerKeyStore()delegates to the parameterized overload with a sensible default (Algorithm.rsa2048), preserving backward compatibility while enabling algorithm flexibility for HTTP/3/QUIC testing.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (4)
176-184: HTTP/3 factory method looks correct.Good additions:
- Uses
NioDatagramChannelfor UDP transport (required for QUIC)- Uses
NettyAllocator.getAllocator(true)to enable direct buffers (required for QUIC)- Properly wires
CountDownLatchHandlerHttp3Note: The
secure=falseparameter is somewhat misleading since HTTP/3 always uses TLS via QUIC, but this only affects the scheme header logic which has a separate issue (see below).
328-336: Good abstraction for channel preparation.The generic
AwaitableChannelInitializer<C extends Channel>with aprepare()hook is a clean way to support different transport protocols (TCP for HTTP/1.1 & HTTP/2, UDP+QUIC for HTTP/3) while maintaining a uniform request dispatch flow.
498-533: Verify HTTP/3 stream handling for multiple requests.The
prepare()method creates a singleQuicStreamChannelwhich is then used to send all requests. In HTTP/3, each request typically uses its own stream for proper multiplexing. Sending multiple requests on a single stream may not work as expected with an HTTP/3 server.For single-request tests this is fine, but for multi-request scenarios (e.g., the
get(SocketAddress, String...)method with multiple URIs), this may need adjustment.Consider whether multi-request tests are needed for HTTP/3, and if so, refactor to create a new stream per request:
// Alternative approach for multi-request support: // Instead of returning one channel from prepare(), // could override the request dispatch logic for HTTP/3
507-531: Pipeline order is now correct.The HTTP/3 pipeline follows the correct order:
Http3FrameToHttpObjectCodec(false)- converts HTTP/3 frames to HTTP objectsHttpContentDecompressor- handles content decompressionHttpObjectAggregator- aggregates HTTP objects- Response handler
This addresses the previous review feedback.
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java (1)
47-47: Client factory update is consistent with new APIUsing
ReactorHttpClient.create(Settings.EMPTY)correctly matches the new factory signature and preserves the existing test behavior.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
83-101: Passing settings intoReactorHttpClient.createlooks correctReusing the same
settingsobject for both the server transport andReactorHttpClient.create(settings)keeps test configuration coherent and matches the updated client API.server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
262-267: New HTTP/3 enable flag is well-scoped
SETTING_HTTP_HTTP3_ENABLEDis a reasonable node-scoped boolean gate for HTTP/3; wiring to transports and documentation just needs to stay in sync with this key.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
122-123: Streaming tests correctly adopt new client factory signatureBoth tests now use
ReactorHttpClient.create(false, Settings.EMPTY), which matches the updated API and maintains the intended non-secure streaming behavior.Also applies to: 162-163
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (1)
104-105: HTTP request size limit ITs use the new client factory correctlySwitching to
ReactorHttpClient.create(false, Settings.EMPTY)in both tests aligns with the updated client API without changing the behavior of the in-flight request limiting checks.Also applies to: 134-135
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
110-136: H3 stream/window settings and defaults look reasonableThe new
SETTING_H3_MAX_STREAM_LOCAL_LENGTH,SETTING_H3_MAX_STREAM_REMOTE_LENGTH, andSETTING_H3_MAX_STREAMSprovide explicit HTTP/3 flow-control tuning with sensible defaults (~1 MB per stream, 100 streams), which aligns connection limits inconfigureHttp3with typical HTTP/3 expectations.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
334-348: LGTM! Protocol selection logic is sound.The randomProtocol method correctly:
- Checks HTTP/3 availability via
Http3.isHttp3Available()- Respects the
SETTING_HTTP_HTTP3_ENABLEDsetting- Falls back to HTTP/1.1 and H2/H2C appropriately for secure/non-secure contexts
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (1)
330-346: Pipeline configuration correctly adapted for HTTP/3.The pipeline now properly uses
Http3FrameToHttpObjectCodecas the first handler to convert QUIC/HTTP3 frames to HttpObjects before other handlers process them. The HTTP/1.x-specific codecs (HttpRequestDecoder, HttpResponseEncoder) have been correctly removed.modules/transport-netty4/build.gradle (1)
66-84: LGTM! QUIC/HTTP3 dependencies properly configured.The build configuration correctly:
- Adds QUIC codec dependencies (http3, classes-quic, native-quic)
- Bundles native libraries for all major OS/architecture combinations
- Uses runtimeOnly scope for platform-specific binaries
plugins/transport-reactor-netty4/build.gradle (1)
38-46: LGTM! Consistent QUIC dependency configuration.The reactor-netty4 plugin build configuration mirrors the netty4 module's QUIC setup, ensuring consistent HTTP/3 support across transport implementations.
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (2)
187-285: Well-structured Expect header tests.The test correctly validates:
- 100-Continue support with valid content-length
- 413 response for oversized payloads
- 417 response for unsupported expectations
The continuation request pattern properly simulates real client behavior.
110-170: Proper TLS setup for HTTP/3 testing.The test harness correctly:
- Uses PKIX KeyManagerFactory with ECP384 algorithm
- Provides SecureHttpTransportSettingsProvider with appropriate SSL configuration
- Configures InsecureTrustManagerFactory for test purposes (acceptable in tests)
modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
Show resolved
Hide resolved
...les/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java
Outdated
Show resolved
Hide resolved
...ransport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java
Show resolved
Hide resolved
...sport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java
Show resolved
Hide resolved
|
❌ Gradle check result for bddf29b: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
♻️ Duplicate comments (4)
modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java (1)
27-27: Exposing mutableDEFAULT_SSL_PROTOCOLSarray remains a security concern.This change still exposes a mutable array as public API, allowing any caller to modify TLS protocol versions at runtime (e.g.,
DEFAULT_SSL_PROTOCOLS[0] = "TLSv1"). The previous review comment correctly identified this as a security posture gap that breaks encapsulation.The recommendation to keep the array private and provide a defensive-copy accessor (e.g.,
getDefaultSslProtocols()) should be implemented to prevent runtime mutation of security-critical TLS configuration.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
273-317: Critical: Composite binding still has unresolved issues from previous review.Two critical issues were flagged in previous reviews and appear unresolved:
- Lines 304-305:
channel()returnsnull, which can cause NPE if callers invoke it- Lines 269-270: If
http11or2.bindNow()throws afterhttp3Serverbinds successfully, the HTTP/3 server is not cleaned up, causing a resource leakThese issues remain from the previous review marked with ``.
Please address both issues:
- Return a valid channel from
channel()(e.g.,http11or2Server.channel()) or throwUnsupportedOperationException- Wrap
http11or2.bindNow()in try-catch to disposehttp3Serveron failure:final DisposableServer http3Server = http3Opt.get(); - final DisposableServer http11or2Server = http11or2.bindNow(); + final DisposableServer http11or2Server; + try { + http11or2Server = http11or2.bindNow(); + } catch (Exception e) { + http3Server.disposeNow(); + throw e; + }modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (2)
349-368: Remove unusedServerChannelExceptionHandlerclass.This class is defined but never instantiated or added to any pipeline. Either integrate it into
configureServerChannelHandler()for proper server-level exception handling, or remove the dead code.If this should handle server channel exceptions, add it to the QUIC codec's parent handler:
// In configureServerChannelHandler(), after building the QUIC codec: ch.pipeline().addLast("server_exception_handler", new ServerChannelExceptionHandler(Netty4QuicServerTransport.this));
273-273: Security:InsecureQuicTokenHandlerbypasses QUIC address validation.This handler disables QUIC token validation which protects against address spoofing attacks (RFC 9000, Section 8). While acceptable for development, this must be replaced with a proper token handler before production use.
Consider adding a configuration option or TODO to track this:
+ // TODO: Issue #XXXX - Replace with secure token handler before GA + // InsecureQuicTokenHandler bypasses address validation (RFC 9000 Section 8) .tokenHandler(InsecureQuicTokenHandler.INSTANCE)
🧹 Nitpick comments (4)
modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java (1)
160-166:getAllocator(boolean)correctly unwrapsNoDirectBuffers; consider clarifying API semanticsThe conditional unwrapping of
NoDirectBuffersto expose the underlying delegate whendirectBuffersistruelooks correct and keeps existing callers (no-arggetAllocator()) unchanged, while enabling HTTP/3/QUIC to obtain a direct-buffer-capable allocator.Two minor suggestions:
- Consider renaming the parameter (e.g.,
requireDirectBuffers) and/or adding Javadoc to make it explicit thattruewill bypass the global “no direct buffers” choice, so future callers don’t passtruecasually.- Optionally use the existing
NoDirectBuffers#getDelegate()instead of accessingndb.delegatedirectly, for consistency with the inner-class abstraction.Please also confirm that overriding the “no direct buffers” behavior for HTTP/3 is acceptable in environments that explicitly configured heap-only buffers (or that HTTP/3 will be disabled there).
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
262-267: Consider enhancing the setting documentation.The new
SETTING_HTTP_HTTP3_ENABLEDsetting looks good with a safe default offalse. However, the comment could be more informative about platform requirements and the QUIC protocol dependency.Consider this enhancement to the comment:
- // Enable HTTP/3 protocol if supported by the operating system and architecture + /** + * Enable HTTP/3 (QUIC) protocol support. HTTP/3 requires native QUIC libraries + * which are platform-dependent (check Netty QUIC documentation for supported OS/arch). + * Binds on UDP alongside TCP when enabled. + */ public static final Setting<Boolean> SETTING_HTTP_HTTP3_ENABLED = Setting.boolSetting(modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (1)
119-119: Add minimum value validation forSETTING_H3_MAX_STREAMS.The setting allows any long value including 0 or negative numbers. Since HTTP/3 requires at least some concurrent streams to function, and the RFC recommends 100, consider adding a minimum bound.
- public static final Setting<Long> SETTING_H3_MAX_STREAMS = Setting.longSetting("h3.max_streams", 100L, Property.NodeScope); + public static final Setting<Long> SETTING_H3_MAX_STREAMS = Setting.longSetting("h3.max_streams", 100L, 1L, Property.NodeScope);modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (1)
577-597: Test validates UDP channel close but may not exercise QUIC-level timeout.The test creates a raw UDP channel without performing a QUIC handshake. While it validates that the server closes idle connections, it doesn't test HTTP/3-specific read timeout behavior since no QUIC connection is established.
Consider using
Netty4HttpClient.http3()with a delayed request to test read timeout at the HTTP/3 layer for more comprehensive coverage.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (43)
CHANGELOG.md(1 hunks)gradle/libs.versions.toml(1 hunks)modules/transport-netty4/build.gradle(2 hunks)modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java(2 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java(1 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java(10 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java(1 hunks)plugins/repository-azure/build.gradle(0 hunks)plugins/transport-reactor-netty4/build.gradle(2 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java(2 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java(2 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java(5 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java(3 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java(7 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java(12 hunks)server/src/main/java/org/opensearch/bootstrap/Security.java(1 hunks)server/src/main/java/org/opensearch/http/HttpRequest.java(1 hunks)server/src/main/java/org/opensearch/http/HttpTransportSettings.java(1 hunks)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java(2 hunks)
💤 Files with no reviewable changes (1)
- plugins/repository-azure/build.gradle
✅ Files skipped from review due to trivial changes (2)
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
🚧 Files skipped from review as they are similar to previous changes (15)
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java
- modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java
- modules/transport-netty4/build.gradle
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- CHANGELOG.md
- modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1
🧰 Additional context used
🧬 Code graph analysis (7)
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (3)
test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
KeyStoreUtils(26-83)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java (1)
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
ReactorNetty4HttpServerTransport(93-582)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: gradle-check
- GitHub Check: assemble (25, ubuntu-24.04-arm)
- GitHub Check: assemble (25, ubuntu-latest)
- GitHub Check: assemble (21, ubuntu-24.04-arm)
- GitHub Check: assemble (25, windows-latest)
- GitHub Check: assemble (21, windows-latest)
- GitHub Check: assemble (21, ubuntu-latest)
- GitHub Check: precommit (25, ubuntu-latest)
- GitHub Check: precommit (21, windows-2025, true)
- GitHub Check: precommit (25, ubuntu-24.04-arm)
- GitHub Check: precommit (25, windows-latest)
- GitHub Check: precommit (25, macos-15)
- GitHub Check: precommit (25, macos-15-intel)
- GitHub Check: precommit (21, ubuntu-latest)
- GitHub Check: detect-breaking-change
- GitHub Check: precommit (21, windows-latest)
- GitHub Check: precommit (21, macos-15)
- GitHub Check: precommit (21, ubuntu-24.04-arm)
- GitHub Check: precommit (21, macos-15-intel)
- GitHub Check: Analyze (java)
- GitHub Check: Mend Security Check
🔇 Additional comments (32)
modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1 (1)
1-1: Checksum format looks correctThe file contains a single 40-character hex SHA-1 string with no extra whitespace, matching the expected format for these license checksum entries.
plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1 (1)
1-1: Verify the SHA-1 hash and dependency version against official sources.Ensure this hash matches the official Netty distribution from Maven Central and confirm that version 4.2.7.Final is appropriate and free from known vulnerabilities.
Run the following script to verify the latest version and check for security advisories:
#!/bin/bash # Check Maven Central for the latest version of netty-incubator-codec-native-quic curl -s 'https://search.maven.org/solrsearch/select?q=g:io.netty.incubator+AND+a:netty-incubator-codec-native-quic&rows=1&wt=json' | jq -r '.response.docs[0].latestVersion' # Check for Netty security advisories gh api graphql -f query=' { securityVulnerabilities(first: 10, ecosystem: MAVEN, package: "io.netty.incubator:netty-incubator-codec-native-quic") { nodes { advisory { summary severity publishedAt } vulnerableVersionRange firstPatchedVersion { identifier } } } }'Additionally, verify the SHA-1 hash by downloading the JAR from Maven Central and computing its checksum:
#!/bin/bash # Download the JAR and verify SHA-1 curl -L -o /tmp/netty-codec-native-quic.jar \ 'https://repo1.maven.org/maven2/io/netty/incubator/netty-incubator-codec-native-quic/4.2.7.Final/netty-incubator-codec-native-quic-4.2.7.Final-osx-x86_64.jar' # Compute SHA-1 sha1sum /tmp/netty-codec-native-quic.jar | awk '{print $1}' # Expected: f3679a6cc103292931098b1dc835ffb831e27368test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (2)
50-55: Good backward-compatible overload pattern.The delegation to the new algorithm-parameterized overload with
rsa2048as default maintains existing behavior while enabling flexibility for HTTP/3 testing scenarios.
67-81: Algorithm parameter properly propagated to CertificateBuilder.The implementation correctly passes the
Algorithmparameter to the certificate builder and usesBouncyCastleFipsProviderconsistently. The inline comment documenting required FIPS-approved algorithms (rsa2048, rsa3072, rsa4096, rsa8192, ecp256, ecp384) serves as clear guidance for callers of this method.modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java (1)
36-50: LGTM! Clean type generalization to support multiple transport implementations.The refactoring from
Netty4HttpServerTransporttoAbstractHttpServerTransportenables this handler to work with both the existing Netty4 transport and the new QUIC/HTTP3 transport, which aligns well with the HTTP/3 support objectives.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (4)
176-184: LGTM! HTTP/3 client factory properly configured.The HTTP/3 factory uses
NioDatagramChannel(since QUIC runs over UDP) and enables buffer allocation, which is appropriate for datagram-based transport.
328-336: LGTM! Generic channel initializer supports multiple transport types.The type parameter
<C extends Channel>and theprepare()method enable proper handling of HTTP/3's two-phase channel setup (DatagramChannel → QuicChannel → QuicStreamChannel) while maintaining compatibility with HTTP/1.x and HTTP/2 transports.
483-496: Verify QUIC timeout and buffer sizes align with production requirements.The QUIC client codec uses:
maxIdleTimeout: 5000msinitialMaxData: 10MBinitialMaxStreamDataBidirectionalLocal: 1MBThese values appear suitable for testing, but ensure they align with expected production load and latency requirements.
507-532: LGTM! HTTP/3 request stream pipeline is correctly ordered.The pipeline properly sequences:
Http3FrameToHttpObjectCodec(false)— converts HTTP/3 frames to HttpObjectHttpContentDecompressor— handles compressionHttpObjectAggregator— aggregates chunks- Response handler — processes FullHttpResponse
This addresses the past review concern about HTTP/1.x codecs being incorrectly placed in the HTTP/3 pipeline.
plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java (1)
60-65: LGTM! HTTP/3 settings properly exposed.The plugin correctly exposes HTTP/3 configuration settings (stream local/remote lengths and max streams) alongside the existing HTTP/2 cleartext setting, enabling runtime configuration of QUIC transport parameters.
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java (1)
47-47: LGTM! Test updated for Settings-based client API.Passing
Settings.EMPTYis appropriate for this test since it doesn't require custom HTTP/3 or transport configuration.server/src/main/java/org/opensearch/http/HttpRequest.java (1)
63-64: LGTM! HTTP/3 enum constant added.The
HTTP_3_0addition follows the established pattern and enables HTTP/3 protocol version representation across the transport layer.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
100-100: LGTM! API update correctly propagates settings.The change correctly updates the client creation to pass the per-test
settings(which includes HTTP port configuration) into the newReactorHttpClient.create(Settings)API. This aligns with the HTTP/3 integration work and maintains proper test behavior.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
122-122: LGTM! Streaming test client creation correctly updated.Both client instantiations properly update to
ReactorHttpClient.create(false, Settings.EMPTY), maintaining the compression-disabled behavior while adapting to the new Settings-aware API.Also applies to: 162-162
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (1)
104-104: LGTM! Integration test client creation properly updated.Both test methods correctly update to the new API signature while preserving the compression-disabled configuration appropriate for these request size limit tests.
Also applies to: 134-134
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (4)
92-92: LGTM! ECC P-384 algorithm appropriate for test certificates.The addition of
Algorithm.ecp384for test certificate generation uses elliptic curve cryptography with the P-384 curve, which provides strong security suitable for testing TLS connections.Also applies to: 121-121
166-170: LGTM! Simplified SSLEngine creation is cleaner.The refactored SSL engine creation directly builds the context and engine without the try-catch block. Since the method signature declares
throws SSLException, exceptions will still propagate correctly to callers.
256-256: LGTM! HTTPS client creation correctly updated with settings.All
ReactorHttpClient.https()calls now properly pass thesettingsparameter, ensuring the secure client receives proper configuration including HTTP/3 enablement where applicable.Also applies to: 363-363, 410-410, 471-471, 543-543, 560-560
295-298: LGTM! HTTP/3 test coverage properly integrated.The changes correctly propagate HTTP/3 enablement through test scaffolding:
testBindUnavailableAddresspreserves the HTTP/3 setting from the initial transport when creating the conflicting transporttestLargeCompressedResponserandomizes HTTP/3 to test both modescreateBuilderWithPortadds random HTTP/3 enablement for general test coverageThis ensures HTTP/3 paths are exercised during testing.
Also applies to: 450-452, 646-648
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (4)
110-135: Verify the stream limit fix from previous review.Past review comments indicated that stream limits of 1,000,000 KB were too large and should be 1 MB. The current code shows:
new ByteSizeValue(1000000, ByteSizeUnit.BYTES)This is ~976 KB, which is close to the recommended 1 MB range. However, it would be clearer to use
new ByteSizeValue(1, ByteSizeUnit.MB)as suggested in the previous review to avoid confusion about the unit.Based on previous review feedback, please confirm whether the current values (1,000,000 BYTES ≈ 976 KB) are intentional or if they should be exactly 1 MB as originally suggested.
319-368: Verify maxData setting change from previous review.Previous review indicated that using
SETTING_HTTP_MAX_CHUNK_SIZEfor QUIC'smaxDatawas incorrect (8 KB is too small for connection-level flow control). Line 356 now shows:.maxData(SETTING_HTTP_MAX_CONTENT_LENGTH.get(settings).getBytes())This uses
SETTING_HTTP_MAX_CONTENT_LENGTH(default 100 MB), which is much better than the previous 8 KB. However, this may still not be ideal since:
- Connection-level
maxDataand max content length serve different purposes- The previous review suggested a dedicated QUIC-specific setting
Since the PR is marked [WIP] and this is an improvement over the original, it's reasonable to defer to a dedicated setting in a future iteration.
Please confirm whether using
SETTING_HTTP_MAX_CONTENT_LENGTHformaxDatais the intended final approach, or if a dedicated HTTP/3 setting is planned for a future commit.
48-48: LGTM! Imports correctly added for HTTP/3 support.The new imports for
Channel,QuicSslContextBuilder,Http3, and the static import ofSETTING_HTTP_HTTP3_ENABLEDare all necessary and correctly placed for the HTTP/3 integration.Also applies to: 55-55, 69-69, 75-75
370-370: LGTM! Method rename clarifies purpose.Renaming
configure()toconfigureHttp11orHttp2()makes the method's scope explicit and distinguishes it from the newconfigureHttp3()method.modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (2)
290-346: LGTM!The HTTP/3 pipeline configuration is correctly structured with
Http3FrameToHttpObjectCodecas the first handler to convert HTTP/3 frames to HTTP objects before other handlers process them.
370-439: LGTM!The extension points and compression configuration are well-designed. The ZSTD exclusion is properly documented with clear rationale regarding
NettyAllocator's direct buffer limitations.plugins/transport-reactor-netty4/build.gradle (1)
162-162: LGTM!Adding
SegmentedDatagramPackettoignoreMissingClassesis appropriate as this epoll-specific class is used for UDP GSO (Generic Segmentation Offload) and is only available on Linux with native epoll support.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (4)
109-180: LGTM!The test setup and teardown are well-structured. Using
InsecureTrustManagerFactoryis acceptable for test scenarios, and the cleanup properly shuts down resources.
186-284: LGTM!The Expect header tests are comprehensive, covering 100-continue, content-length limits, and unsupported expectations. Resource management with try-with-resources and explicit
release()in finally blocks is correct.
286-326: LGTM!The duplicate bind test correctly validates that attempting to bind to an already-used address throws
BindHttpExceptionwith an appropriate message.
459-530: LGTM!The CORS test comprehensively validates both pre-flight OPTIONS request handling and origin rejection for non-allowed origins.
server/src/main/java/org/opensearch/bootstrap/Security.java (1)
132-134: Verify the regex pattern handles all platform-specific Netty QUIC/HTTP3 native library JAR names.The updated pattern now captures optional classifiers, which is necessary for platform-specific JARs. However, verify that the hardcoded platform prefixes cover all cases:
Platform prefix coverage: The pattern only recognizes
linux-,windows-, andosx-prefixes. If Netty QUIC native libraries use additional platform identifiers (e.g.,macos-,darwin-, oraarch64-in the classifier), they may not be correctly parsed and could fail to load.Classifier matching limitation: The pattern
[^-]+assumes classifiers don't contain internal dashes (except for the platform prefix). While this works for most cases, it could break with unusual classifier formats.Impact on security policy: When
group(1)is extracted (line 244), the filename is reconstructed and routed to a special codebase handling path. If the pattern fails to match JAR names with unknown platform identifiers, they may not receive the correct security permissions, potentially causing runtime failures.Add unit tests with actual Netty QUIC native library JAR names to verify the pattern correctly matches all expected platform variants. Additionally, document which platform identifiers are supported and why others are excluded.
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
205-205: Settings-awareReactorHttpClientusage is consistent and correctAll updated call sites now use
ReactorHttpClient.create(settings)orReactorHttpClient.create(Settings.EMPTY)and keep the client settings aligned with the server transport configuration. Lifecycle management via try‑with‑resources is intact, and the changes are a straightforward adaptation to the new factory API with no apparent behavioral regressions in these tests.Also applies to: 310-310, 356-356, 412-412, 478-478, 541-541, 558-558
| assertThat( | ||
| new String(response.content().array(), Charset.forName("UTF-8")), | ||
| containsString("you sent a bad request and you should feel bad") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential UnsupportedOperationException if buffer is not array-backed.
Calling response.content().array() assumes the ByteBuf is heap-backed. If the allocator returns a direct buffer, this will throw UnsupportedOperationException.
Consider using ByteBufUtil.getBytes() which handles both heap and direct buffers:
- assertThat(
- new String(response.content().array(), Charset.forName("UTF-8")),
- containsString("you sent a bad request and you should feel bad")
- );
+ assertThat(
+ new String(ByteBufUtil.getBytes(response.content()), StandardCharsets.UTF_8),
+ containsString("you sent a bad request and you should feel bad")
+ );📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| assertThat( | |
| new String(response.content().array(), Charset.forName("UTF-8")), | |
| containsString("you sent a bad request and you should feel bad") | |
| assertThat( | |
| new String(ByteBufUtil.getBytes(response.content()), StandardCharsets.UTF_8), | |
| containsString("you sent a bad request and you should feel bad") | |
| ); |
🤖 Prompt for AI Agents
In
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java
around lines 386 to 388, the test calls response.content().array() which can
throw UnsupportedOperationException for direct ByteBufs; replace that usage by
extracting bytes via ByteBufUtil.getBytes(response.content()) and construct the
String with StandardCharsets.UTF_8 so both heap and direct buffers are handled
safely and charset handling is explicit.
| try ( | ||
| Netty4QuicServerTransport transport = new Netty4QuicServerTransport( | ||
| Settings.EMPTY, | ||
| networkService, | ||
| bigArrays, | ||
| threadPool, | ||
| xContentRegistry(), | ||
| dispatcher, | ||
| clusterSettings, | ||
| new SharedGroupFactory(Settings.EMPTY), | ||
| secureHttpTransportSettingsProvider, | ||
| NoopTracer.INSTANCE | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test uses Settings.EMPTY which may cause port binding issues.
Unlike other tests that use createSettings() to configure a random port range, this test passes Settings.EMPTY which relies on default port binding. This could cause flaky failures in CI environments due to port conflicts.
try (
Netty4QuicServerTransport transport = new Netty4QuicServerTransport(
- Settings.EMPTY,
+ createSettings(),
networkService,
bigArrays,
threadPool,
xContentRegistry(),
dispatcher,
clusterSettings,
- new SharedGroupFactory(Settings.EMPTY),
+ new SharedGroupFactory(createSettings()),
secureHttpTransportSettingsProvider,
NoopTracer.INSTANCE
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| try ( | |
| Netty4QuicServerTransport transport = new Netty4QuicServerTransport( | |
| Settings.EMPTY, | |
| networkService, | |
| bigArrays, | |
| threadPool, | |
| xContentRegistry(), | |
| dispatcher, | |
| clusterSettings, | |
| new SharedGroupFactory(Settings.EMPTY), | |
| secureHttpTransportSettingsProvider, | |
| NoopTracer.INSTANCE | |
| ) | |
| try ( | |
| Netty4QuicServerTransport transport = new Netty4QuicServerTransport( | |
| createSettings(), | |
| networkService, | |
| bigArrays, | |
| threadPool, | |
| xContentRegistry(), | |
| dispatcher, | |
| clusterSettings, | |
| new SharedGroupFactory(createSettings()), | |
| secureHttpTransportSettingsProvider, | |
| NoopTracer.INSTANCE | |
| ) |
🤖 Prompt for AI Agents
In
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java
around lines 426 to 438, the test constructs Netty4QuicServerTransport with
Settings.EMPTY which can cause port binding conflicts in CI; replace
Settings.EMPTY with a test settings instance that uses the same randomized port
range as other tests (e.g. call createSettings() or build Settings with the
ephemeral network port range used elsewhere) so the transport binds to a random
available port; update the constructor invocation to pass that settings object.
...eactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
Show resolved
Hide resolved
|
❌ Gradle check result for 8a90e43: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (9)
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java (1)
161-162: Fix HTTP/3 protocol string to match Reactor Netty's format.Reactor Netty's
HttpServerRequest.protocol()returns"HTTP/3"(without the.0suffix), so the conditionprotocol.equals("HTTP/3.0")will never match HTTP/3 requests. This causes the HTTP/3 branch to be unreachable.- } else if (protocol.equals("HTTP/3.0")) { + } else if (protocol.equals("HTTP/3")) { return HttpRequest.HttpVersion.HTTP_3_0;plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java (2)
39-44: Close listener will be invoked multiple times.The listener is attached to each
closeContext, so it fires once per channel close rather than once when all channels have closed. If callers expect a single callback (e.g., for cleanup), this leads to duplicate operations.Consider using
CompletableFuture.allOf()to aggregate and trigger the listener only once when all channels are closed.
25-32: Add validation for null or empty channels array.The constructor doesn't validate the input array. If
channelsis null, lines 27-30 will throwNullPointerException. If empty,getLocalAddress()at line 36 will throwArrayIndexOutOfBoundsException.@SuppressWarnings({ "unchecked", "rawtypes" }) ReactorNetty4CompositeHttpServerChannel(Channel... channels) { + if (channels == null || channels.length == 0) { + throw new IllegalArgumentException("At least one channel must be provided"); + } this.channels = channels; this.closeContexts = new CompletableContext[channels.length];plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (2)
298-316: HTTP/3 server not cleaned up if HTTP/1.1/2 bind fails.If
http11or2.bindNow()(line 300) throws an exception afterhttp3Serverhas successfully bound (line 299), the HTTP/3 server remains open, causing a resource leak and potentially blocking the port.final DisposableServer http3Server = http3Opt.get(); - final DisposableServer http11or2Server = http11or2.bindNow(); + final DisposableServer http11or2Server; + try { + http11or2Server = http11or2.bindNow(); + } catch (Exception e) { + http3Server.disposeNow(); + throw e; + } disposableServer = new DisposableServer() {
302-313: Returningnullfromchannel()may cause NPE.If any caller (logging, monitoring, or parent class methods) invokes
channel()expecting a valid reference, this will result in aNullPointerException.@Override public Channel channel() { - return null; /* not implemented */ + return http11or2Server.channel(); }plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
308-314: Reconsider the setting used for HTTP/3maxData.The
maxDataparameter represents the connection-level flow-control limit for HTTP/3 (QUICinitial_max_dataper RFC 9000), which is the aggregate maximum bytes permitted across all streams on the connection. UsingSETTING_HTTP_MAX_CHUNK_SIZEhere is semantically incorrect—this setting represents per-chunk size limits, not connection-level aggregates.Consider using
SETTING_HTTP_MAX_CONTENT_LENGTHor introducing a dedicated connection-level setting instead.Based on past review comments, this issue was previously flagged but remains unresolved.
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (1)
357-376:ServerChannelExceptionHandleris still defined but never used.This class was flagged in a previous review as dead code. It's never instantiated or added to any pipeline. Either integrate it into the QUIC server channel pipeline for proper exception handling, or remove it entirely.
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (2)
386-390: PotentialUnsupportedOperationExceptionfor direct buffers.Using
response.content().array()assumes the buffer is heap-backed. UseByteBufUtil.getBytes()for compatibility with both heap and direct buffers, consistent with line 273.assertThat(response.status(), equalTo(HttpResponseStatus.BAD_REQUEST)); assertThat( - new String(response.content().array(), Charset.forName("UTF-8")), + new String(ByteBufUtil.getBytes(response.content()), StandardCharsets.UTF_8), containsString("you sent a bad request and you should feel bad") );
427-439: Test usesSettings.EMPTYwhich may cause port binding issues.This test passes
Settings.EMPTYwhich relies on default port binding. UsecreateSettings()to configure a random port range and avoid flaky failures in CI due to port conflicts.+ final Settings settings = createSettings(); try ( Netty4QuicServerTransport transport = new Netty4QuicServerTransport( - Settings.EMPTY, + settings, networkService, bigArrays, threadPool, xContentRegistry(), dispatcher, clusterSettings, - new SharedGroupFactory(Settings.EMPTY), + new SharedGroupFactory(settings), secureHttpTransportSettingsProvider, NoopTracer.INSTANCE )
🧹 Nitpick comments (7)
modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java (1)
160-166: NewgetAllocator(boolean directBuffers)looks correct; consider minor style/encapsulation tweaksThe behavior—returning the underlying allocator only when
directBuffersis explicitly requested andALLOCATORisNoDirectBuffers—is a clean way to opt into direct buffers for HTTP/3/QUIC while preserving existing behavior for all other callers. No functional issues stand out.A couple of small, optional refinements:
- You can simplify the condition and avoid the explicit comparison:
if (directBuffers && ALLOCATOR instanceof NoDirectBuffers ndb) { return ndb.delegate; // Http3/Quic only supports direct buffers }
- Since
NoDirectBuffersalready exposesgetDelegate(), you might prefer to use that instead of accessing the private field from the outer class, which keeps encapsulation a bit clearer:if (directBuffers && ALLOCATOR instanceof NoDirectBuffers ndb) { return ndb.getDelegate(); }Both are non‑blocking suggestions; the current implementation is fine as is.
test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
54-76: Validatealgorithmand align the contract with the FIPS commentBecause
createServerKeyStore(Algorithm)is public in the test framework, a null or otherwise invalidalgorithmwill currently fail deeper in the stack with a less clear error. A small guard here would make misuse easier to diagnose:- public static KeyStore createServerKeyStore(Algorithm algorithm) throws Exception { - var serverCred = generateCert(algorithm); + public static KeyStore createServerKeyStore(Algorithm algorithm) throws Exception { + Objects.requireNonNull(algorithm, "algorithm must not be null"); + var serverCred = generateCert(algorithm);and add:
import java.util.Objects;You might also consider documenting (or asserting in tests) that only FIPS‑approved algorithms are expected here, to match the comment in
generateCert.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (1)
121-121: Consider making the keystore algorithm configurable or document the choice.The keystore is now initialized with a hardcoded
Algorithm.ecp384. While ECC P-384 is a valid choice for HTTP/3, consider whether this should be randomized or parameterized in tests to ensure broader algorithm coverage, especially since HTTP/3 may support different cipher suites.modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (2)
316-318: Unused methodgetRequestHandler().This method is defined but never called anywhere in the codebase. Consider removing it or documenting its intended use as an extension point.
378-447: Code duplication withNetty4HttpServerTransport.The
createHeaderVerifier(),createDecompressor(), anddefaultCompressionOptions()methods are duplicated fromNetty4HttpServerTransport. Consider extracting these to a shared utility class or abstract base class to reduce maintenance burden.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (1)
298-298: InconsistentSettingsusage inSharedGroupFactory.The transport is created with
initialSettings, butSharedGroupFactoryusesSettings.EMPTY. For consistency, useinitialSettingsfor both.- new SharedGroupFactory(Settings.EMPTY), + new SharedGroupFactory(initialSettings),modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
132-144: GenericAwaitableChannelInitializerwiring looks correct;preparesignature could be simplified later.The change to have
handlerFactoryreturnAwaitableChannelInitializer<?>and to drive everything throughawait()+prepare(...)is consistent and keeps HTTP/1.1 and HTTP/2 behavior intact while enabling HTTP/3’s extra setup.Right now
prepare(Bootstrap clientBootstrap, Channel channel)ignores theclientBootstrapparameter in all implementations. If you don’t foresee a concrete need for it, you could drop that argument to keep the hook minimal and easier to maintain (or at least document its intended future use).Also applies to: 328-336
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (44)
CHANGELOG.md(1 hunks)gradle/libs.versions.toml(1 hunks)modules/transport-netty4/build.gradle(2 hunks)modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java(2 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java(1 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java(10 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java(1 hunks)plugins/repository-azure/build.gradle(0 hunks)plugins/transport-reactor-netty4/build.gradle(2 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java(2 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java(2 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java(5 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java(3 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java(7 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java(12 hunks)server/src/main/java/org/opensearch/bootstrap/Security.java(1 hunks)server/src/main/java/org/opensearch/common/settings/ClusterSettings.java(1 hunks)server/src/main/java/org/opensearch/http/HttpRequest.java(1 hunks)server/src/main/java/org/opensearch/http/HttpTransportSettings.java(1 hunks)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java(2 hunks)
💤 Files with no reviewable changes (1)
- plugins/repository-azure/build.gradle
✅ Files skipped from review due to trivial changes (3)
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
🚧 Files skipped from review as they are similar to previous changes (23)
- plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- server/src/main/java/org/opensearch/http/HttpTransportSettings.java
- server/src/main/java/org/opensearch/http/HttpRequest.java
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java
- modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java
- modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- server/src/main/java/org/opensearch/bootstrap/Security.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- CHANGELOG.md
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java
- modules/transport-netty4/build.gradle
🧰 Additional context used
🧬 Code graph analysis (6)
server/src/main/java/org/opensearch/common/settings/ClusterSettings.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(74-350)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (1)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java (3)
ChannelHandler(543-562)Netty4HttpServerTransport(130-635)HttpChannelHandler(364-541)
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: gradle-check
- GitHub Check: assemble (25, ubuntu-24.04-arm)
- GitHub Check: assemble (25, ubuntu-latest)
- GitHub Check: assemble (25, windows-latest)
- GitHub Check: assemble (21, ubuntu-24.04-arm)
- GitHub Check: assemble (21, windows-latest)
- GitHub Check: assemble (21, ubuntu-latest)
- GitHub Check: detect-breaking-change
- GitHub Check: Analyze (java)
- GitHub Check: precommit (25, macos-15-intel)
- GitHub Check: precommit (25, ubuntu-latest)
- GitHub Check: precommit (25, ubuntu-24.04-arm)
- GitHub Check: precommit (21, windows-2025, true)
- GitHub Check: precommit (21, windows-latest)
- GitHub Check: precommit (25, windows-latest)
- GitHub Check: precommit (21, macos-15)
- GitHub Check: precommit (25, macos-15)
- GitHub Check: precommit (21, ubuntu-24.04-arm)
- GitHub Check: precommit (21, ubuntu-latest)
- GitHub Check: precommit (21, macos-15-intel)
- GitHub Check: Mend Security Check
🔇 Additional comments (26)
test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
50-52: Delegation to the new overload preserves existing behaviorUsing
createServerKeyStore(Algorithm.rsa2048)as the default keeps the previous RSA‑2048 behavior while exposing a more flexible overload; this looks good.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (2)
110-136: HTTP/3 stream settings look reasonable.The settings now use
ByteSizeUnit.BYTESwith 1,000,000 bytes (~1 MB) per stream, which aligns with typical QUIC implementations (1–10 MB range). The max streams default of 100 matches HTTP/3 recommendations.
319-368: HTTP/3 configuration looks well-structured.The method properly:
- Checks both runtime availability (
Http3.isHttp3Available()) and the setting toggle- Reuses the existing
SecureHttpTransportSettingsProviderinfrastructure- Applies appropriate QUIC/HTTP3 settings including flow control limits
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (2)
122-122: LGTM!The test correctly adapts to the new
ReactorHttpClient.create(boolean, Settings)API signature.
162-162: LGTM!Consistent with the API change for
ReactorHttpClient.plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (2)
104-104: LGTM!The test correctly adapts to the new
ReactorHttpClient.create(boolean, Settings)API signature.
134-134: LGTM!Consistent API usage with
Settings.EMPTYfor non-HTTP/3 testing scenarios.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
205-205: LGTM! API alignment looks correct.All test client instantiation calls have been updated to pass the required
Settingsparameter, correctly using either the test-specific settings orSettings.EMPTYas appropriate.Also applies to: 310-310, 356-356, 412-412, 478-478, 541-541, 558-558
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (3)
256-256: LGTM! HTTPS client creation updated correctly.All secure client instantiations properly use
ReactorHttpClient.https(settings), aligning with the new API that requires Settings for protocol selection.Also applies to: 363-363, 410-410, 471-471, 543-543, 560-560
295-298: Good practice: Preserving HTTP/3 setting for consistent test behavior.Copying the
SETTING_HTTP_HTTP3_ENABLEDvalue frominitialSettingsensures both transport instances have the same protocol configuration, which is essential for reproducing the bind conflict correctly.
646-648: Appropriate test randomization for HTTP/3 coverage.Randomly enabling HTTP/3 in the test settings builder ensures tests exercise both HTTP/3-enabled and HTTP/3-disabled code paths, improving coverage.
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (6)
96-113: LGTM! API updated to support Settings-driven protocol selection.The constructor and factory methods correctly propagate Settings through the client initialization, enabling deterministic protocol selection based on configuration rather than per-instance randomization.
284-292: LGTM! HTTP/1.1 SSL context configured correctly.The HTTP/1.1 secure path properly uses
Http11SslContextSpec.forClient()with appropriate trust manager configuration and handshake timeout.
293-300: LGTM! HTTP/2 SSL context configured correctly.The HTTP/2 secure path properly uses
Http2SslContextSpec.forClient()with protocol array[HTTP11, H2]for ALPN negotiation, appropriate trust manager, and handshake timeout.
317-322: LGTM! Non-secure protocol selection is correct.The cleartext path appropriately uses
HTTP11for HTTP/1.1-only mode and[HTTP11, H2C]for HTTP/2 cleartext with HTTP/1.1 fallback.
330-332: LGTM! Protocol check correctly refactored.The
useHttp11only()method now correctly checks the protocol field state rather than a separate boolean flag, maintaining consistency with the Settings-driven protocol selection.
334-348: LGTM! Protocol randomization correctly accounts for HTTP/3 availability and settings.The random protocol selection appropriately:
- Checks both HTTP/3 availability (
Http3.isHttp3Available()) and configuration (SETTING_HTTP_HTTP3_ENABLED)- Provides appropriate protocol arrays for secure (HTTP11/H2/HTTP3) and non-secure (HTTP11/H2C) scenarios
- Uses test randomization for coverage
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (4)
186-285: LGTM!The expect header tests are well-structured with proper use of
createSettings()for random port binding andNetty4HttpClient.http3()for HTTP/3 client testing.
461-531: LGTM!The CORS test properly exercises both pre-flight and forbidden origin scenarios with correct settings configuration.
601-607: LGTM!The helper methods follow established patterns for test port configuration.
577-594: Read timeout test may not properly exercise QUIC server timeout.This test creates a raw UDP socket to the QUIC server without performing a QUIC handshake. Since UDP is connectionless and the QUIC protocol requires a handshake to establish streams, the server-side read timeout may not trigger as expected. Consider establishing a proper QUIC connection first (if
Netty4HttpClient.http3()or similar is available) and then not sending requests, or verify this test intentionally validates server behavior against non-QUIC UDP packets.server/src/main/java/org/opensearch/common/settings/ClusterSettings.java (1)
390-428: HTTP/3 enablement setting correctly wired into cluster settings.Adding
HttpTransportSettings.SETTING_HTTP_HTTP3_ENABLEDtoBUILT_IN_CLUSTER_SETTINGSis consistent with how other HTTP transport settings are exposed and should allow cluster‑level toggling without issues.plugins/transport-reactor-netty4/build.gradle (2)
162-162: Verify consistency ofSegmentedDatagramPacketinignoreMissingClassesconfiguration.Adding
io.netty.channel.epoll.SegmentedDatagramPackettoignoreMissingClassesshould match how other optional, platform-specific Netty epoll/kqueue/uring classes are handled to avoid false positives when native implementations aren't available. Confirm this pattern is consistently applied across similar optional classes in the configuration.
36-46: Verify classifier naming for QUIC native artifacts.Maven Central confirms
io.netty:netty-codec-native-quic:4.2.7.Finalexists with platform-specific classifiers, but the web search results show Maven Central useslinux-aarch64andosx-aarch64(no underscore), whereas the build.gradle snippet showslinux-aarch_64andosx-aarch_64(with underscore). Confirm that Gradle's dependency resolution correctly handles the classifier names as specified in lines 36–46; if the underscore format is incorrect, artifact resolution may fail at runtime.The remaining aspects—API dependencies on
libs.netty.codec.classes.quicandlibs.netty.codec.native.quic, and the audit ignore entry forio.netty.channel.epoll.SegmentedDatagramPacket—could not be verified against the actual codebase due to repository access constraints.gradle/libs.versions.toml (1)
152-153: Netty QUIC version wiring looks correct and consistent.Both
io.netty:netty-codec-native-quic:4.2.7.Finalandio.netty:netty-codec-classes-quic:4.2.7.Finalare published artifacts and are used by other projects at this version, so pointing them atversion.ref = "netty"(4.2.7.Final) is appropriate and keeps the Netty stack aligned.modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1 (1)
1-1: Verify SHA‑1 matches the actualnetty-codec-native-quicJAR.The format looks correct, but please confirm this hash was generated from the exact
netty-codec-native-quic-4.2.7.Final.jarfile you ship, to keep license/audit checks reliable.You can verify with:
JAR="netty-codec-native-quic-4.2.7.Final.jar" EXPECTED="d6a7141d5fab45c8d2f6c646965f2dd53a43b41e" ACTUAL=$(sha1sum "$JAR" | awk '{print $1}') test "$ACTUAL" = "$EXPECTED" && echo "SHA1 OK" || echo "SHA1 MISMATCH"
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java
Show resolved
Hide resolved
|
❌ Gradle check result for 07f5199: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
197-197: Inverted scheme header logic—sets "http" whensecureis true.The ternary condition is backwards. When
secureistrue, the scheme should be"https".- httpRequest.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), secure ? "http" : "https"); + httpRequest.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), secure ? "https" : "http");
♻️ Duplicate comments (12)
CHANGELOG.md (1)
39-40: ** Fix duplicate entry and malformed markdown links in CHANGELOG.**Line 39 duplicates line 35 (identical text and PR number for pull-based ingestion). Additionally, both lines 39–40 have malformed markdown: they end with mismatched brackets
]instead of).Apply this diff:
- Support pull-based ingestion message mappers and raw payload support ([#19765](https://github.com/opensearch-project/OpenSearch/pull/19765)] - Support for HTTP/3 (server side) ([#20017](https://github.com/opensearch-project/OpenSearch/pull/20017)] + Support for HTTP/3 (server side) ([#20017](https://github.com/opensearch-project/OpenSearch/pull/20017))This removes the duplicate ingestion line and corrects the HTTP/3 link syntax.
gradle/libs.versions.toml (1)
152-153: ** Fix netty-codec-classes-quic version mismatch — artifact unavailable at 4.2.7.Final.**The artifact
io.netty:netty-codec-classes-quicis not published at version 4.2.7.Final on Maven Central; the latest available release is 4.2.6.Final. Line 153 must use a concrete version to avoid dependency resolution failure.Apply this diff:
netty-codec-native-quic = { group = "io.netty", name = "netty-codec-native-quic", version.ref = "netty" } - netty-codec-classes-quic = { group = "io.netty", name = "netty-codec-classes-quic", version.ref = "netty" } + netty-codec-classes-quic = { group = "io.netty", name = "netty-codec-classes-quic", version = "4.2.6.Final" }plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java (2)
39-44: Listener invoked multiple times; use composite approach.The same listener is added to every
closeContext, so it will be called once for each channel that closes rather than once when all channels have closed. This violates the expected contract of a composite channel.As noted in the previous review, consider using an aggregate close context that completes only when all channels are closed, or use atomic counters to invoke the listener exactly once.
24-32: Add input validation to prevent runtime exceptions.The constructor does not validate the
channelsparameter. Ifchannelsisnullor empty, subsequent calls togetLocalAddress()(line 36) ortoString()(line 65) will throw exceptions.Apply this diff to add validation:
@SuppressWarnings({ "unchecked", "rawtypes" }) ReactorNetty4CompositeHttpServerChannel(Channel... channels) { + if (channels == null || channels.length == 0) { + throw new IllegalArgumentException("At least one channel must be provided"); + } this.channels = channels;modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
181-189: HTTP/3 still only supports a single request per client instance due to single-stream reuse.The
prepare()method returns oneQuicStreamChannel, butsendRequests()iterates all requests over it. Per RFC 9114, each HTTP/3 request requires its own stream. The past review suggested adding a guard or opening new streams per request.This remains unaddressed—tests passing multiple requests via
http3()would violate the spec.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java (1)
161-162: Fix the HTTP/3 protocol string to match Reactor Netty's format.The protocol check uses
"HTTP/3.0", but Reactor Netty'sHttpServerRequest.protocol()returns"HTTP/3"(without the ".0" suffix). This causes the HTTP/3 branch to never execute.Based on past review findings (web search confirmed), change the string to:
- } else if (protocol.equals("HTTP/3.0")) { + } else if (protocol.equals("HTTP/3")) {plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (2)
302-313: Returningnullfromchannel()may cause NPE.The anonymous
DisposableServerreturnsnullforchannel(). If any downstream code invokeschannel()expecting a valid reference (for logging, monitoring, or internal operations), it will result in aNullPointerException.Consider returning one of the underlying channels or throwing
UnsupportedOperationException:@Override public Channel channel() { - return null; /* not implemented */ + return http11or2Server.channel(); // or throw UnsupportedOperationException }
294-317: Exception handling issue: HTTP/3 server not cleaned up if HTTP/1.1/2 bind fails.If
http11or2.bindNow()(line 300) throws an exception afterhttp3Serverhas successfully bound (line 299), the HTTP/3 server remains bound and is not cleaned up, leading to a resource leak.Wrap the second bind in a try-catch:
final DisposableServer http3Server = http3Opt.get(); -final DisposableServer http11or2Server = http11or2.bindNow(); +final DisposableServer http11or2Server; +try { + http11or2Server = http11or2.bindNow(); +} catch (Exception e) { + http3Server.disposeNow(); + throw e; +}modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (2)
357-376: Remove or integrate unused ServerChannelExceptionHandler.This class is never instantiated or added to any pipeline, making it dead code. If server-channel-level exception handling is needed, integrate it into
configureServerChannelHandler(). Otherwise, remove it to reduce maintenance burden.If integration is intended, consider adding it to the parent channel in
configureServerChannelHandler():// After adding the QUIC server codec: ch.pipeline().addLast("server_exception_handler", new ServerChannelExceptionHandler(Netty4QuicServerTransport.this));
266-288: Security: InsecureQuicTokenHandler remains a production risk.Line 274 still uses
InsecureQuicTokenHandler.INSTANCE, which was flagged in previous reviews. QUIC token validation helps prevent address spoofing and amplification attacks. While acceptable for development, this should be replaced with a proper token handler before production use.Consider implementing a secure token handler or adding a configuration flag:
+ // TODO: Implement secure token handler for production (RFC 9000 §8) + // Current insecure handler acceptable only for development/testing .tokenHandler(InsecureQuicTokenHandler.INSTANCE)Alternatively, introduce a node-scoped boolean setting to control this behavior, defaulting to a secure implementation in production.
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (2)
386-389: Potential UnsupportedOperationException with direct buffers.Line 387 uses
response.content().array()which assumes a heap-backed ByteBuf. If the allocator returns a direct buffer, this throwsUnsupportedOperationException.Apply this fix to handle both heap and direct buffers:
- assertThat( - new String(response.content().array(), Charset.forName("UTF-8")), - containsString("you sent a bad request and you should feel bad") - ); + assertThat( + new String(ByteBufUtil.getBytes(response.content()), StandardCharsets.UTF_8), + containsString("you sent a bad request and you should feel bad") + );
426-438: Potential port binding conflicts in CI environments.Lines 428 and 435 use
Settings.EMPTY, which relies on default port binding and can cause flaky test failures due to port conflicts. Other tests usecreateSettings()to bind to random available ports.Apply this fix to use randomized port ranges:
try ( Netty4QuicServerTransport transport = new Netty4QuicServerTransport( - Settings.EMPTY, + createSettings(), networkService, bigArrays, threadPool, xContentRegistry(), dispatcher, clusterSettings, - new SharedGroupFactory(Settings.EMPTY), + new SharedGroupFactory(createSettings()), secureHttpTransportSettingsProvider, NoopTracer.INSTANCE )
🧹 Nitpick comments (6)
plugins/transport-reactor-netty4/build.gradle (1)
42-46: Fix inconsistent dependency declaration — use library references instead of hardcoded coordinates.Lines 42–46 use hardcoded artifact coordinates for platform-specific native binaries instead of referencing the library catalog. For consistency and maintainability, these should reference the library definition from
libs.versions.toml(similar to lines 38–39) by using a library reference with appropriate classifiers, or define a separate library entry for each platform variant.Additionally, verify that the
io.nettygroupId is correct (previous feedback suggestsio.netty.incubatormay be the correct namespace for QUIC artifacts).One option is to avoid the platform-specific runtimeOnly declarations entirely if Gradle can automatically select the correct classifier based on the build platform. Alternatively, consider using Gradle's built-in platform resolution or a custom configuration that selects the artifact dynamically.
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java (2)
46-54: Consider enhanced for-loop for readability.The logic correctly returns
falseif any channel is closed. You may simplify with an enhanced for-loop:@Override public boolean isOpen() { - for (int i = 0; i < channels.length; ++i) { - if (channels[i].isOpen() == false) { + for (Channel channel : channels) { + if (!channel.isOpen()) { return false; } } return true; }
56-61: Consider enhanced for-loop for readability.The close logic is correct. For consistency and readability, consider using an enhanced for-loop:
@Override public void close() { - for (int i = 0; i < channels.length; ++i) { - channels[i].close(); + for (Channel channel : channels) { + channel.close(); } }modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
523-540: Consider movinglatch.countDown()inside theifblock for consistency.The
latch.countDown()at line 532 executes for allHttpObjectmessages, not justFullHttpResponse. WhileHttpObjectAggregatorshould only emitFullHttpResponse, if any other message type slips through, the latch would decrement without adding a response to the collection—potentially causing the test to complete prematurely with missing responses.For defensive consistency (and to match the expected 1:1 relationship between requests and responses):
ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpObject>() { @Override protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) { if (msg instanceof FullHttpResponse ht) { // We copy the buffer manually to avoid a huge allocation on a pooled allocator. We have // a test that tracks huge allocations, so we want to avoid them in this test code. ByteBuf newContent = Unpooled.copiedBuffer(ht.content()); content.add(ht.replace(newContent)); + latch.countDown(); } - latch.countDown(); }plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
354-360: HTTP/3 settings configuration looks good, but consider a dedicatedmaxDatasetting.The HTTP/3 QUIC settings are properly configured. Using
SETTING_HTTP_MAX_CONTENT_LENGTHformaxDatais semantically reasonable, as both are connection-level limits. However,maxDatais a QUIC flow-control parameter (aggregate byte limit across all streams), whileMAX_CONTENT_LENGTHis an HTTP message size limit. They serve different purposes.Consider introducing a dedicated setting like
SETTING_HTTP3_MAX_CONNECTION_DATAwith a default in the 10–25 MB range (typical for QUIC implementations) to independently tune flow control without coupling it to content length limits.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (1)
577-592: Consider testing HTTP/3 read timeout at the application layer.The test creates a raw UDP datagram channel and waits for closure without performing any HTTP/3/QUIC handshake. This tests UDP-level timeout behavior but may not properly exercise the HTTP/3 application-layer read timeout logic.
For more realistic HTTP/3 testing, consider using
Netty4HttpClient.http3()to establish a proper QUIC connection and then let it idle:try (Netty4HttpClient client = Netty4HttpClient.http3()) { // Connect but don't send any data to trigger read timeout // Monitor for connection closure or timeout exception }Alternatively, if low-level UDP timeout testing is intended, add a comment explaining the rationale.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (44)
CHANGELOG.md(1 hunks)gradle/libs.versions.toml(1 hunks)modules/transport-netty4/build.gradle(2 hunks)modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java(2 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java(1 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java(13 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java(1 hunks)plugins/repository-azure/build.gradle(0 hunks)plugins/transport-reactor-netty4/build.gradle(2 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java(2 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java(2 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java(5 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java(3 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java(7 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java(12 hunks)server/src/main/java/org/opensearch/bootstrap/Security.java(1 hunks)server/src/main/java/org/opensearch/common/settings/ClusterSettings.java(1 hunks)server/src/main/java/org/opensearch/http/HttpRequest.java(1 hunks)server/src/main/java/org/opensearch/http/HttpTransportSettings.java(1 hunks)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java(2 hunks)
💤 Files with no reviewable changes (1)
- plugins/repository-azure/build.gradle
✅ Files skipped from review due to trivial changes (2)
- modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
🚧 Files skipped from review as they are similar to previous changes (24)
- server/src/main/java/org/opensearch/common/settings/ClusterSettings.java
- modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java
- plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- server/src/main/java/org/opensearch/http/HttpRequest.java
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- server/src/main/java/org/opensearch/http/HttpTransportSettings.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- server/src/main/java/org/opensearch/bootstrap/Security.java
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java
- modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
🧰 Additional context used
🧬 Code graph analysis (3)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (3)
libs/core/src/main/java/org/opensearch/core/common/bytes/BytesArray.java (1)
BytesArray(48-151)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
KeyStoreUtils(26-83)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java (1)
SslUtils(26-107)
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(77-353)
plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java (1)
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
ReactorNetty4HttpServerTransport(93-582)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: gradle-check
- GitHub Check: assemble (25, ubuntu-24.04-arm)
- GitHub Check: assemble (25, windows-latest)
- GitHub Check: assemble (25, ubuntu-latest)
- GitHub Check: assemble (21, ubuntu-latest)
- GitHub Check: assemble (21, ubuntu-24.04-arm)
- GitHub Check: assemble (21, macos-15)
- GitHub Check: assemble (21, windows-latest)
- GitHub Check: precommit (25, macos-15)
- GitHub Check: precommit (25, ubuntu-latest)
- GitHub Check: precommit (21, windows-2025, true)
- GitHub Check: precommit (25, windows-latest)
- GitHub Check: precommit (25, macos-15-intel)
- GitHub Check: precommit (21, macos-15-intel)
- GitHub Check: precommit (21, ubuntu-24.04-arm)
- GitHub Check: precommit (21, windows-latest)
- GitHub Check: precommit (21, macos-15)
- GitHub Check: precommit (21, ubuntu-latest)
- GitHub Check: detect-breaking-change
- GitHub Check: Analyze (java)
- GitHub Check: Mend Security Check
🔇 Additional comments (34)
modules/transport-netty4/build.gradle (2)
66-68: Verify Netty QUIC artifact coordinates are correct.The dependencies reference
io.netty:netty-codec-native-quicandio.netty:netty-codec-classes-quic. Previous feedback noted that Netty QUIC artifacts may be published underio.netty.incubatorwith different naming (e.g.,io.netty.incubator:netty-incubator-codec-native-quic). Confirm that theio.nettygroupId coordinates are valid and resolve correctly on Maven Central, or update to use the incubator coordinates if necessary.
80-84: Verify native QUIC artifact classifier resolution.The platform-specific runtimeOnly declarations reference standard platform classifiers. Confirm these match the published artifacts on Maven Central and that the build system correctly selects the appropriate classifier for each target platform during dependency resolution.
plugins/transport-reactor-netty4/build.gradle (2)
38-39: Approve QUIC library API dependencies (subject to artifact coordinate verification).The use of library references from
libs.versions.tomlis correct and maintains consistency with the dependency catalog pattern.Confirm that the artifact coordinates and versions defined in
libs.versions.toml(lines 152–153) resolve correctly on Maven Central.
162-162: Approve addition of missing QUIC-related class to audit configuration.The inclusion of
io.netty.channel.epoll.SegmentedDatagramPacketin the missing classes list is appropriate for QUIC support and aligns with similar additions in the netty4 transport module.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java (2)
34-37: Delegation to first channel's address is reasonable for composite binding.The method returns the local address of the first channel, which is appropriate for a composite server channel where all channels share the same logical bind address (but may differ by protocol, e.g., HTTP/2 vs HTTP/3).
63-66: String representation is clear and useful.The
toStringmethod provides a concise representation of the composite channel, delegating to the first channel's address as expected.test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (4)
50-52: LGTM! Good backward compatibility pattern.The delegation to the new overload with a sensible default (
Algorithm.rsa2048) maintains backward compatibility while enabling algorithm customization.
67-67: LGTM! Signature correctly updated.The signature change properly enables algorithm parameterization for certificate generation.
75-75: LGTM! Algorithm parameter correctly applied.The certificate builder now uses the provided algorithm parameter, enabling the intended customization for different certificate types (e.g., RSA vs. ECC for HTTP/3 support).
54-65: Validate algorithm compliance in FIPS mode.When FIPS mode is enabled (line 56), the provided algorithm must be FIPS-approved. The comment on lines 71-72 explicitly lists approved algorithms (rsa2048, rsa3072, rsa4096, rsa8192, ecp256, ecp384), but there is no runtime validation to ensure the caller respects this constraint. Passing a non-compliant algorithm in FIPS mode could violate security requirements.
Consider adding validation to ensure only FIPS-approved algorithms are used when FIPS mode is enabled.
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (4)
108-114: LGTM!The imports for HTTP/3, QUIC, and H3 settings are appropriate for the new functionality.
234-234: Scheme logic is correct here.Note: This correctly uses
secure ? "https" : "http", which confirms the inverted logic at lines 197 and 210 are bugs.
335-343: Clean abstraction for protocol-specific channel preparation.The
prepare()hook allows HTTP/3 to set up QUIC channels before sending, while HTTP/1.1 and HTTP/2 use the default pass-through behavior.
488-505: LGTM!Using
Settings.EMPTYto obtain default values is appropriate for test code. The QUIC client codec configuration correctly applies the H3 stream settings from the server transport's constants.plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java (1)
60-65: LGTM! HTTP/3 settings properly exposed.The plugin correctly exposes the new H2C and HTTP/3-related settings through
getSettings(), following the standard plugin pattern. The settings are properly scoped and align with the HTTP/3 integration.plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java (1)
17-17: LGTM! Test updated to match new API signature.The test correctly updates the
ReactorHttpClient.create()call to accept aSettingsparameter, usingSettings.EMPTYas a sensible default. This aligns with the broader API changes enabling Settings-driven HTTP/3 configuration.Also applies to: 47-47
plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java (1)
104-104: LGTM! Test correctly updated for new API.Both test methods properly use
ReactorHttpClient.create(false, Settings.EMPTY)to create the HTTP client with compression disabled and default settings. The change is consistent with the new Settings-aware API.Also applies to: 134-134
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
205-205: LGTM! Comprehensive test updates for Settings-aware API.All test methods correctly propagate
SettingsthroughReactorHttpClientconstruction. The tests appropriately use either test-specific settings (fromcreateSettings()) orSettings.EMPTYwhen no custom configuration is needed. This enables proper HTTP/3 testing when enabled via settings.Also applies to: 310-310, 356-356, 412-412, 478-478, 541-541, 558-558
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (4)
92-92: LGTM! ECC P-384 certificate appropriate for HTTP/3 testing.Using
Algorithm.ecp384(ECC P-384) for test certificate generation is a good choice, providing strong security and compatibility with HTTP/3/QUIC requirements.Also applies to: 121-121
166-170: LGTM! SSL engine construction follows correct pattern.The SSL context and engine initialization properly chains
SslContextBuilder.forServer()with the key manager factory and trust manager, then creates the engine with the appropriate allocator. This is the correct approach for secure transport setup in tests.
295-298: LGTM! HTTP/3 settings properly integrated into secure transport tests.The tests correctly propagate HTTP/3 enablement settings:
testBindUnavailableAddressensures consistent HTTP/3 configuration across transport instancestestLargeCompressedResponserandomly enables HTTP/3 for coveragecreateBuilderWithPort()helper randomizes HTTP/3 by default, providing comprehensive test coverageAlso applies to: 450-452, 646-648
256-256: LGTM! Secure client creation properly updated.All secure test scenarios correctly use
ReactorHttpClient.https(settings), ensuring the HTTPS client is configured with the appropriate settings for each test context. This enables proper HTTP/3-over-TLS testing when configured.Also applies to: 363-363, 410-410, 471-471, 543-543, 560-560
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (3)
110-135: LGTM! HTTP/3 stream settings have reasonable defaults.The HTTP/3 settings are properly configured:
- Stream local/remote lengths: 1,000,000 bytes (~1 MB per stream)
- Max concurrent streams: 100
These values align with typical QUIC implementations (1–10 MB per stream) and the HTTP/3 standard's recommendation of at least 100 concurrent bidirectional streams for performance.
370-454: LGTM! Method renamed for clarity.Renaming
configure()toconfigureHttp11orHttp2()improves code clarity by explicitly distinguishing it from the newconfigureHttp3()method. The functionality remains unchanged and correct.
48-48: LGTM! Necessary imports added for HTTP/3 support.The new imports properly support HTTP/3 integration:
Channelfor composite server channel handlingQuicSslContextBuilderfor HTTP/3 SSL configurationHttp3for availability checkingSETTING_HTTP_HTTP3_ENABLEDfor feature gatingAlso applies to: 55-55, 69-69, 75-75
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (6)
17-17: LGTM! Settings-based state properly introduced.Adding the
Settingsfield andprotocolfield enables deterministic, Settings-driven configuration instead of per-instance randomization. This is a good architectural improvement.Also applies to: 80-81
99-116: LGTM! Constructor and factory methods properly refactored.The new API surface correctly requires
Settingsfor all client construction paths:
- Constructor initializes protocol via
randomProtocol(secure, settings)- Factory methods (
create,https) consistently propagateSettings- Clear separation between secure and non-secure variants
337-351: LGTM! Protocol selection logic is well-designed.The
randomProtocol()method properly:
- Gates HTTP/3 on both availability (
Http3.isHttp3Available()) and configuration (SETTING_HTTP_HTTP3_ENABLED)- Selects appropriate protocols for secure (HTTP/1.1, H2, HTTP/3) vs. non-secure (HTTP/1.1, H2C) contexts
- Provides randomized test coverage across protocols
59-59: LGTM! HTTP/3 dependencies properly imported.The necessary imports for HTTP/3 client support are in place:
Http3SslContextSpecfor HTTP/3 SSL configurationHttp3for availability checks- HTTP/3 settings constants for configuration
Also applies to: 63-63, 66-70
279-326: LGTM! HTTP/3 client configuration correctly implemented.The
createClient()method properly handles protocol-specific configuration:✅ HTTP/3 SSL context fixed: Line 308 correctly uses
configure(s -> s.trustManager(...))without calling.build()inside the lambda (past issue resolved).✅
maxDatasetting fixed: Line 313 now usesSETTING_HTTP_MAX_CONTENT_LENGTHinstead of the incorrectSETTING_HTTP_MAX_CHUNK_SIZE(past issue resolved).The protocol branching (HTTP/1.1, H2, HTTP/3) is clean, and each path configures the appropriate SSL context spec and protocol settings.
333-335: LGTM! Method updated to reflect protocol state.The
useHttp11only()method correctly checks whether the current protocol is HTTP/1.1, replacing the old field-based approach with protocol-aware logic.modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (2)
98-120: LGTM: HTTP/3 settings are well-defined.The three HTTP/3-specific settings (max stream local/remote length and max streams) have reasonable defaults aligned with HTTP/3 specifications. The documentation clearly explains their purpose.
337-354: LGTM: HTTP/3 pipeline correctly configured.The pipeline properly places
Http3FrameToHttpObjectCodecfirst to convert HTTP/3 frames before other handlers process them. The subsequent handlers (aggregator, compression, request/response handling) are correctly ordered.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (1)
109-180: LGTM: Test setup properly configured for HTTP/3/QUIC.The setup correctly initializes SSL/TLS infrastructure with an ecp384 certificate (FIPS-approved algorithm) and provides appropriate test fixtures. Teardown properly cleans up all resources.
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java
Outdated
Show resolved
Hide resolved
|
❌ Gradle check result for 36cda04: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java (1)
215-226: Fix HTTP/2/HTTP/3 detection – currentequals("HTTP/2.0")/equals("HTTP/3.0")never match.
request.protocolVersion()is a NettyHttpVersion; itsequalsmethod returns false unless the argument is anotherHttpVersioninstance. Comparing toStringliterals is always false, so HTTP/2 or HTTP/3 requests will incorrectly fall through to the "Unexpected http protocol version" exception.Use
protocolName()andmajorVersion()instead:@Override public HttpVersion protocolVersion() { - if (request.protocolVersion().equals(io.netty.handler.codec.http.HttpVersion.HTTP_1_0)) { + io.netty.handler.codec.http.HttpVersion v = request.protocolVersion(); + if (v.equals(io.netty.handler.codec.http.HttpVersion.HTTP_1_0)) { return HttpRequest.HttpVersion.HTTP_1_0; - } else if (request.protocolVersion().equals(io.netty.handler.codec.http.HttpVersion.HTTP_1_1)) { + } else if (v.equals(io.netty.handler.codec.http.HttpVersion.HTTP_1_1)) { return HttpRequest.HttpVersion.HTTP_1_1; - } else if (request.protocolVersion().equals("HTTP/2.0")) { - return HttpRequest.HttpVersion.HTTP_2_0; - } else if (request.protocolVersion().equals("HTTP/3.0")) { - return HttpRequest.HttpVersion.HTTP_3_0; + } else if ("HTTP".equals(v.protocolName()) && v.majorVersion() == 2) { + return HttpRequest.HttpVersion.HTTP_2_0; + } else if ("HTTP".equals(v.protocolName()) && v.majorVersion() == 3) { + return HttpRequest.HttpVersion.HTTP_3_0; } else { throw new IllegalArgumentException("Unexpected http protocol version: " + request.protocolVersion()); } }plugins/transport-reactor-netty4/build.gradle (1)
32-55: QUIC native dependency coordinates are incorrect and will not resolve.The runtimeOnly declarations use wrong Maven coordinates. The actual Netty QUIC artifacts use
io.netty.incubatoras groupId:// Incorrect (will not resolve): runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:linux-x86_64" // Should be: runtimeOnly "io.netty.incubator:netty-incubator-codec-native-quic:${versions.netty}:linux-x86_64"The same applies to all platform classifiers. Also verify that the api dependencies (
libs.netty.codec.classes.quic,libs.netty.codec.native.quic) in the version catalog point to the correctio.netty.incubatorgroup and artifact names (netty-incubator-codec-classes-quic,netty-incubator-codec-native-quic), as Netty QUIC is maintained as an incubator project separate from core Netty.
♻️ Duplicate comments (9)
modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java (1)
27-27: Previous security concern remains unaddressed: mutable array exposed as public API.The issue flagged in the previous review has not been resolved. Exposing
DEFAULT_SSL_PROTOCOLSas apublic static finalarray still allows any caller to mutate the array elements (e.g.,DEFAULT_SSL_PROTOCOLS[0] = "TLSv1"), which can silently compromise TLS security globally at runtime.With the addition of HTTP/3/QUIC support increasing the surface area of SSL/TLS configuration usage, this security risk becomes more critical. Please apply the previously suggested fix to keep the array private and expose an immutable accessor method instead.
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (2)
191-199: Fix invertedSCHEMEheader whensecureis true (GET andsend()).In both
get(...)andsend(...)you currently set:httpRequest.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), secure ? "http" : "https");while the body‑request path correctly uses:
request.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), secure ? "https" : "http");So when
secure == trueyou end up advertising"http"instead of"https"on GET andsend(...).Align all three call sites to the same correct ternary:
- httpRequest.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), secure ? "http" : "https"); + httpRequest.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), secure ? "https" : "http"); - httpRequest.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), secure ? "http" : "https"); + httpRequest.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), secure ? "https" : "http");Also applies to: 208-211, 221-237
241-270: HTTP/3: avoid sending multiple requests on a singleQuicStreamChannel.
sendRequests(...)calls:final Channel channel = handler.prepare(clientBootstrap, channelFuture.channel()); for (HttpRequest request : requests) { channel.writeAndFlush(request); }For HTTP/3,
CountDownLatchHandlerHttp3.prepare(...)returns a singleQuicStreamChannelcreated viaHttp3.newRequestStream(...). Per RFC 9114, each request/response must use its own bidirectional stream; a client MUST NOT send multiple requests on the same stream. Reusing oneQuicStreamChannelfor multiple entries inrequestsis therefore spec‑invalid if any caller passes more than one request when usinghttp3().If multi‑request support isn’t required for the HTTP/3 test client, the minimal and safe change is to fail fast:
- final Channel channel = handler.prepare(clientBootstrap, channelFuture.channel()); - for (HttpRequest request : requests) { - channel.writeAndFlush(request); - } + final Channel channel = handler.prepare(clientBootstrap, channelFuture.channel()); + + // HTTP/3: one request per QUIC stream; enforce this for the test client. + if (channel instanceof QuicStreamChannel && requests.size() > 1) { + throw new IllegalStateException( + "HTTP/3 test client only supports a single request per QUIC stream; got " + requests.size() + ); + } + + for (HttpRequest request : requests) { + channel.writeAndFlush(request); + }If you want multi‑request support, instead open a new
Http3.newRequestStream(...)(and thus a freshQuicStreamChannel) per request while reusing the sameQuicChannel.Does HTTP/3 (RFC 9114) allow multiple requests to be sent sequentially on a single bidirectional QUIC stream, or must each request/response use its own stream?Also applies to: 507-543
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java (1)
155-165: Make HTTP/2/HTTP/3 protocol checks resilient to Reactor’s actual protocol string.
protocolhere is whateverHttpServerRequest.protocol()returns, and hard‑coding"HTTP/2.0"/"HTTP/3.0"is brittle: if Reactor returns"HTTP/2"or"HTTP/3"(or changes formatting), these branches will never match and HTTP/2 or HTTP/3 requests will fall into theIllegalArgumentException.I’d suggest relaxing the comparison to handle both formats:
- } else if (protocol.equals("HTTP/2.0")) { - return HttpRequest.HttpVersion.HTTP_2_0; - } else if (protocol.equals("HTTP/3.0")) { - return HttpRequest.HttpVersion.HTTP_3_0; + } else if (protocol.startsWith("HTTP/2")) { + return HttpRequest.HttpVersion.HTTP_2_0; + } else if (protocol.startsWith("HTTP/3")) { + return HttpRequest.HttpVersion.HTTP_3_0;and ideally add a small test that logs
request.protocol()for an HTTP/3 request to confirm the exact value Reactor is using.CHANGELOG.md (1)
39-40: Deduplicate ingestion entry and fix malformed link.Line 39 repeats the existing pull‑based ingestion changelog entry from line 35, and its link ends with
]instead of), which breaks markdown.A minimal clean-up:
-- Support pull-based ingestion message mappers and raw payload support ([#19765](https://github.com/opensearch-project/OpenSearch/pull/19765)] -- Support for HTTP/3 (server side) ([#20017](https://github.com/opensearch-project/OpenSearch/pull/20017)) +- Support for HTTP/3 (server side) ([#20017](https://github.com/opensearch-project/OpenSearch/pull/20017))plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
272-317: Clean up HTTP/3 server on HTTP/1.1/2 bind failure and return a non-null channel.In the dual-server case:
final DisposableServer http3Server = http3Opt.get(); final DisposableServer http11or2Server = http11or2.bindNow(); disposableServer = new DisposableServer() { @Override public Channel channel() { return null; } @Override public void disposeNow() { ... } }; return new ReactorNetty4CompositeHttpServerChannel(http11or2Server.channel(), http3Server.channel());there are two issues:
- Resource leak on bind failure – if
http11or2.bindNow()throws afterhttp3Serverhas bound, the HTTP/3 server stays running.channel()returnsnull– any code callingdisposableServer.channel()will NPE.Suggested fix:
final DisposableServer http3Server = http3Opt.get(); final DisposableServer http11or2Server; try { http11or2Server = http11or2.bindNow(); } catch (Exception e) { http3Server.disposeNow(); throw e; } disposableServer = new DisposableServer() { @Override public Channel channel() { // e.g. delegate to primary HTTP/1.1/2 channel return http11or2Server.channel(); } @Override public void disposeNow() { http3Server.disposeNow(); http11or2Server.disposeNow(); } };to ensure both servers are cleaned up on failure and
channel()is safe to call.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java (1)
39-44: Clarify/combine close-listener semantics to avoid multiple invocations.
addCloseListenercurrently registers the same listener on everycloseContexts[i], so it will be invoked once per underlying channel close. For a “composite” server channel, callers are likely to expect a single callback when the whole composite is closed.You can instead aggregate completion over all contexts (e.g., via an
AtomicIntegercounter or a sharedCompletableContext<Void>) and invoke the listener exactly once when all channels complete, propagating the first failure if any.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (2)
328-398: Avoidresponse.content().array(); handle direct buffers safely.In
testBadRequest:assertThat( new String(response.content().array(), Charset.forName("UTF-8")), containsString("you sent a bad request and you should feel bad") );assumes the
ByteBufis heap-backed; if a direct buffer is returned, this will throwUnsupportedOperationException.You’re already using
ByteBufUtil.getBytes(...)elsewhere in this class. Consider:assertThat( new String(ByteBufUtil.getBytes(response.content()), StandardCharsets.UTF_8), containsString("you sent a bad request and you should feel bad") );for compatibility with both heap and direct buffers and consistent charset usage.
426-457: Use randomized test settings instead ofSettings.EMPTYto avoid port conflicts.
testLargeCompressedResponseconstructs the transport with:Netty4QuicServerTransport transport = new Netty4QuicServerTransport( Settings.EMPTY, ..., new SharedGroupFactory(Settings.EMPTY), ... );Unlike other tests that use
createSettings()(which randomizes the HTTP port), relying on defaults here risks binding to fixed ports and causing flaky failures in CI.Recommend switching to:
final Settings settings = createSettings(); try (Netty4QuicServerTransport transport = new Netty4QuicServerTransport( settings, ..., new SharedGroupFactory(settings), ... )) { ... }to keep port selection consistent across tests.
🧹 Nitpick comments (9)
test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (2)
50-65: Overload design keeps behavior while adding flexibility; consider null-safety and docsThe delegation from
createServerKeyStore()tocreateServerKeyStore(Algorithm.rsa2048)is a clean way to preserve existing behavior while enabling algorithm selection in tests.To make this a bit more robust and self-documenting:
- Add an explicit null check on the
algorithmparameter so failures are immediate and clear (rather than a later NPE inside the builder).- Optionally add brief Javadoc on the new overload describing what
Algorithmvalues are expected/valid in this context and that the no‑arg overload usesrsa2048by default.For example:
- public static KeyStore createServerKeyStore(Algorithm algorithm) throws Exception { - var serverCred = generateCert(algorithm); + public static KeyStore createServerKeyStore(Algorithm algorithm) throws Exception { + Objects.requireNonNull(algorithm, "algorithm"); + var serverCred = generateCert(algorithm);(plus the corresponding
import java.util.Objects;).
67-76: Clarify FIPS expectations for caller-supplied algorithms (and optionally enforce in FIPS mode)Now that
generateCerttakes a caller-providedAlgorithm, the comment:// must use FIPS-approved algorithms like rsa2048, rsa3072, rsa4096, rsa8192, ecp256, ecp384is more of a guideline than a guarantee. If
Algorithmcontains non‑FIPS options, a caller could now pass something incompatible withBouncyCastleFipsProvider, especially whenFipsMode.CHECK.isFipsEnabled()returns true.Two suggestions:
- Update the comment to make it clear this requirement applies when running in FIPS mode (and that callers are responsible for choosing a FIPS‑approved algorithm in that case).
- Optionally, in FIPS mode, validate
algorithmagainst the allowed set and fail fast with a descriptive exception instead of relying on provider/builder failures.This would make test failures more targeted and avoid confusion if a non‑approved algorithm is accidentally used in a FIPS run.
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (2)
335-417: NewAwaitableChannelInitializerabstraction for HTTP/1/2 looks correct.The
AwaitableChannelInitializer<C extends Channel>base plus the HTTP/2 override ofawait()neatly separates “handshake/readiness” concerns from the common send logic.CountDownLatchHandlerHttpandCountDownLatchHandlerHttp2wiring both look sound, and the HTTP/2 settings wait inawait()is correctly placed before sending requests.You might optionally add
@OverrideonCountDownLatchHandlerHttp2.await()for clarity, but functionally this block is good as‑is.
476-544: HTTP/3 client pipeline is well‑structured; consider tightening latch semantics.The HTTP/3 handler sets up:
- QUIC client codec with H3‑related settings,
- an HTTP/3 request stream whose pipeline is
Http3FrameToHttpObjectCodec(false)→HttpContentDecompressor→HttpObjectAggregator→SimpleChannelInboundHandler<HttpObject>,and in
channelRead0it copies theFullHttpResponsebody into a new buffer before adding tocontent, matching the allocation behavior of the HTTP/1/2 paths. This wiring looks correct and consistent.Minor robustness nit:
latch.countDown()is called unconditionally, even whenmsgis not aFullHttpResponse. Today the aggregator ensures onlyFullHttpResponsearrives, but to make the code future‑proof you could tie the latch strictly to responses (and failures) only:- protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) { - if (msg instanceof FullHttpResponse ht) { - // copy buffer... - ByteBuf newContent = Unpooled.copiedBuffer(ht.content()); - content.add(ht.replace(newContent)); - } - latch.countDown(); - } + protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) { + if (msg instanceof FullHttpResponse ht) { + ByteBuf newContent = Unpooled.copiedBuffer(ht.content()); + content.add(ht.replace(newContent)); + latch.countDown(); + } + }(and keep the
latch.countDown()inexceptionCaughtas you already do).plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (2)
110-136: Consider centralizing HTTP/3 flow-control settings instead of duplicating them here.
SETTING_H3_MAX_STREAM_LOCAL_LENGTH,SETTING_H3_MAX_STREAM_REMOTE_LENGTH, andSETTING_H3_MAX_STREAMSare also defined inNetty4QuicServerTransportwith identical keys and defaults. Duplicating these settings in two classes increases the risk of drift later.Consider moving the H3 settings into a shared location (e.g.,
HttpTransportSettingsor a dedicated helper) and referencing them from both transports.
319-363: Align HTTP/3 timeout and flow-control tuning with existing HTTP settings.The HTTP/3 configuration hard-codes:
.http3Settings(spec -> spec.idleTimeout(Duration.ofSeconds(5)) .maxData(SETTING_HTTP_MAX_CONTENT_LENGTH.get(settings).getBytes()) .maxStreamDataBidirectionalLocal(SETTING_H3_MAX_STREAM_LOCAL_LENGTH.get(settings).getBytes()) .maxStreamDataBidirectionalRemote(SETTING_H3_MAX_STREAM_REMOTE_LENGTH.get(settings).getBytes()) .maxStreamsBidirectional(SETTING_H3_MAX_STREAMS.get(settings).longValue()) )Two observations:
- Using
SETTING_HTTP_MAX_CONTENT_LENGTHas the connection-levelmaxDatais serviceable but conflates message size with transport flow-control; some deployments might want different connection budgets than per-request max content length.- The idle timeout is hard-coded to 5 seconds instead of reusing or deriving from
SETTING_HTTP_READ_TIMEOUT.Not blocking, but consider:
- Introducing an HTTP/3-specific connection
maxDatasetting (or at least documenting its coupling to max content length), and- Tying
idleTimeoutto existing timeout settings (or exposing it via a dedicated setting) for consistent tuning.modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (2)
95-121: Avoid duplicating HTTP/3 flow-control settings across transports.The H3 settings:
public static final Setting<ByteSizeValue> SETTING_H3_MAX_STREAM_LOCAL_LENGTH = ... public static final Setting<ByteSizeValue> SETTING_H3_MAX_STREAM_REMOTE_LENGTH = ... public static final Setting<Long> SETTING_H3_MAX_STREAMS = ...are defined here with the same keys and defaults as in
ReactorNetty4HttpServerTransport. Keeping two independent definitions increases the chance of divergence over time.Consider extracting these into a shared settings holder (e.g.,
HttpTransportSettingsor a dedicatedHttp3TransportSettings) and reusing them from both transports.
357-376:ServerChannelExceptionHandleris never used; either wire it or remove it.
ServerChannelExceptionHandleris defined but not added to any pipeline, so it’s currently dead code. If you intend to surface server-channel exceptions throughonServerException, you probably want to attach it inconfigureServerChannelHandler():ch.pipeline() .addLast("quic_server_codec", Http3.newQuicServerCodecBuilder()....build()) .addLast("server_exception_handler", new ServerChannelExceptionHandler(Netty4QuicServerTransport.this));Otherwise, consider removing this class to reduce noise.
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (1)
532-597: Read-timeout test uses raw UDP; consider exercising actual HTTP/3 traffic.
testReadTimeoutnow usesNioDatagramChannelwith a bare pipeline to connect to the QUIC server and waits for the client channel to close. This validates “something” causes the UDP channel to close, but it doesn’t clearly exercise the HTTP/3 stream-levelReadTimeoutHandlerthat’s onQuicStreamChannel.Not a blocker, but for stronger coverage you might consider:
- Using
Netty4HttpClient.http3()to open an HTTP/3 request that deliberately stalls, then asserting the connection/stream is closed due to read timeout, or- At least adding a brief comment explaining the intent of this raw UDP approach.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (44)
CHANGELOG.md(1 hunks)gradle/libs.versions.toml(1 hunks)modules/transport-netty4/build.gradle(2 hunks)modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java(2 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java(1 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java(13 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java(1 hunks)plugins/repository-azure/build.gradle(0 hunks)plugins/transport-reactor-netty4/build.gradle(2 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java(2 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java(2 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java(5 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java(3 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java(7 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java(12 hunks)server/src/main/java/org/opensearch/bootstrap/Security.java(1 hunks)server/src/main/java/org/opensearch/common/settings/ClusterSettings.java(1 hunks)server/src/main/java/org/opensearch/http/HttpRequest.java(1 hunks)server/src/main/java/org/opensearch/http/HttpTransportSettings.java(1 hunks)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java(2 hunks)
💤 Files with no reviewable changes (1)
- plugins/repository-azure/build.gradle
✅ Files skipped from review due to trivial changes (3)
- modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
🚧 Files skipped from review as they are similar to previous changes (19)
- modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java
- server/src/main/java/org/opensearch/http/HttpRequest.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- server/src/main/java/org/opensearch/http/HttpTransportSettings.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
🧰 Additional context used
🧬 Code graph analysis (9)
server/src/main/java/org/opensearch/common/settings/ClusterSettings.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (8)
libs/core/src/main/java/org/opensearch/core/common/bytes/BytesArray.java (1)
BytesArray(48-151)server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)server/src/main/java/org/opensearch/rest/BytesRestResponse.java (1)
BytesRestResponse(59-219)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java (1)
KeyStoreUtils(26-83)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java (1)
NettyAllocator(51-350)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java (1)
SslUtils(26-107)server/src/main/java/org/opensearch/bootstrap/Bootstrap.java (1)
Bootstrap(89-495)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
Netty4HttpClient(119-545)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(77-353)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(77-353)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (6)
libs/core/src/main/java/org/opensearch/ExceptionsHelper.java (1)
ExceptionsHelper(76-476)server/src/main/java/org/opensearch/http/AbstractHttpServerTransport.java (1)
AbstractHttpServerTransport(93-507)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java (1)
NettyAllocator(51-350)server/src/main/java/org/opensearch/bootstrap/Bootstrap.java (1)
Bootstrap(89-495)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java (1)
Netty4HttpServerTransport(130-635)server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (3)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (2)
ChannelHandler(357-376)Netty4QuicServerTransport(92-449)server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java (1)
NettyAllocator(51-350)
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(77-353)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: gradle-check
- GitHub Check: precommit (25, macos-15)
- GitHub Check: assemble (25, ubuntu-24.04-arm)
- GitHub Check: precommit (21, ubuntu-24.04-arm)
- GitHub Check: assemble (25, windows-latest)
- GitHub Check: assemble (25, ubuntu-latest)
- GitHub Check: assemble (21, windows-latest)
- GitHub Check: precommit (25, macos-15-intel)
- GitHub Check: precommit (25, ubuntu-24.04-arm)
- GitHub Check: assemble (21, ubuntu-latest)
- GitHub Check: precommit (21, windows-2025, true)
- GitHub Check: assemble (21, ubuntu-24.04-arm)
- GitHub Check: precommit (21, macos-15)
- GitHub Check: precommit (25, ubuntu-latest)
- GitHub Check: precommit (25, windows-latest)
- GitHub Check: precommit (21, macos-15-intel)
- GitHub Check: precommit (21, windows-latest)
- GitHub Check: precommit (21, ubuntu-latest)
- GitHub Check: Mend Security Check
- GitHub Check: Analyze (java)
- GitHub Check: detect-breaking-change
🔇 Additional comments (21)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java (1)
200-200: LGTM! Documentation typo fixed.The Javadoc parameter name is now correctly spelled.
plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1 (1)
1-1: Verify checksum matches the committed JAR and is consistent with peer files.Ensure the recorded SHA-1 hash is computed correctly against the corresponding
netty-codec-native-quic-4.2.7.Final-osx-x86_64.jarand verify formatting is consistent with othernetty-codec-native-quic-4.2.7.*.jar.sha1files in the same directory.server/src/main/java/org/opensearch/bootstrap/Security.java (1)
132-134: Verify the regex pattern correctly matches all classifier variants and add unit tests.The updated regex pattern is complex with non-greedy matching (
.*?) and multiple optional groups that create potential for ambiguous or incorrect capture group assignments. For example, withlucene-core-9.11.0-snapshot-8a555eb.jar, it is unclear whether group 2 (classifier) captures the final segment, multiple segments, or requires specific boundaries.Since this affects security policy grants for HTTP/3 dependencies with platform-specific classifiers, incorrect matching could result in missing permissions or runtime failures. Verify the regex against all example JAR names in the comments and add unit tests to ensure correct behavior for edge cases (multiple dashes, absent classifiers, various platform prefixes).
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (2)
35-112: Imports and HTTP/3/QUIC settings wiring look consistent.The additional imports (Settings, Datagram/QUIC/HTTP3 classes, and static H3 settings) are coherent with the new HTTP/3 client logic and are used appropriately below; no issues from this block.
137-189: Verify allocator settings for HTTP/3 client bootstrap.The http3() factory differs from http(), http2(), and https() by calling
NettyAllocator.getAllocator(true)instead ofNettyAllocator.getAllocator(). Confirm whether this boolean flag relates to direct buffer allocation and whether the resulting configuration is appropriate for Netty QUIC expectations. If direct buffers should be enabled for HTTP/3, consider aligning with the default allocator used in the other factory methods.gradle/libs.versions.toml (1)
152-153: Netty QUIC dependencies look consistent with published artifacts.Both
io.netty:netty-codec-native-quicandio.netty:netty-codec-classes-quicare now available at4.2.7.Finalon Maven Central, so usingversion.ref = "netty"here is valid and keeps them aligned with the rest of the Netty stack. (mvnrepository.com)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
83-101: Client creation update tocreate(settings)looks correct.Passing the same
Settingsused to configure the server intoReactorHttpClient.create(settings)keeps this bad‑request test aligned with the new client API and future protocol selection logic, without changing test semantics.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
106-140: Streaming tests correctly updated to the newReactorHttpClient.create(boolean, Settings)API.Using
ReactorHttpClient.create(false, Settings.EMPTY)in both streaming tests preserves the existing behavior (no compression, HTTP/1.1) while wiring in the requiredSettingsparameter; the extra blank line at the end is harmless.Also applies to: 150-180, 243-244
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
191-225: Settings-awareReactorHttpClient.create(...)usage is consistent across tests.Each test now instantiates
ReactorHttpClientwith the sameSettingsused to configure itsReactorNetty4HttpServerTransport(orSettings.EMPTYwhen appropriate), which aligns client behavior with server configuration and the new factory signature without changing the underlying test logic.Also applies to: 294-322, 341-367, 396-427, 467-498, 520-556
server/src/main/java/org/opensearch/common/settings/ClusterSettings.java (1)
390-428: HTTP/3 enablement setting correctly added to built-in cluster settings.Including
HttpTransportSettings.SETTING_HTTP_HTTP3_ENABLEDinBUILT_IN_CLUSTER_SETTINGSalongside the other HTTP transport settings makes the newhttp.protocol.http3.enabledflag visible to cluster settings infrastructure and consistent with how other HTTP options are exposed.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (3)
78-116: Settings-driven protocol selection for tests looks reasonable.Using a
Settingsargument and therandomProtocol(secure, settings)helper to select among HTTP/1.1, H2, and HTTP/3 (when enabled and available) gives good coverage without complicating call sites. The newcreate(Settings)/https(Settings)factories are straightforward.No changes needed here.
333-351:useHttp11only()andrandomProtocolbehavior are consistent.
useHttp11only()now simply checksprotocol == HttpProtocol.HTTP11, andrandomProtocollimits HTTP/3 selection tosecure == trueplusSETTING_HTTP_HTTP3_ENABLEDand runtime availability, falling back to HTTP/1.1/H2 otherwise. For insecure clients, only HTTP/1.1/H2C are considered.This matches expectations and gives tests a clear way to detect the chosen protocol.
279-325: HTTP/3 client SSL context configuration aligns with Reactor Netty APIs.The secure HTTP/3 branch correctly uses
Http3SslContextSpec.forClient().configure(...)followed by.sslContext()to obtain the SSL context, matching the recommended Reactor Netty pattern. The configuration properly applies HTTP/3/QUIC-specific defaults before the customize callback runs.Note: The HTTP/3 branch omits the explicit
clientAuth(ClientAuth.NONE)configuration present in the HTTP/1.1 and H2 branches. While this is acceptable (client SSL contexts do not require explicit client auth settings), the inconsistency across protocol branches may warrant a comment explaining the intentional difference.modules/transport-netty4/build.gradle (2)
141-222: Audit ignore list additions for QUIC-related classes look appropriate.Adding:
'io.netty.pkitesting.X509Bundle', 'io.netty.channel.epoll.SegmentedDatagramPacket',to
ignoreMissingClassesmatches the new Netty QUIC/PKI helper classes and epoll datagram support; it prevents false positives when those classes are absent on some platforms.No changes needed here.
58-85: Validate QUIC/HTTP3 dependency coordinates and consider centralizing runtime native classifiers.Verify that:
versions.nettycorresponds to a Netty release that publishesnetty-codec-http3,netty-codec-classes-quic, and platform-specificnetty-codec-native-quicclassifiers (linux-x86_64, linux-aarch_64, osx-x86_64, osx-aarch_64, windows-x86_64)- Gradle successfully resolves these artifacts on all supported platforms
Consider defining the
netty-codec-native-quicruntime natives through the version catalog (e.g.,libs.netty.codec.native.quic) to centralize coordinates and reduce duplication across modules.modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (4)
148-189: Constructor wiring and logging are consistent with existing Netty HTTP transports.The constructor sets up:
- processors (
Netty4Utils.setAvailableProcessors),- allocator logging (
NettyAllocator.logAllocatorDescriptionIfNeeded),- HTTP handling settings (
maxChunkSize,maxHeaderSize,maxInitialLineLength),- composite buffer components, read timeout, and receive predictor.
The debug log mirrors the existing Netty HTTP transport and should be useful for diagnosing misconfiguration.
Looks good.
195-219: Server startup path matches existing transport lifecycle.
doStart()initializes the shared group, Bootstrap withNioDatagramChannel, allocator, receive buffer allocator, and handler, then callsbindServer()with proper failure cleanup.Assuming
SharedGroupFactory#getHttpGroup()is QUIC-compatible, this is consistent with other transports’ lifecycle and doesn’t introduce obvious leaks.
298-355: HTTP/3 stream pipeline configuration looks correct and HTTP/1.x-free.
HttpChannelHandler.configurePipeline:ch.pipeline().addLast(new Http3FrameToHttpObjectCodec(true)); ch.pipeline().addLast("header_verifier", transport.createHeaderVerifier()); ch.pipeline().addLast("decoder_compress", transport.createDecompressor()); HttpObjectAggregator aggregator = new HttpObjectAggregator(handlingSettings.getMaxContentLength()); aggregator.setMaxCumulationBufferComponents(transport.maxCompositeBufferComponents); ch.pipeline().addLast("aggregator", aggregator); ... ch.pipeline().addLast("request_creator", requestCreator); ch.pipeline().addLast("response_creator", responseCreator); ch.pipeline().addLast("handler", requestHandler);avoids HTTP/1.x codecs and places
Http3FrameToHttpObjectCodecat the front, which matches the expected HTTP/3 pipeline. The aggregator and compression handlers mirror the existing Netty HTTP transport behavior.Looks good.
381-393: Header verifier and decompressor extension points match existing HTTP transport.
createHeaderVerifier()andcreateDecompressor()provide the same extension hooks as the existing Netty HTTP server transport, allowing plugins to inject custom logic.No issues here.
plugins/transport-reactor-netty4/build.gradle (1)
91-183: New audit ignore forSegmentedDatagramPacketis aligned with QUIC UDP usage.Adding
io.netty.channel.epoll.SegmentedDatagramPackettoignoreMissingClassesis appropriate given the new UDP/QUIC support and platform-specific presence of epoll classes.No issues here.
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (1)
182-284: HTTP/3 “Expect: 100-continue” tests look solid and consistent.The
testExpectContinueHeader*tests andrunExpectHeaderTest(...)helper correctly:
- Configure the transport with appropriate
http.max_content_lengthvalues,- Use HTTP/3 client (
Netty4HttpClient.http3()) against the QUIC server,- Assert status codes for
100-continue,413, and417, and- Verify follow-up request behavior for the successful
100-continuecase.This is a good coverage of edge cases around
Expecthandling on the HTTP/3 path.
| public ChannelHandler configureServerChannelHandler() { | ||
| return new ChannelInitializer<Channel>() { | ||
| @Override | ||
| protected void initChannel(Channel ch) throws Exception { | ||
| final Optional<SecureHttpTransportParameters> parameters = secureHttpTransportSettingsProvider.parameters(settings); | ||
|
|
||
| final KeyManagerFactory keyManagerFactory = parameters.flatMap(SecureHttpTransportParameters::keyManagerFactory) | ||
| .orElseThrow(() -> new OpenSearchException("The KeyManagerFactory instance is not provided")); | ||
|
|
||
| final QuicSslContextBuilder sslContextBuilder = QuicSslContextBuilder.forServer(keyManagerFactory, null); | ||
|
|
||
| parameters.flatMap(SecureHttpTransportParameters::trustManagerFactory).ifPresent(sslContextBuilder::trustManager); | ||
| parameters.flatMap(SecureHttpTransportParameters::clientAuth) | ||
| .ifPresent(clientAuth -> sslContextBuilder.clientAuth(ClientAuth.valueOf(clientAuth))); | ||
|
|
||
| final QuicSslContext sslContext = sslContextBuilder.applicationProtocols( | ||
| io.netty.handler.codec.http3.Http3.supportedApplicationProtocols() | ||
| ).build(); | ||
|
|
||
| ch.pipeline() | ||
| .addLast( | ||
| Http3.newQuicServerCodecBuilder() | ||
| .sslContext(sslContext) | ||
| .initialMaxData(SETTING_HTTP_MAX_CONTENT_LENGTH.get(settings).getBytes()) | ||
| .initialMaxStreamDataBidirectionalLocal(SETTING_H3_MAX_STREAM_LOCAL_LENGTH.get(settings).getBytes()) | ||
| .initialMaxStreamDataBidirectionalRemote(SETTING_H3_MAX_STREAM_REMOTE_LENGTH.get(settings).getBytes()) | ||
| .initialMaxStreamsBidirectional(SETTING_H3_MAX_STREAMS.get(settings).longValue()) | ||
| .tokenHandler(InsecureQuicTokenHandler.INSTANCE) | ||
| .handler(new ChannelInitializer<QuicChannel>() { | ||
| @Override | ||
| protected void initChannel(QuicChannel ch) { | ||
| // Called for each connection | ||
| ch.pipeline() | ||
| .addLast( | ||
| new Http3ServerConnectionHandler( | ||
| new HttpChannelHandler(Netty4QuicServerTransport.this, handlingSettings) | ||
| ) | ||
| ); | ||
| } | ||
| }) | ||
| .build() | ||
| ); | ||
| } | ||
| }; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Netty InsecureQuicTokenHandler QUIC token validation security
💡 Result:
Short answer: InsecureQuicTokenHandler in Netty performs token generation/validation without cryptographic integrity or secrecy and is explicitly documented as "shouldn't be used in production." That makes it unsafe for QUIC address-validation tokens (tokens can be guessed/forged/replayed), which can enable address‑spoofing, replay/amplification or linkage attacks and violates RFC 9000's requirement that address‑validation tokens be integrity‑protected. Use a crypto-backed QuicTokenHandler (AEAD/HMAC with server-only keys, include client IP and expiry, key rotation) or disable token-based validation. Sources: Netty docs and the QUIC RFC. (netty.io)
Citations:
- 1: https://netty.io/4.2/api/io/netty/handler/codec/quic/InsecureQuicTokenHandler.html?utm_source=openai
🌐 Web query:
Netty HTTP/3 QUIC server token handler best practices production
💡 Result:
Short checklist of production best practices for a Netty HTTP/3 (QUIC) server token handler:
-
Use authenticated, integrity-protected tokens (AEAD) that encode only what’s needed for address validation (client address, issue timestamp, token type). RFC recommends integrity protection and distinguishable token types. [2]
-
Treat Retry vs NEW_TOKEN differently: accept Retry tokens only briefly and validate strictly; NEW_TOKEN may live longer but avoid unlimited reuse. Prefer single‑use when practical. [2]
-
Keep tokens stateless on server side (encrypt/signed payload) so you can scale/rotate without stored state; include timestamp/nonce to limit replay. RFC and stateless designs advise this. [2]
-
Rotate and protect token keys: use key rotation, maintain short TTL for keys, and securely store keys (HSM/KMS) to limit exposure if leaked.
-
Bind token contents to transport address (and optionally connection-id) to prove client ownership; include version/party tag to prevent cross-purpose reuse. RFC recommends enabling server to verify client transport address and distinguish token purpose. [2]
-
Enforce short acceptance windows for tokens used for address validation (Retry) to avoid DDoS amplification/replay; rate-limit token validation work and fallback to sending Retry when uncertain. [2]
-
Graceful handling of unreadable/unknown-format tokens: treat as “no token” (don’t abort) and proceed with address validation/fallback per RFC to avoid false drops. [2]
-
Implement metrics, logging and alarms around token validation failures, token replay rates, and Retry issuance to detect attacks or misconfiguration.
-
Use Netty’s QuicTokenHandler API (set via QuicServerCodecBuilder.tokenHandler) and follow examples; pay attention to max connection-id length and endianness fixes in recent releases. Test with the incubator codec releases. [1][3]
-
Test at scale (connection spikes, migration, loss) and validate interoperability with clients; ensure NEW_TOKEN issuance for 0-RTT use-cases is consistent with privacy/linkability guidance in RFC. [2]
References:
- Netty QuicServer/QuicTokenHandler API (QuicServerCodecBuilder). [1]
- RFC 9000 (QUIC) — token semantics, Retry vs NEW_TOKEN, stateless tokens, address validation guidance. [2]
- Netty incubator QUIC release notes (QuicTokenHandler fixes/changes). [3]
If you want, I can: (a) sketch a sample QuicTokenHandler implementation (AEAD + timestamp + nonce) compatible with Netty, or (b) review your existing handler code. Which would you prefer?
🏁 Script executed:
# Search for InsecureQuicTokenHandler usage in the codebase
rg "InsecureQuicTokenHandler" --type java -B 3 -A 3
# Also search for any token handler related settings or configurations
rg "token.*handler|TokenHandler" --type java -i | head -50
# Look for TODO or FIXME comments related to QUIC or token handling
rg "TODO|FIXME" --type java | grep -i "quic\|token\|security" | head -20
# Check if there are any settings related to insecure handlers or QUIC security
rg "insecure|h3|QUIC" --type java | grep -i "setting\|config" | head -30Repository: opensearch-project/OpenSearch
Length of output: 202
🏁 Script executed:
# Find all QUIC-related files in the transport-netty4 module
fd -e java . modules/transport-netty4 | xargs grep -l "Quic\|QUIC\|H3\|h3" 2>/dev/null
# Check the settings definitions for QUIC/H3 related configurations
fd -e java . modules/transport-netty4 | xargs grep -l "SETTING.*H3\|SETTING.*QUIC" 2>/dev/nullRepository: opensearch-project/OpenSearch
Length of output: 202
QUIC server codec configuration uses insecure token handler; replace with cryptographically-backed implementation for production.
The QUIC setup uses InsecureQuicTokenHandler.INSTANCE, which is explicitly documented by Netty as unsuitable for production. This handler performs token generation and validation without cryptographic integrity or secrecy, enabling address-spoofing, replay/amplification attacks, and token forgery. RFC 9000 explicitly requires address-validation tokens to be integrity-protected—a requirement that InsecureQuicTokenHandler violates.
For production deployment, replace with a cryptographically-backed QuicTokenHandler implementation that:
- Uses AEAD or HMAC for token integrity and confidentiality
- Encodes client transport address, timestamp, and nonce to prevent replay
- Implements stateless token design (signed/encrypted payload) with key rotation and short TTL
- Binds tokens to transport address and connection context
- Enforces short acceptance windows for address validation to mitigate DDoS amplification
At minimum, add a feature flag (e.g., h3.require_secure_token_handler) that defaults to enforcing secure tokens and prevents accidental production use of InsecureQuicTokenHandler, with clear documentation linking to RFC 9000 token validation requirements.
🤖 Prompt for AI Agents
In
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java
around lines 247 to 291, the QUIC server codec currently uses
InsecureQuicTokenHandler.INSTANCE which is unsuitable for production; replace it
with a cryptographically-backed QuicTokenHandler implementation (or factory)
that signs/encrypts token payloads (client address, timestamp, nonce), verifies
address binding, enforces short TTL and replay protection, and supports key
rotation; add a boolean setting (e.g., h3.require_secure_token_handler)
defaulting to true that prevents use of the insecure handler unless explicitly
disabled for tests, wire the setting into codec construction to select the
secure handler and document the requirement per RFC 9000.
...rc/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java
Show resolved
Hide resolved
|
❌ Gradle check result for 0593761: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (9)
CHANGELOG.md (1)
35-35: Remove duplicate entry and fix malformed link.Line 39 duplicates the pull-based ingestion entry from line 35 with a malformed markdown link (ends with
)]instead of)). Line 40 (HTTP/3) is the intended new entry.Apply this diff to remove the duplicate and correct the link syntax:
- Support pull-based ingestion message mappers and raw payload support ([#19765](https://github.com/opensearch-project/OpenSearch/pull/19765)) - Add search API tracker ([#18601](https://github.com/opensearch-project/OpenSearch/pull/18601)) - Support dynamic consumer configuration update in pull-based ingestion ([#19963](https://github.com/opensearch-project/OpenSearch/pull/19963)) - Cache the `StoredFieldsReader` for scroll query optimization ([#20112](https://github.com/opensearch-project/OpenSearch/pull/20112)) - - Support pull-based ingestion message mappers and raw payload support ([#19765](https://github.com/opensearch-project/OpenSearch/pull/19765)] - Support for HTTP/3 (server side) ([#20017](https://github.com/opensearch-project/OpenSearch/pull/20017))Also applies to: 39-40
modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java (1)
27-27: Security issue: Mutable array exposed as public API (previously flagged).This concern was already raised in a previous review and remains unresolved. Exposing
DEFAULT_SSL_PROTOCOLSas a public mutable array allows any caller to modify the TLS protocol list at runtime (e.g.,DEFAULT_SSL_PROTOCOLS[0] = "TLSv1"), creating a security vulnerability and breaking encapsulation.The previous review provided a correct solution: keep the array private and expose protocols via a defensive-copy accessor method. Please implement that recommendation before merging this PR.
plugins/transport-reactor-netty4/build.gradle (1)
42-46: [DUPLICATE] Fix unresolved critical artifact coordinate mismatch — dependency resolution will fail.This issue was flagged in the previous review but remains unresolved. The correct artifact coordinates are
io.netty.incubator:netty-incubator-codec-native-quic, notio.netty:netty-codec-native-quic. Using the wrong groupId and artifactId will cause dependency resolution to fail. Additionally, the version should reference a QUIC release (e.g., 0.0.72.Final), not${versions.netty}.Apply this diff to use the correct coordinates and align with the lib references at lines 38–39:
- // Bundle all supported OSes and Archs - runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:linux-x86_64" - runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:linux-aarch_64" - runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:osx-x86_64" - runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:osx-aarch_64" - runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:windows-x86_64" + // Bundle all supported OSes and Archs + runtimeOnly "io.netty.incubator:netty-incubator-codec-native-quic:${versions.nettyQuic}:linux-x86_64" + runtimeOnly "io.netty.incubator:netty-incubator-codec-native-quic:${versions.nettyQuic}:linux-aarch_64" + runtimeOnly "io.netty.incubator:netty-incubator-codec-native-quic:${versions.nettyQuic}:osx-x86_64" + runtimeOnly "io.netty.incubator:netty-incubator-codec-native-quic:${versions.nettyQuic}:osx-aarch_64" + runtimeOnly "io.netty.incubator:netty-incubator-codec-native-quic:${versions.nettyQuic}:windows-x86_64"Then define
versions.nettyQuicingradle/libs.versions.toml(or the appropriate version catalog) with a valid QUIC release (e.g.,0.0.72.Final).modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (2)
274-274: Security:InsecureQuicTokenHandleris not suitable for production.This handler bypasses QUIC address validation tokens, which protect against address spoofing attacks per RFC 9000. While acceptable for initial development, a production-ready token handler should be implemented before release.
Consider adding a configuration option or TODO to track this:
- .tokenHandler(InsecureQuicTokenHandler.INSTANCE) + // TODO: Implement secure token handler before production release + // See RFC 9000 Section 8 for token validation requirements + .tokenHandler(InsecureQuicTokenHandler.INSTANCE)
357-376:ServerChannelExceptionHandleris defined but never used.This class is never instantiated or added to any pipeline. Either integrate it for proper server-level exception handling or remove the dead code.
If this should handle server channel exceptions:
// In configureServerChannelHandler(), after adding the QUIC server codec: ch.pipeline().addLast("server_exception_handler", new ServerChannelExceptionHandler(Netty4QuicServerTransport.this));modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (2)
380-388: PotentialUnsupportedOperationExceptionif buffer is not heap-backed.At line 387, calling
response.content().array()assumes theByteBufis heap-backed. If the allocator returns a direct buffer, this will throwUnsupportedOperationException. Also, preferStandardCharsets.UTF_8overCharset.forName("UTF-8").- final String url = "/" + new String(new byte[maxInitialLineLength], Charset.forName("UTF-8")); + final String url = "/" + new String(new byte[maxInitialLineLength], StandardCharsets.UTF_8); final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url); final FullHttpResponse response = client.send(remoteAddress.address(), request); try { assertThat(response.status(), equalTo(HttpResponseStatus.BAD_REQUEST)); assertThat( - new String(response.content().array(), Charset.forName("UTF-8")), + new String(ByteBufUtil.getBytes(response.content()), StandardCharsets.UTF_8), containsString("you sent a bad request and you should feel bad") );
426-438: Test usesSettings.EMPTYwhich may cause port binding issues.Unlike other tests that use
createSettings()to configure a random port range, this test passesSettings.EMPTYwhich relies on default port binding. This could cause flaky failures in CI environments due to port conflicts.try ( Netty4QuicServerTransport transport = new Netty4QuicServerTransport( - Settings.EMPTY, + createSettings(), networkService, bigArrays, threadPool, xContentRegistry(), dispatcher, clusterSettings, - new SharedGroupFactory(Settings.EMPTY), + new SharedGroupFactory(createSettings()), secureHttpTransportSettingsProvider, NoopTracer.INSTANCE )plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (2)
299-300: Critical: HTTP/3 server not cleaned up if HTTP/1.1/2 bind fails.If
http11or2.bindNow()at line 300 throws an exception afterhttp3Serverhas successfully bound at line 299, the HTTP/3 server remains bound and is not cleaned up, leading to a resource leak.Apply this diff to ensure proper cleanup:
final DisposableServer http3Server = http3Opt.get(); -final DisposableServer http11or2Server = http11or2.bindNow(); +final DisposableServer http11or2Server; +try { + http11or2Server = http11or2.bindNow(); +} catch (Exception e) { + http3Server.disposeNow(); + throw e; +}Based on past review comments, this issue was marked as addressed but the fix is not present in the current code.
302-313: Latent defect: AnonymousDisposableServerreturnsnullfromchannel().The anonymous
DisposableServerimplementation returnsnullforchannel(). While the current code only callsdisposeNow()(line 541), this is fragile—if any future code (logging, monitoring, debugging, or refactoring) invokeschannel()expecting a valid reference, it will cause aNullPointerException.Consider returning a representative channel or throwing
UnsupportedOperationException:@Override public Channel channel() { - return null; /* not implemented */ + // Return the primary HTTP/1.1/2 channel for compatibility + return http11or2Server.channel(); }Based on past review comments, this issue was marked as addressed but the fix is not present in the current code.
🧹 Nitpick comments (3)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
498-501: Consider accepting test-specific settings instead of usingSettings.EMPTY.The QUIC client codec is configured with
Settings.EMPTYfor max content length and stream parameters. If tests need custom settings (e.g., larger content limits), this will use the defaults instead of test-provided values.Consider:
- Adding a
Settingsparameter toCountDownLatchHandlerHttp3constructor, or- Passing settings through the
handlerFactoryif tests require custom configuration.For now,
Settings.EMPTYmay be acceptable if all tests use default limits.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (1)
243-243: Optional: Remove extraneous blank line.This extra blank line appears to be an unintended formatting change with no behavioral impact.
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
337-351: Protocol selection logic is sound.The
randomProtocol()method correctly selects protocols based on security, HTTP/3 availability, and settings, ensuring test coverage across different protocol paths.Simplify the boolean check at line 341:
-if (Http3.isHttp3Available() && SETTING_HTTP_HTTP3_ENABLED.get(settings).booleanValue() == true) { +if (Http3.isHttp3Available() && SETTING_HTTP_HTTP3_ENABLED.get(settings)) {The explicit
== truecomparison is redundant with primitive booleans.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (44)
CHANGELOG.md(1 hunks)gradle/libs.versions.toml(1 hunks)modules/transport-netty4/build.gradle(2 hunks)modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java(2 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java(1 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java(13 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java(1 hunks)plugins/repository-azure/build.gradle(0 hunks)plugins/transport-reactor-netty4/build.gradle(2 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java(2 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java(2 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java(5 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java(3 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java(7 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java(12 hunks)server/src/main/java/org/opensearch/bootstrap/Security.java(1 hunks)server/src/main/java/org/opensearch/common/settings/ClusterSettings.java(1 hunks)server/src/main/java/org/opensearch/http/HttpRequest.java(1 hunks)server/src/main/java/org/opensearch/http/HttpTransportSettings.java(1 hunks)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java(2 hunks)
💤 Files with no reviewable changes (1)
- plugins/repository-azure/build.gradle
✅ Files skipped from review due to trivial changes (3)
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1
🚧 Files skipped from review as they are similar to previous changes (25)
- plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java
- modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java
- server/src/main/java/org/opensearch/common/settings/ClusterSettings.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java
- gradle/libs.versions.toml
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java
- server/src/main/java/org/opensearch/http/HttpTransportSettings.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
- plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java
🧰 Additional context used
🧬 Code graph analysis (3)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (1)
ReactorHttpClient(77-353)
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (3)
server/src/main/java/org/opensearch/http/AbstractHttpServerTransport.java (1)
AbstractHttpServerTransport(93-507)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java (1)
NettyAllocator(51-350)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java (3)
ChannelHandler(543-562)Netty4HttpServerTransport(130-635)HttpChannelHandler(364-541)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: gradle-check
- GitHub Check: detect-breaking-change
- GitHub Check: precommit (21, macos-15)
- GitHub Check: precommit (21, windows-2025, true)
- GitHub Check: precommit (25, ubuntu-24.04-arm)
- GitHub Check: precommit (25, windows-latest)
- GitHub Check: precommit (25, ubuntu-latest)
- GitHub Check: precommit (21, ubuntu-latest)
- GitHub Check: precommit (21, windows-latest)
- GitHub Check: precommit (25, macos-15-intel)
- GitHub Check: precommit (25, macos-15)
- GitHub Check: precommit (21, macos-15-intel)
- GitHub Check: precommit (21, ubuntu-24.04-arm)
- GitHub Check: assemble (21, windows-latest)
- GitHub Check: assemble (25, windows-latest)
- GitHub Check: assemble (21, ubuntu-latest)
- GitHub Check: assemble (25, ubuntu-latest)
- GitHub Check: assemble (25, ubuntu-24.04-arm)
- GitHub Check: assemble (21, ubuntu-24.04-arm)
- GitHub Check: Analyze (java)
- GitHub Check: Mend Security Check
🔇 Additional comments (42)
plugins/transport-reactor-netty4/build.gradle (2)
162-162: Addition of SegmentedDatagramPacket to audit exclusions is appropriate.The inclusion of
io.netty.channel.epoll.SegmentedDatagramPacketinignoreMissingClassesis correct for QUIC support, as this class is only available on Linux systems with kernel support for UDP segmentation offload (GSO), which is leveraged by QUIC's native implementation.
233-268: LGTM: Removing QUIC classes from audit violations reflects appropriate architectural elevation.By removing QUIC-related classes from
ignoreViolations(per the AI summary), this PR properly elevates QUIC from an experimental/hidden dependency to first-class public API. This signals that Netty's QUIC codec is stable enough for production use within OpenSearch's HTTP/3 transport layer.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (4)
197-197: Scheme header logic is now correct.The ternary expression correctly sets
"https"whensecureistrueand"http"whensecureisfalse. The previously reported inversion issue has been addressed.Also applies to: 210-210, 234-234
335-343: LGTM! Clean abstraction for protocol-specific channel preparation.The generic type parameter and
prepare()hook provide a flexible way for different protocol handlers to customize channel setup. HTTP/1 and HTTP/2 use the default (return channel as-is), while HTTP/3 can override to create aQuicStreamChannel.
520-540: LGTM! HTTP/3 request stream pipeline is correctly ordered.The pipeline correctly places:
Http3FrameToHttpObjectCodec(false)first to convert HTTP/3 frames to HTTP objectsHttpContentDecompressorfor decompressionHttpObjectAggregatorto aggregate chunked content- Application handler to process
FullHttpResponseThis addresses the previous review comment about codec ordering and removes the incorrect HTTP/1.x codecs (
HttpResponseDecoder,HttpRequestEncoder).
181-189: The review comment requires verification against the actual implementation of theprepare()method andsendRequestsloop. The concern about creating multipleQuicChannelinstances per request cannot be confirmed or refuted without examining the complete code at the referenced lines (508-543). The visible snippet (lines 181-189) shows only the factory method, which appears correct for basic HTTP/3 client setup.To properly verify this review comment, access to the full
CountDownLatchHandlerHttp3class and thesendRequestsmethod implementation is necessary.modules/transport-netty4/build.gradle (3)
79-84: Platform-specific native libraries bundled for all supported platforms.The approach of bundling native QUIC codecs for all platforms ensures the module works out-of-the-box on any supported OS and architecture. This follows the existing Netty pattern in the project but does increase the artifact size.
219-221: Appropriate addition to ignore platform-specific class.
SegmentedDatagramPacketis a Linux-specific (epoll) class used for optimized UDP packet handling in QUIC. It's correct to ignore this in third-party audit since it's platform-specific and not available on all operating systems.
66-68: Confirm these are incubator artifacts and document production-readiness strategy.These HTTP/3 and QUIC codecs (
netty-codec-http3,netty-codec-classes-quic,netty-codec-native-quic) are Netty incubator artifacts, not yet graduated to Netty core. As of early 2025, they remain at 0.0.xx.Final versions. While actively maintained and used in production by downstream projects like Reactor Netty (which declared HTTP/3 production-ready in Nov 2024), the incubator status means API changes and frequent releases are possible. Verify the specific${versions.netty}resolves to a supported incubator release and document the production-readiness rationale for this project.modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1 (1)
1-1: Verify the SHA1 hash matches the official Maven Central artifact.Version 4.2.7.Final is production-ready—the QUIC codec graduated from the incubator into Netty Core starting with 4.2.1.Final. Confirm the SHA1 hash
d6a7141d5fab45c8d2f6c646965f2dd53a43b41ematches the published artifact in Maven Central.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java (1)
100-100: LGTM!The change correctly passes the
settingsobject toReactorHttpClient.create(), aligning with the updated API that now requires settings for protocol selection and configuration.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java (12)
92-92: LGTM!Import for
CertificateBuilder.Algorithmenum supports the updated key store creation with explicit algorithm selection.
121-121: LGTM!Explicit algorithm specification (
Algorithm.ecp384) for key store creation improves clarity and aligns with the updatedKeyStoreUtilsAPI.
166-170: LGTM!The SSL engine construction is clean and correctly uses the key manager factory with the insecure trust manager for test purposes.
295-298: LGTM!Correctly propagates the HTTP/3 enabled setting from
initialSettingsto ensure consistent transport configuration when testing address binding conflicts.
450-456: LGTM!Randomized HTTP/3 enablement provides good test coverage for both HTTP/1.x and HTTP/3 paths in the large compressed response test.
256-256: LGTM!Passing
settingstoReactorHttpClient.https()ensures the client is configured consistently with the server's protocol settings.
363-363: LGTM!Client creation with settings aligns with the updated API contract.
410-410: LGTM!Consistent settings propagation to the HTTP client.
471-471: LGTM!Settings-aware client creation for the large compressed response test.
543-543: LGTM!Settings propagation for CORS pre-flight request test.
560-560: LGTM!Settings propagation for CORS short-circuited request test.
646-648: LGTM!Adding randomized HTTP/3 enablement to the base settings builder ensures comprehensive test coverage across both protocol modes for all tests in this class.
modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (5)
98-120: LGTM!The HTTP/3 stream settings are well-documented with sensible defaults. The 100 concurrent bidirectional streams default aligns with RFC 9114 recommendations for maintaining performance parallelism.
148-189: LGTM!Constructor properly initializes all HTTP/3 transport settings and follows established patterns from the existing Netty4HttpServerTransport implementation.
196-228: LGTM!The lifecycle implementation correctly uses
NioDatagramChannelfor UDP-based QUIC transport and properly manages the shared group and bootstrap configuration.
337-354: LGTM!The HTTP/3 pipeline is correctly configured with
Http3FrameToHttpObjectCodecplaced first to convert HTTP/3 frames to HTTP objects before downstream handlers process them. This addresses the previous review feedback about codec ordering.
378-447: LGTM!Extension points for header verification and decompression provide appropriate plugin extensibility. The compression options correctly exclude ZSTD with clear documentation explaining the direct buffer constraints.
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (4)
109-169: LGTM!Test setup properly initializes the secure HTTP transport settings provider with appropriate key/trust manager factories for QUIC/TLS testing.
186-284: LGTM!The "Expect: 100-continue" tests are well-structured, correctly use the HTTP/3 client, and properly handle response lifecycle with
ByteBufUtil.getBytes()for safe buffer access.
577-588: LGTM!The channel type mismatch from the previous review has been addressed. The bootstrap now correctly uses
NioDatagramChannelwith a matchingChannelInitializer<NioDatagramChannel>for proper UDP/QUIC testing.
599-605: LGTM!Helper methods for creating test settings with randomized port ranges are clean and consistent.
server/src/main/java/org/opensearch/http/HttpRequest.java (1)
63-64: LGTM!Adding
HTTP_3_0to theHttpVersionenum correctly extends the public API to support HTTP/3 protocol identification. The placement maintains logical version ordering and is backward compatible.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java (2)
122-122: LGTM!The test correctly adapts to the updated
ReactorHttpClient.create()signature by passingSettings.EMPTY.
162-162: LGTM!The test correctly adapts to the updated
ReactorHttpClient.create()signature by passingSettings.EMPTYin the try-with-resources block.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (3)
110-135: LGTM!The HTTP/3 stream settings use appropriate defaults:
- 1 MB (1,000,000 bytes) per stream for local and remote bidirectional streams aligns with typical QUIC implementation ranges (1-10 MB)
- 100 concurrent bidirectional streams matches the HTTP/3 standard's minimum recommendation for maintaining parallelism
These values address the concerns raised in previous reviews about excessive memory allocation.
319-368: LGTM!The
configureHttp3()method correctly:
- Checks for HTTP/3 availability and enablement (line 327)
- Configures QUIC SSL context with appropriate trust managers and client auth (lines 328-336)
- Uses
SETTING_HTTP_MAX_CONTENT_LENGTHfor connection-levelmaxData(line 356), which addresses previous feedback about not using the too-smallSETTING_HTTP_MAX_CHUNK_SIZE- Applies the newly defined HTTP/3 stream settings for bidirectional data limits and stream counts (lines 357-359)
The connection-level
maxDatavalue derived fromMAX_CONTENT_LENGTHis semantically reasonable and within typical QUIC implementation ranges.
370-370: LGTM!Renaming the method to
configureHttp11orHttp2()improves clarity by explicitly distinguishing HTTP/1.1/2 configuration from the newconfigureHttp3()method.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (3)
99-116: LGTM!The updated constructor and factory method signatures correctly accept
Settingsto enable protocol selection (including HTTP/3) based on configuration. This is a necessary API evolution for HTTP/3 support, and the changes are consistent across all factory methods.
286-326: LGTM!The
createClient()method correctly configures protocol-specific SSL contexts and settings:
- HTTP/1.1 and H2 paths use appropriate
Http11SslContextSpecandHttp2SslContextSpec- HTTP/3 path uses
Http3SslContextSpecwithout the erroneous.build()call in the lambda (addressing previous feedback)- HTTP/3 settings use
SETTING_HTTP_MAX_CONTENT_LENGTHfor connection-levelmaxDatainstead of the inappropriateSETTING_HTTP_MAX_CHUNK_SIZE(addressing previous feedback)- All settings align with the server-side HTTP/3 configuration
The changes address the concerns raised in previous reviews.
333-335: LGTM!Refactoring
useHttp11only()to check theprotocolfield instead of a separate boolean flag is cleaner and more maintainable.server/src/main/java/org/opensearch/bootstrap/Security.java (1)
132-134: Regex pattern correctly captures platform-specific JAR classifiers for Netty HTTP/3 libraries.The updated pattern properly handles JAR names with platform prefixes (linux-, windows-, osx-) required for HTTP/3 QUIC support. The regex correctly extracts both the base library name and optional platform-specific classifier from test cases including netty-tcnative-boringssl-static, kafka-server-common, lucene-core, and zstd-jni variants.
| Channel prepare(Bootstrap clientBootstrap, Channel channel) throws InterruptedException { | ||
| final QuicChannel quicChannel = QuicChannel.newBootstrap(channel) | ||
| .handler(new Http3ClientConnectionHandler()) | ||
| .remoteAddress(channel.remoteAddress()) | ||
| .connect() | ||
| .sync() | ||
| .getNow(); | ||
|
|
||
| return Http3.newRequestStream(quicChannel, new Http3RequestStreamInitializer() { | ||
| @Override | ||
| protected void initRequestStream(QuicStreamChannel ch) { | ||
| final int maxContentLength = new ByteSizeValue(100, ByteSizeUnit.MB).bytesAsInt(); | ||
| ch.pipeline().addLast(new Http3FrameToHttpObjectCodec(false)); | ||
| ch.pipeline().addLast(new HttpContentDecompressor()); | ||
| ch.pipeline().addLast(new HttpObjectAggregator(maxContentLength)); | ||
| ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpObject>() { | ||
| @Override | ||
| protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) { | ||
| if (msg instanceof FullHttpResponse ht) { | ||
| // We copy the buffer manually to avoid a huge allocation on a pooled allocator. We have | ||
| // a test that tracks huge allocations, so we want to avoid them in this test code. | ||
| ByteBuf newContent = Unpooled.copiedBuffer(ht.content()); | ||
| content.add(ht.replace(newContent)); | ||
| } | ||
| latch.countDown(); | ||
| } | ||
|
|
||
| @Override | ||
| public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { | ||
| super.exceptionCaught(ctx, cause); | ||
| latch.countDown(); | ||
| } | ||
| }); | ||
| } | ||
| }).sync().getNow(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creating a new QUIC connection for each request is inefficient and non-idiomatic.
The prepare() method is called once per request in the sendRequests loop (line 256). Each invocation creates a new QuicChannel via QuicChannel.newBootstrap(channel).connect() (line 509), which establishes a new QUIC connection. For multiple requests, this results in multiple QUIC connections instead of reusing a single connection with multiple streams.
Correct HTTP/3 behavior:
- Create the
QuicChannelonce (e.g., cache it in a field after the first call) - For subsequent requests, reuse the cached
QuicChanneland create only newQuicStreamChannelinstances viaHttp3.newRequestStream(cachedQuicChannel, ...)
Consider refactoring to cache the QuicChannel:
private static class CountDownLatchHandlerHttp3 extends AwaitableChannelInitializer<DatagramChannel> {
private final CountDownLatch latch;
private final Collection<FullHttpResponse> content;
+ private volatile QuicChannel quicChannel;
CountDownLatchHandlerHttp3(final CountDownLatch latch, final Collection<FullHttpResponse> content, final boolean secure) {
this.latch = latch;
this.content = content;
}
// ... initChannel remains the same ...
@Override
Channel prepare(Bootstrap clientBootstrap, Channel channel) throws InterruptedException {
- final QuicChannel quicChannel = QuicChannel.newBootstrap(channel)
- .handler(new Http3ClientConnectionHandler())
- .remoteAddress(channel.remoteAddress())
- .connect()
- .sync()
- .getNow();
+ if (quicChannel == null) {
+ synchronized (this) {
+ if (quicChannel == null) {
+ quicChannel = QuicChannel.newBootstrap(channel)
+ .handler(new Http3ClientConnectionHandler())
+ .remoteAddress(channel.remoteAddress())
+ .connect()
+ .sync()
+ .getNow();
+ }
+ }
+ }
return Http3.newRequestStream(quicChannel, new Http3RequestStreamInitializer() {
// ... rest remains the same ...
}).sync().getNow();
}
}Committable suggestion skipped: line range outside the PR's diff.
|
❌ Gradle check result for 3c97207: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
Signed-off-by: Andriy Redko <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (10)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
507-543: Reuse the QuicChannel across multiple requests instead of creating a new connection per request.The
prepare()method creates a newQuicChannel(QUIC connection) on each invocation. SincesendRequestscallsprepare()in a loop (line 256), each request establishes a separate QUIC connection. This is inefficient and non-idiomatic for HTTP/3, where multiple request streams should share a single QUIC connection.Expected behavior:
- First request: Create
QuicChannel→ create stream 1 → send request- Second request: Reuse
QuicChannel→ create stream 2 → send requestCurrent behavior:
- First request: Create
QuicChannel1 → create stream → send request- Second request: Create
QuicChannel2 → create stream → send requestCache the
QuicChannelin a field and reuse it for subsequent streams:private static class CountDownLatchHandlerHttp3 extends AwaitableChannelInitializer<DatagramChannel> { private final CountDownLatch latch; private final Collection<FullHttpResponse> content; + private volatile QuicChannel quicChannel; CountDownLatchHandlerHttp3(final CountDownLatch latch, final Collection<FullHttpResponse> content, final boolean secure) { this.latch = latch; this.content = content; } // ... initChannel remains the same ... @Override Channel prepare(Bootstrap clientBootstrap, Channel channel) throws InterruptedException { - final QuicChannel quicChannel = QuicChannel.newBootstrap(channel) - .handler(new Http3ClientConnectionHandler()) - .remoteAddress(channel.remoteAddress()) - .connect() - .sync() - .getNow(); + if (quicChannel == null) { + synchronized (this) { + if (quicChannel == null) { + quicChannel = QuicChannel.newBootstrap(channel) + .handler(new Http3ClientConnectionHandler()) + .remoteAddress(channel.remoteAddress()) + .connect() + .sync() + .getNow(); + } + } + } return Http3.newRequestStream(quicChannel, new Http3RequestStreamInitializer() { @Override protected void initRequestStream(QuicStreamChannel ch) { // ... pipeline setup remains the same ... } }).sync().getNow(); } }modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java (1)
27-27: Avoid exposing mutableDEFAULT_SSL_PROTOCOLSarray as public API.This concern was raised in a prior review. Changing this to
public static finalexposes a mutable array; any caller can modify its elements, silently changing TLS behavior globally at runtime. Prefer keeping the array private and exposing a defensive copy via an accessor method.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (2)
380-388: UseStandardCharsets.UTF_8instead ofCharset.forName("UTF-8").Line 380 uses
Charset.forName("UTF-8")while the rest of the file usesStandardCharsets.UTF_8. Additionally, the past review concern aboutresponse.content().array()potentially throwingUnsupportedOperationExceptionfor direct buffers remains relevant.- final String url = "/" + new String(new byte[maxInitialLineLength], Charset.forName("UTF-8")); + final String url = "/" + new String(new byte[maxInitialLineLength], StandardCharsets.UTF_8);For the
response.content().array()issue on lines 386-388, consider usingByteBufUtil.getBytes()as suggested in the past review to handle both heap and direct buffers.
426-438: Test usesSettings.EMPTYwhich may cause port binding issues.This was flagged in a prior review. Unlike other tests that use
createSettings()to configure a random port range,testLargeCompressedResponsepassesSettings.EMPTYwhich relies on default port binding. This could cause flaky failures in CI environments due to port conflicts.modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java (1)
357-376: Remove unused ServerChannelExceptionHandler or integrate it into the pipeline.This class is defined but never instantiated or added to any channel pipeline. Either wire it into
configureServerChannelHandler()to handle server-level exceptions, or remove the dead code to reduce maintenance burden.If server-level exception handling is needed, consider adding it to the server channel pipeline. Otherwise, apply this diff:
- @ChannelHandler.Sharable - private static class ServerChannelExceptionHandler extends ChannelInboundHandlerAdapter { - - private final Netty4QuicServerTransport transport; - - private ServerChannelExceptionHandler(Netty4QuicServerTransport transport) { - this.transport = transport; - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - ExceptionsHelper.maybeDieOnAnotherThread(cause); - Netty4HttpServerChannel httpServerChannel = ctx.channel().attr(HTTP_SERVER_CHANNEL_KEY).get(); - if (cause instanceof Error) { - transport.onServerException(httpServerChannel, new Exception(cause)); - } else { - transport.onServerException(httpServerChannel, (Exception) cause); - } - } - }CHANGELOG.md (1)
39-39: Remove duplicate changelog entry with malformed link.Line 39 duplicates the entry already present on line 35 and has a malformed markdown link (trailing
]instead of)).Apply this diff:
- Support dynamic consumer configuration update in pull-based ingestion ([#19963](https://github.com/opensearch-project/OpenSearch/pull/19963)) - Cache the `StoredFieldsReader` for scroll query optimization ([#20112](https://github.com/opensearch-project/OpenSearch/pull/20112)) -- Support pull-based ingestion message mappers and raw payload support ([#19765](https://github.com/opensearch-project/OpenSearch/pull/19765)] - Support for HTTP/3 (server side) ([#20017](https://github.com/opensearch-project/OpenSearch/pull/20017))gradle/libs.versions.toml (1)
152-153: Dependency resolution will fail: netty-codec-classes-quic 4.2.7.Final unavailable.As previously verified,
netty-codec-classes-quicis not published at version 4.2.7.Final on Maven Central. The build will fail during dependency resolution.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java (1)
26-37: Missing input validation in constructor may cause NPE.The constructor accepts a varargs
channelsparameter without validating that it's non-null and non-empty. Line 37'sgetLocalAddress()dereferenceschannels[0]directly, which will throw NPE or ArrayIndexOutOfBoundsException if the array is null or empty.Add validation at the start of the constructor:
ReactorNetty4CompositeHttpServerChannel(Channel... channels) { + if (channels == null || channels.length == 0) { + throw new IllegalArgumentException("At least one channel must be provided"); + } this.channels = channels; this.closeContexts = new CompletableContext[channels.length];plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
295-317: HTTP/3 server resource leak if HTTP/1.1/2 bind fails.If
http11or2.bindNow()(line 301) throws afterhttp3Serveris successfully created (line 300), the HTTP/3 server remains bound and will not be disposed, causing a resource leak and leaving a port occupied.Wrap the HTTP/1.1/2 bind in try-catch to ensure cleanup:
} else { final DisposableServer http3Server = http3Opt.get(); - final DisposableServer http11or2Server = http11or2.bindNow(); + final DisposableServer http11or2Server; + try { + http11or2Server = http11or2.bindNow(); + } catch (Exception e) { + disposeQuietly(http3Server); + throw e; + } disposableServer = new DisposableServer() {plugins/transport-reactor-netty4/build.gradle (1)
42-46: [DUPLICATE] Incorrect Netty QUIC native artifact coordinates—dependency resolution will fail.This critical issue was flagged in a prior review and remains unresolved. The artifact coordinates
io.netty:netty-codec-native-quicdo not exist on Maven Central. The correct coordinates areio.netty.incubator:netty-incubator-codec-native-quicwith separate versioning (historically0.0.x.Final, now aligned with Netty releases).Apply this diff to correct the artifact coordinates:
- // Bundle all supported OSes and Archs - runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:linux-x86_64" - runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:linux-aarch_64" - runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:osx-x86_64" - runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:osx-aarch_64" - runtimeOnly "io.netty:netty-codec-native-quic:${versions.netty}:windows-x86_64" + // Bundle all supported OSes and Archs + runtimeOnly "io.netty.incubator:netty-incubator-codec-native-quic:${versions.nettyQuic}:linux-x86_64" + runtimeOnly "io.netty.incubator:netty-incubator-codec-native-quic:${versions.nettyQuic}:linux-aarch_64" + runtimeOnly "io.netty.incubator:netty-incubator-codec-native-quic:${versions.nettyQuic}:osx-x86_64" + runtimeOnly "io.netty.incubator:netty-incubator-codec-native-quic:${versions.nettyQuic}:osx-aarch_64" + runtimeOnly "io.netty.incubator:netty-incubator-codec-native-quic:${versions.nettyQuic}:windows-x86_64"Then verify the corrected coordinates resolve by running a dependency check:
#!/bin/bash # Verify corrected QUIC artifact coordinates resolve on Maven Central cd plugins/transport-reactor-netty4 ./gradlew dependencies --configuration runtimeClasspath 2>&1 | grep -A2 -B2 'netty-incubator-codec-native-quic'
🧹 Nitpick comments (4)
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (1)
488-505: Consider parameterizing QUIC client settings for test flexibility.The QUIC client codec uses
Settings.EMPTYfor all configuration (max content length, stream lengths, max streams). While default values work for most tests, consider accepting a Settings parameter in the factory method to allow tests to customize these limits when needed (e.g., testing large payloads or many concurrent streams).Example approach:
-public static Netty4HttpClient http3() { +public static Netty4HttpClient http3(Settings settings) { return new Netty4HttpClient( new Bootstrap().channel(NioDatagramChannel.class) .option(ChannelOption.ALLOCATOR, NettyAllocator.getAllocator(true)) .group(new NioEventLoopGroup(1)), - CountDownLatchHandlerHttp3::new, + (latch, content, secure) -> new CountDownLatchHandlerHttp3(latch, content, secure, settings), false ); }Then pass
settingsinstead ofSettings.EMPTYin lines 498-501.modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java (1)
160-166: Consider simplifying the boolean comparison.The logic correctly provides direct buffer support for HTTP/3/QUIC which requires direct buffers. Minor style suggestion:
directBuffers == truecan be simplified todirectBuffers.public static ByteBufAllocator getAllocator(boolean directBuffers) { - if (directBuffers == true && ALLOCATOR instanceof NoDirectBuffers ndb) { + if (directBuffers && ALLOCATOR instanceof NoDirectBuffers ndb) { return ndb.delegate; /* Http3/Quic only supports direct buffers */ } else { return ALLOCATOR; } }plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
320-369: Consider validating QUIC availability earlier to fail fast.The HTTP/3 configuration checks
Http3.isHttp3Available()insideconfigureHttp3(), which is called during bind. Consider validating HTTP/3 availability duringdoStart()and logging a clear warning if HTTP/3 is enabled but unavailable (e.g., missing native libraries for the current OS/architecture), so operators can detect configuration issues before attempting to bind.server/src/main/java/org/opensearch/bootstrap/Security.java (1)
132-134: Regex update forCODEBASE_JAR_WITH_CLASSIFIERlooks correct; confirm classifier semantics vs existing policiesThe new pattern:
private static final Pattern CODEBASE_JAR_WITH_CLASSIFIER = Pattern.compile( "^(.+)-\\d+\\.\\d+[^-]*.*?[-]?((?:linux-|windows-|osx-)?[^-]+)?\\.jar$" );behaves as expected for the examples called out in the comments:
netty-tcnative-boringssl-static-2.0.61.Final-linux-x86_64.jar→group(2) == "linux-x86_64".kafka-server-common-3.6.1-test.jar→group(2) == "test".zstd-jni-1.5.6-1.jar→group(2) == "1".- Plain versioned jars like
lucene-core-9.11.0.jarkeepgroup(2) == nulland follow the existing non-classifier path.One nuance to be aware of: for names with multiple hyphen-separated tokens after the version (e.g.,
lucene-core-9.11.0-snapshot-8a555eb.jar),group(2)will only expose the final token ("8a555eb"), not"snapshot-8a555eb". That’s fine if the intent is just to derive a unique suffix for aliasing, but it can change the exact alias key used in policy files (codebase.<name>@<suffix>).I’d suggest:
- Double-checking whether any existing
.policyfiles rely on the oldgroup(2)shape (e.g., expectingsnapshot-<hash>instead of just<hash>), since that could silently change alias names.- Adding or updating a small unit test for
CODEBASE_JAR_WITH_CLASSIFIERcovering the four examples in the comment (including the lucene snapshot case) so future classifier variants don’t regress.If you want, I can sketch a small JUnit test that exercises this pattern against representative jar names and asserts the expected
group(1)/group(2)pairs.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (44)
CHANGELOG.md(1 hunks)gradle/libs.versions.toml(1 hunks)modules/transport-netty4/build.gradle(2 hunks)modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java(2 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4QuicServerTransport.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/NettyAllocator.java(1 hunks)modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SslUtils.java(1 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java(13 hunks)modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java(1 hunks)plugins/repository-azure/build.gradle(0 hunks)plugins/transport-reactor-netty4/build.gradle(2 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1(1 hunks)plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1(1 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java(2 hunks)plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java(2 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4CompositeHttpServerChannel.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java(1 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java(7 hunks)plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java(6 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java(1 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java(3 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java(7 hunks)plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java(12 hunks)server/src/main/java/org/opensearch/bootstrap/Security.java(1 hunks)server/src/main/java/org/opensearch/common/settings/ClusterSettings.java(1 hunks)server/src/main/java/org/opensearch/http/HttpRequest.java(1 hunks)server/src/main/java/org/opensearch/http/HttpTransportSettings.java(1 hunks)test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java(2 hunks)
💤 Files with no reviewable changes (1)
- plugins/repository-azure/build.gradle
✅ Files skipped from review due to trivial changes (1)
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
🚧 Files skipped from review as they are similar to previous changes (22)
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequestHandler.java
- modules/transport-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4PipeliningIT.java
- plugins/transport-reactor-netty4/src/internalClusterTest/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequestSizeLimitIT.java
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-windows-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-classes-quic-4.2.7.Final.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-aarch_64.jar.sha1
- plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpRequest.java
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportStreamingTests.java
- plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4BadRequestTests.java
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-osx-x86_64.jar.sha1
- modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1
- plugins/transport-reactor-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-aarch_64.jar.sha1
- modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpServerTransport.java
- test/framework/src/main/java/org/opensearch/test/KeyStoreUtils.java
🧰 Additional context used
🧬 Code graph analysis (2)
server/src/main/java/org/opensearch/common/settings/ClusterSettings.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
HttpTransportSettings(58-270)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: gradle-check
- GitHub Check: detect-breaking-change
- GitHub Check: assemble (21, ubuntu-24.04-arm)
- GitHub Check: assemble (25, ubuntu-latest)
- GitHub Check: assemble (21, windows-latest)
- GitHub Check: assemble (21, ubuntu-latest)
- GitHub Check: assemble (25, ubuntu-24.04-arm)
- GitHub Check: assemble (25, windows-latest)
- GitHub Check: precommit (25, macos-15-intel)
- GitHub Check: precommit (25, macos-15)
- GitHub Check: precommit (21, windows-2025, true)
- GitHub Check: precommit (25, ubuntu-24.04-arm)
- GitHub Check: precommit (25, ubuntu-latest)
- GitHub Check: precommit (25, windows-latest)
- GitHub Check: precommit (21, macos-15-intel)
- GitHub Check: precommit (21, macos-15)
- GitHub Check: precommit (21, ubuntu-24.04-arm)
- GitHub Check: precommit (21, ubuntu-latest)
- GitHub Check: precommit (21, windows-latest)
- GitHub Check: Analyze (java)
- GitHub Check: Mend Security Check
🔇 Additional comments (20)
plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransportTests.java (1)
205-205: LGTM! Consistent Settings propagation to ReactorHttpClient.The updates consistently pass Settings to
ReactorHttpClient.create()across all test methods, aligning client configuration with the transport. When the transport uses specific settings, the client receives them; when the transport usesSettings.EMPTY, so does the client. This enables HTTP/3 protocol configuration to flow through the test infrastructure.Also applies to: 310-310, 356-356, 412-412, 478-478, 541-541, 558-558
modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4HttpClient.java (2)
181-189: LGTM! HTTP/3 factory correctly configured for QUIC transport.The factory method properly sets up a UDP-based (DatagramChannel) bootstrap for QUIC/HTTP/3, with the appropriate allocator and handler.
516-542: LGTM! HTTP/3 request stream pipeline correctly configured.The pipeline setup follows the correct order for HTTP/3:
Http3FrameToHttpObjectCodec(false)converts HTTP/3 frames to HTTP objects- Standard HTTP processing (
HttpContentDecompressor,HttpObjectAggregator)- Application handler
The response handler properly copies buffers to avoid pooled allocator issues and counts down the latch in both success and exception paths.
plugins/transport-reactor-netty4/src/main/java/org/opensearch/transport/reactor/ReactorNetty4Plugin.java (1)
59-66: LGTM!The expansion of
getSettings()to include the new HTTP/3 related settings (SETTING_H3_MAX_STREAM_LOCAL_LENGTH,SETTING_H3_MAX_STREAM_REMOTE_LENGTH,SETTING_H3_MAX_STREAMS) aligns with the HTTP/3 feature additions and properly exposes these settings for cluster configuration.modules/transport-netty4/licenses/netty-codec-http3-4.2.7.Final.jar.sha1 (1)
1-1: LGTM!SHA1 checksum file for the new
netty-codec-http3dependency required for HTTP/3 support.server/src/main/java/org/opensearch/http/HttpRequest.java (1)
60-65: LGTM!The
HTTP_3_0constant extends the publicHttpVersionenum to support HTTP/3 protocol identification, maintaining consistent naming with existing versions.modules/transport-netty4/src/test/java/org/opensearch/http/netty4/Netty4QuicServerTransportTests.java (2)
109-169: LGTM on test setup!The test infrastructure is well-configured with proper SSL/TLS setup using PKIX key manager factory and ECP384 algorithm, appropriate for HTTP/3 testing requirements.
577-596: LGTM on read timeout test structure!The test correctly uses
NioDatagramChannelwith matchingChannelInitializer<NioDatagramChannel>generic type, addressing the previous channel type mismatch concern. The UDP-based bootstrap is appropriate for QUIC testing.plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ReactorHttpClient.java (4)
99-104: LGTM on constructor refactoring!The constructor now properly accepts
Settingsand delegates torandomProtocol()for protocol selection, enabling settings-driven HTTP/3 enablement.
106-116: LGTM on factory method updates!The static factory methods now require
Settingsparameter, ensuring consistent settings propagation for protocol selection.
287-318: LGTM on HTTP/3 client configuration!The secure client configuration correctly handles all three protocol paths:
- HTTP/1.1 with
Http11SslContextSpec- HTTP/2 with
Http2SslContextSpec(including HTTP/1.1 fallback)- HTTP/3 with
Http3SslContextSpecand proper QUIC settingsThe
http3Settingsconfiguration correctly uses connection-levelSETTING_HTTP_MAX_CONTENT_LENGTHformaxData(addressing the prior review concern) and stream-level settings for bidirectional stream limits.
337-351: LGTM on protocol selection logic!The
randomProtocol()method correctly:
- Checks
Http3.isHttp3Available()before including HTTP/3 as an option- Respects
SETTING_HTTP_HTTP3_ENABLEDsetting- Falls back to HTTP/1.1 and H2 when HTTP/3 is unavailable or disabled
server/src/main/java/org/opensearch/common/settings/ClusterSettings.java (1)
427-427: LGTM! HTTP/3 setting properly registered.The addition of
SETTING_HTTP_HTTP3_ENABLEDto the built-in cluster settings is correct and necessary for cluster-wide recognition of the HTTP/3 enablement flag.server/src/main/java/org/opensearch/http/HttpTransportSettings.java (1)
262-267: LGTM! HTTP/3 enablement setting properly defined.The setting declaration is correct with appropriate default (false), scope (NodeScope), and documentation noting OS/architecture dependencies.
modules/transport-netty4/build.gradle (2)
66-84: LGTM! HTTP/3 and QUIC dependencies properly added.The additions correctly wire HTTP/3 and QUIC codecs as API dependencies and include platform-specific native QUIC libraries for comprehensive runtime support across Linux, macOS, and Windows on both x86_64 and aarch64 architectures.
219-221: LGTM! thirdPartyAudit exclusions appropriate for QUIC integration.The additions to
ignoreMissingClassesforio.netty.pkitesting.X509Bundleandio.netty.channel.epoll.SegmentedDatagramPacketare appropriate for the Netty QUIC codec integration.plugins/transport-reactor-netty4/src/main/java/org/opensearch/http/reactor/netty4/ReactorNetty4HttpServerTransport.java (1)
114-136: LGTM! HTTP/3 stream settings use reasonable defaults.The defaults of 1MB per stream (local/remote) and 100 concurrent bidirectional streams align with typical QUIC implementations and provide a good balance between memory usage and throughput for server-side HTTP/3.
plugins/transport-reactor-netty4/build.gradle (2)
162-162: Addition of SegmentedDatagramPacket to ignoreMissingClasses is appropriate for UDP-based QUIC support.The addition of
io.netty.channel.epoll.SegmentedDatagramPacketto theignoreMissingClasseslist aligns with Netty's UDP-based QUIC implementation and is consistent with the native QUIC codec additions in this file.
37-39: Verify that libs.netty.codec.classes.quic and libs.netty.codec.native.quic are defined in the version catalog.Lines 38–39 reference version catalog properties for QUIC codecs. Ensure these aliases are properly defined in the central version catalog (typically
gradle/libs.versions.toml) and resolve to valid Netty QUIC artifacts.modules/transport-netty4/licenses/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1 (1)
1-1: Confirm the SHA-1 hash matches Maven Central upstream.The
io.netty:netty-codec-native-quic:4.2.7.Finalversion is current (released October 14, 2025) and the checksum file format is correct. Verify the digest6a3e4398852f926c4b22f381d89dae2388446ae8matches the upstream artifact by running:curl -s "https://repo1.maven.org/maven2/io/netty/netty-codec-native-quic/4.2.7.Final/netty-codec-native-quic-4.2.7.Final-linux-x86_64.jar.sha1"If the value differs from what's in the file, update the checksum to match the upstream artifact.
|
❌ Gradle check result for ffa76d3: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
Description
Support for HTTP/3 (server side)
Related Issues
Closes #4451
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.
Summary by CodeRabbit
New Features
HTTP Behavior
Settings
Tests
Chores
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.