Skip to content

Add HTTP protocol version to response extra field#2466

Merged
AlexV525 merged 10 commits intomainfrom
copilot/add-http-version-to-response
Mar 2, 2026
Merged

Add HTTP protocol version to response extra field#2466
AlexV525 merged 10 commits intomainfrom
copilot/add-http-version-to-response

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Nov 25, 2025

Expose the negotiated HTTP protocol version in Response.extra so it can be used for telemetry and observability.

Changes Made

  • Added support for storing HTTP version in response metadata:
    • IOHttpClientAdapter populates the value from dart:io response headers (best-effort).
    • Http2Adapter sets the value to 2.0 and preserves any pre-existing value (??=).
  • Moved the key from a top-level constant to a static member on HttpClientAdapter, and renamed it to:
    • HttpClientAdapter.extraKeyHttpVersion
  • Updated API documentation to clarify that this value may be unavailable with some adapters (for example web_adapter and native_dio_adapter) depending on transport metadata support.
  • Updated tests to use HttpClientAdapter.extraKeyHttpVersion and verify behavior in dio and http2_adapter.

Notes

  • web_adapter uses XMLHttpRequest, which does not reliably expose negotiated HTTP protocol version.
  • native_dio_adapter uses package:http response abstractions in its shared conversion layer, which do not provide a generic HTTP version field.
Original prompt

This section details on the original issue you should resolve

<issue_title>Indicate http version used for connection/response</issue_title>
<issue_description>### Request Statement

When receiving an http response from upstream server it would be really handy to know which http version served the response. E.g. http1.1 / http2

This is super handy to add to e.g. OTEL telemetry to understand how the responses are being server from upstream infrastructure.

Thank you!

Solution Brainstorm

Updating the ResponseBody with an extra parameter might be an ok place to put this. Its not really the body of the response, but it already has some non-body items in anyway....</issue_description>

<agent_instructions>Investigate if it's truly possible to identify the actual HTTP protocol.
If yes, file a PR to implement it; If not, reply to the issue instead.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@AlexV525 Based on my knowledge, the *protocol* header with the HTTP version should be available in the response's header. @AlexV525 For HTTP/1.x it's available in the raw header, but it's not publicly visible. Image

For H2 we have nothing available from the transport, unfortunately.

We seem to have no reliable method to inspect the protocol during the request and response. WDYT?</comment_new>
<comment_new>@AlexV525

The http2 proto is handled by a separate code path, so it already knows that it is http2..

and http2 (h2) can be hardcoded in the http2 handler? If the status line protocol version isn't available at all, it would still be ok to make distinction between http1.x and 2, as there are different code paths.

If you don't access the adapter directly, you won't know if it's actually h2:

} on DioH2NotSupportedException catch (e) {
// Fallback to use the callback
// or to another adapter (typically IOHttpClientAdapter)
// since the request can have a better handle by it.
if (onNotSupported != null) {
return onNotSupported!(options, requestStream, cancelFuture, e);
}
return fallbackAdapter.fetch(options, requestStream, cancelFuture);

The adapter will automatically retry with H1 if H2 is not available.
So the result here doesn't make sense since it's just simply guessing.

Can get the http1.x proto from status line - 99% it will be 1.1,

This is also inaccessible with dart:io AFAIK.

Then can be exposed in a way to make it public in the ResponseBody.

We intend to place only necessary information in classes. To retrieve the protocol version, based on the above paths, you can guess the protocol version from what adapter you are using, and make a minimum override to the H2 adapter to be aware of the fallback behavior.</comment_new>


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits November 25, 2025 02:34
Co-authored-by: AlexV525 <15884415+AlexV525@users.noreply.github.com>
Co-authored-by: AlexV525 <15884415+AlexV525@users.noreply.github.com>
Copilot AI changed the title [WIP] Add HTTP version indication to response Add HTTP protocol version to response extra field Nov 25, 2025
Copilot AI requested a review from AlexV525 November 25, 2025 02:43
Copy link
Copy Markdown
Member

@AlexV525 AlexV525 left a comment

Choose a reason for hiding this comment

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

@copilot Fix suggestions below and merge from the main branch.

Comment thread plugins/http2_adapter/lib/src/http2_adapter.dart Outdated
Co-authored-by: AlexV525 <15884415+AlexV525@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage Report: Only Changed Files listed

Package Base Coverage New Coverage Difference
dio/lib/src/adapters/io_adapter.dart 🟢 88.61% 🟢 88.89% 🟢 0.28%
plugins/http2_adapter/lib/src/http2_adapter.dart 🟠 74.13% 🟠 74.31% 🟢 0.18%
Overall Coverage 🟢 88.42% 🟢 88.44% 🟢 0.02%

Minimum allowed coverage is 0%, this run produced 88.44%

@AlexV525
Copy link
Copy Markdown
Member

@copilot Explore the ability to obtain the HTTP version from native_dio_adapter and web_adapter based on this PR.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 28, 2026

@copilot Explore the ability to obtain the HTTP version from native_dio_adapter and web_adapter based on this PR.

Findings from exploration:

  • native_dio_adapter: in the shared conversion layer we only receive package:http StreamedResponse, which has no HTTP version field. For Cronet specifically, runtime responses can be CronetStreamedResponse with negotiatedProtocol, so we could read that via dynamic cast and infer protocol/version in a best-effort way. For Cupertino, I couldn’t find a public equivalent in the package:http surface.
  • web_adapter: current implementation uses XMLHttpRequest, which does not expose negotiated HTTP version/protocol (no reliable h1/h2/h3 signal).

So: reliable generic support is not available for native/web today; only Cronet has an adapter-specific path (negotiatedProtocol) that could be added as best-effort if you want me to implement that.

@AlexV525 AlexV525 marked this pull request as ready for review February 28, 2026 16:34
@AlexV525 AlexV525 requested a review from a team as a code owner February 28, 2026 16:34
@AlexV525
Copy link
Copy Markdown
Member

AlexV525 commented Mar 1, 2026

@copilot Move httpVersionKey to a static member of HttpClientAdapter, and indicate that the value might be not available when using other adapters such as web_adapter and native_dio_adapter.

Co-authored-by: AlexV525 <15884415+AlexV525@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 1, 2026

@copilot Move httpVersionKey to a static member of HttpClientAdapter, and indicate that the value might be not available when using other adapters such as web_adapter and native_dio_...

Implemented in 6d1a1e9. httpVersionKey is now HttpClientAdapter.httpVersionKey, usages/tests were updated, and API docs now note that the value may be unavailable with adapters like web_adapter and native_dio_adapter.

@AlexV525
Copy link
Copy Markdown
Member

AlexV525 commented Mar 1, 2026

@copilot rename httpVersionKey to extraKeyHttpVersion

Co-authored-by: AlexV525 <15884415+AlexV525@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 1, 2026

@copilot rename httpVersionKey to extraKeyHttpVersion

Implemented in 8a480bf. Renamed to HttpClientAdapter.extraKeyHttpVersion and updated all usages/tests accordingly.

Copy link
Copy Markdown
Contributor

@CaiJingLong CaiJingLong left a comment

Choose a reason for hiding this comment

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

LGTM

@AlexV525 AlexV525 merged commit d4289af into main Mar 2, 2026
6 checks passed
@AlexV525 AlexV525 deleted the copilot/add-http-version-to-response branch March 2, 2026 02:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Indicate http version used for connection/response

3 participants