Skip to content

Fix preserving %2F at HTTP/1 absolute-form request#65930

Merged
DeagleGross merged 6 commits intodotnet:mainfrom
DeagleGross:dmkorolev/kestrel-absolute-form-path-canonicalization
Apr 13, 2026
Merged

Fix preserving %2F at HTTP/1 absolute-form request#65930
DeagleGross merged 6 commits intodotnet:mainfrom
DeagleGross:dmkorolev/kestrel-absolute-form-path-canonicalization

Conversation

@DeagleGross
Copy link
Copy Markdown
Member

Fixes an inconsistency in HTTP/1.1 request-target parsing where %2F in the path produces different
HttpRequest.Path values depending on the request-target form:

Request Before After
GET /a%2Fb (origin-form) /a%2Fb /a%2Fb
GET http://host/a%2Fb (absolute-form) /a/b /a%2Fb

DeagleGross and others added 4 commits March 23, 2026 19:41
…ute-form

When processing HTTP/1.1 absolute-form request targets (e.g.,
GET http://host/a%2Fb), Kestrel used Uri.LocalPath to extract the path,
which decodes %2F to '/'. This differed from origin-form handling which
uses PathDecoder.DecodePath that deliberately preserves %2F.

Replace Uri.LocalPath with Uri.AbsolutePath (which preserves percent-
encoding) followed by PathDecoder.DecodePath, ensuring both request-
target forms produce identical HttpRequest.Path values.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ute-form

When processing HTTP/1.1 absolute-form request targets (e.g.,
GET http://host/a%2Fb), Kestrel used Uri.LocalPath to extract the path,
which decodes %2F to '/'. This differed from origin-form handling which
uses PathDecoder.DecodePath that deliberately preserves %2F.

Replace Uri.LocalPath with Uri.AbsolutePath (which preserves percent-
encoding) followed by PathDecoder.DecodePath, ensuring both request-
target forms produce identical HttpRequest.Path values.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
https://github.com/DeagleGross/aspnetcore into dmkorolev/kestrel-absolute-form-path-canonicalization

# Conflicts:
#	src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs
@DeagleGross DeagleGross self-assigned this Mar 23, 2026
@DeagleGross DeagleGross requested a review from halter73 as a code owner March 23, 2026 19:27
Copilot AI review requested due to automatic review settings March 23, 2026 19:27
@DeagleGross DeagleGross added the area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions label Mar 23, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes an inconsistency in Kestrel HTTP/1.1 request-target parsing so that an encoded slash (%2F) is preserved in HttpRequest.Path for absolute-form targets, matching origin-form (and aligning with HTTP/2/3 path decoding behavior).

Changes:

  • Add StartLineTests coverage for %2F preservation in both origin-form and absolute-form request-targets.
  • Update Http1Connection.OnAbsoluteFormTarget to derive Path via PathDecoder.DecodePath (using Uri.AbsolutePath) instead of uri.LocalPath, avoiding %2F being decoded to /.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/Servers/Kestrel/Core/test/StartLineTests.cs Adds test cases validating %2F stays encoded in Path for origin-form and absolute-form.
src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs Switches absolute-form path materialization from Uri.LocalPath to PathDecoder.DecodePath over Uri.AbsolutePath to preserve %2F.

Comment thread src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs Outdated
Comment thread src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs Outdated
Comment thread src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs Outdated
Comment thread src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs Outdated
@DeagleGross DeagleGross enabled auto-merge (squash) March 24, 2026 10:29
This was referenced Mar 25, 2026
@dotnet-policy-service dotnet-policy-service Bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Mar 31, 2026
@DeagleGross DeagleGross disabled auto-merge April 7, 2026 20:31
@DeagleGross
Copy link
Copy Markdown
Member Author

/azp run

@dotnet-policy-service dotnet-policy-service Bot removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Apr 13, 2026
@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

@DeagleGross DeagleGross merged commit 5886e20 into dotnet:main Apr 13, 2026
25 checks passed
@DeagleGross DeagleGross deleted the dmkorolev/kestrel-absolute-form-path-canonicalization branch April 13, 2026 12:07
@dotnet-policy-service dotnet-policy-service Bot added this to the 11.0-preview4 milestone Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants