Skip to content

Add support for HttpProtocolOptions - #6843

Merged
jrhee17 merged 2 commits into
line:mainfrom
jrhee17:feat/xds-session-protocol
Jul 9, 2026
Merged

Add support for HttpProtocolOptions#6843
jrhee17 merged 2 commits into
line:mainfrom
jrhee17:feat/xds-session-protocol

Conversation

@jrhee17

@jrhee17 jrhee17 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Motivation:

When a cluster configures typed_extension_protocol_options with envoy.extensions.upstreams.http.v3.HttpProtocolOptions, Envoy uses the ExplicitHttpConfig or AutoHttpConfig to determine which HTTP version to use for upstream connections. Previously, Armeria's xDS client ignored this configuration and always defaulted to HTTP/HTTPS based solely on whether TLS was enabled, which meant clusters that explicitly declared HTTP/2 or HTTP/1 were not honored.

Modifications:

  • Parse HttpProtocolOptions from the cluster's typed_extension_protocol_options map in ClusterStream and pass it into ClusterFilterFactory.
  • Derive SessionProtocol from the parsed options in ClusterFilterFactory:
    • explicit_http_config with http2_protocol_optionsH2 / H2C
    • explicit_http_config with http_protocol_optionsH1 / H1C
    • auto_config or absent → HTTPS / HTTP (existing default behavior)

Result:

  • The xDS client now respects HttpProtocolOptions from cluster configuration and selects the correct SessionProtocol (H1, H1C, H2, H2C, HTTP, HTTPS) accordingly.

@jrhee17 jrhee17 added this to the 1.41.0 milestone Jul 7, 2026
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 67a374f0-bf4b-44b2-b26c-3c9d7273edb0

📥 Commits

Reviewing files that changed from the base of the PR and between a01e376 and cf7e17d.

📒 Files selected for processing (1)
  • xds/src/main/java/com/linecorp/armeria/xds/ClusterStream.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • xds/src/main/java/com/linecorp/armeria/xds/ClusterStream.java

📝 Walkthrough

Walkthrough

This PR adds XDS proto support annotations, parses HttpProtocolOptions from cluster configuration, threads them through cluster snapshot creation, updates session protocol selection based on TLS and explicit HTTP config, and adds integration tests covering HTTP and HTTPS cases.

Changes

HttpProtocolOptions session protocol wiring

Layer / File(s) Summary
Proto annotations for supported fields
xds-api/.../cluster.proto, xds-api/.../http_protocol_options.proto
Adds Armeria XDS support annotations to typed_extension_protocol_options and the HTTP protocol option oneof members in the cluster and upstream HTTP proto schemas.
Parse HttpProtocolOptions from cluster extensions
xds/.../ClusterStream.java
Reads typed_extension_protocol_options, unpacks HttpProtocolOptions, and passes the parsed value into cluster snapshot construction through the new wiring path.
ClusterFilterFactory session protocol computation
xds/.../ClusterFilterFactory.java
Accepts nullable HttpProtocolOptions, computes sessionProtocol from TLS and explicit HTTP config, and includes sessionProtocol in toString().
ClusterSnapshot delegation to ClusterFilterFactory
xds/.../ClusterSnapshot.java
Stores a ClusterFilterFactory, exposes httpProtocolOptions(), delegates preprocessor accessors to the factory, and updates its debug string.
Integration test for session protocol selection
it/xds-client/.../HttpProtocolOptionsTest.java
New integration tests build HTTP and TLS bootstrap configurations, run requests through the XDS preprocessor, and assert the captured SessionProtocol values.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ClusterStream
  participant ExtensionRegistry
  participant ClusterFilterFactory
  participant ClusterSnapshot
  participant Server as Armeria Server

  ClusterStream->>ClusterStream: read typed_extension_protocol_options
  ClusterStream->>ExtensionRegistry: unpack HttpProtocolOptions from Any
  ClusterStream->>ClusterFilterFactory: new ClusterFilterFactory(loadBalancer, httpProtocolOptions, transportSocket)
  ClusterStream->>ClusterSnapshot: new ClusterSnapshot(..., clusterFilterFactory)
  ClusterSnapshot->>ClusterFilterFactory: httpPreprocessor()
  ClusterFilterFactory->>ClusterFilterFactory: sessionProtocol(tls, httpProtocolOptions)
  ClusterSnapshot->>Server: preprocessor output for request
Loading

Suggested reviewers: trustin, ikhoon, minwoox

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding support for HttpProtocolOptions.
Description check ✅ Passed The description matches the implemented changes and explains the new HttpProtocolOptions handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
it/xds-client/src/test/java/com/linecorp/armeria/xds/it/HttpProtocolOptionsTest.java (1)

63-133: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider extracting shared test scaffolding to reduce duplication.

BOOTSTRAP_TEMPLATE/sessionProtocolSelection and TLS_BOOTSTRAP_TEMPLATE/tlsSessionProtocolSelection duplicate nearly the entire YAML template and test body, differing only in the transport_socket block and port. Consider parameterizing a single template/method with an optional TLS block to avoid the duplication.

Also applies to: 136-211

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@it/xds-client/src/test/java/com/linecorp/armeria/xds/it/HttpProtocolOptionsTest.java`
around lines 63 - 133, The `sessionProtocolSelection` and
`tlsSessionProtocolSelection` tests duplicate the same bootstrap YAML and
request/assertion flow, differing mainly in the `transport_socket` block and
port. Refactor the shared setup into one parameterized test (or shared helper)
in `HttpProtocolOptionsTest`, and make
`BOOTSTRAP_TEMPLATE`/`TLS_BOOTSTRAP_TEMPLATE` a single template that accepts an
optional TLS block so both cases reuse the same `XdsResourceReader`,
`XdsBootstrap`, `XdsHttpPreprocessor`, and client execution path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@xds-api/src/main/proto/envoy/extensions/upstreams/http/v3/http_protocol_options.proto`:
- Around line 156-165: Add support for the oneof arm UseDownstreamHttpConfig in
the HTTP protocol options handling, since it is currently only warned/rejected
and not respected by ClusterFilterFactory.sessionProtocol(). Update the logic
that parses the HttpProtocolOptions oneof in the relevant validator/index and
cluster filter code so this arm is accepted and mapped to the downstream
protocol behavior instead of falling back to HTTP/HTTPS; reference the oneof in
HttpProtocolOptions, DefaultXdsValidatorIndex, StrictXdsValidatorIndex, and
ClusterFilterFactory.sessionProtocol() when implementing the change.

In `@xds/src/main/java/com/linecorp/armeria/xds/ClusterStream.java`:
- Around line 112-129: In ClusterStream.parseHttpProtocolOptions, invalid or
mismatched Any values can still throw IllegalArgumentException from
context.extensionRegistry().unpack() and break snapshot creation. Update the
parsing flow to catch that failure around the unpack of
HTTP_PROTOCOL_OPTIONS_KEY and either return null as if the option is missing or
convert it into a targeted validation error, so the exception does not escape
the lbStream mapping in ClusterStream.

---

Nitpick comments:
In
`@it/xds-client/src/test/java/com/linecorp/armeria/xds/it/HttpProtocolOptionsTest.java`:
- Around line 63-133: The `sessionProtocolSelection` and
`tlsSessionProtocolSelection` tests duplicate the same bootstrap YAML and
request/assertion flow, differing mainly in the `transport_socket` block and
port. Refactor the shared setup into one parameterized test (or shared helper)
in `HttpProtocolOptionsTest`, and make
`BOOTSTRAP_TEMPLATE`/`TLS_BOOTSTRAP_TEMPLATE` a single template that accepts an
optional TLS block so both cases reuse the same `XdsResourceReader`,
`XdsBootstrap`, `XdsHttpPreprocessor`, and client execution path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1410acd1-dcd6-4c52-adfd-2ea36b31aa2f

📥 Commits

Reviewing files that changed from the base of the PR and between 051d14e and a01e376.

📒 Files selected for processing (6)
  • it/xds-client/src/test/java/com/linecorp/armeria/xds/it/HttpProtocolOptionsTest.java
  • xds-api/src/main/proto/envoy/config/cluster/v3/cluster.proto
  • xds-api/src/main/proto/envoy/extensions/upstreams/http/v3/http_protocol_options.proto
  • xds/src/main/java/com/linecorp/armeria/xds/ClusterFilterFactory.java
  • xds/src/main/java/com/linecorp/armeria/xds/ClusterSnapshot.java
  • xds/src/main/java/com/linecorp/armeria/xds/ClusterStream.java

Comment thread xds/src/main/java/com/linecorp/armeria/xds/ClusterStream.java Outdated
@jrhee17
jrhee17 marked this pull request as ready for review July 8, 2026 01:25
@jrhee17
jrhee17 requested review from ikhoon and minwoox as code owners July 8, 2026 01:25
@mergify

mergify Bot commented Jul 8, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0.00%. Comparing base (8150425) to head (a01e376).
⚠️ Report is 524 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main   #6843       +/-   ##
============================================
- Coverage     74.46%       0   -74.47%     
============================================
  Files          1963       0     -1963     
  Lines         82437       0    -82437     
  Branches      10764       0    -10764     
============================================
- Hits          61385       0    -61385     
+ Misses        15918       0    -15918     
+ Partials       5134       0     -5134     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ikhoon ikhoon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍

@minwoox minwoox left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍 👍

final ClusterFilterFactory factory = new ClusterFilterFactory(loadBalancer, transportSocket);
httpPreprocessor = factory.httpPreprocessor();
rpcPreprocessor = factory.rpcPreprocessor();
this.clusterFilterFactory = clusterFilterFactory;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add this to toString, hashCode, equals?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fields in clusterFilterFactory are XdsLoadBalancer, HttpProtocolOptions, TransportSocketSnapshot.
All of these are derived from the raw resources, or are already part of the equality/hashcode contract.

I'm not sure if adding toString would add much value

}
return lbStream.map(lb -> new ClusterSnapshot(
resource, lb, input.transportSocket, input.transportSocketMatches));
final HttpProtocolOptions httpProtocolOptions = parseHttpProtocolOptions(resource.resource());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can call this at line 92 not to parse the resource multiple time.

@jrhee17
jrhee17 merged commit fe73b6c into line:main Jul 9, 2026
14 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants