Skip to content

Keep percent-encoded reserved characters when following Location - #2607

Closed
xop01 wants to merge 1 commit into
yhirose:masterfrom
xop01:fix-redirect-reserved-encoding
Closed

xop01 wants to merge 1 commit into
yhirose:masterfrom
xop01:fix-redirect-reserved-encoding

Conversation

@xop01

@xop01 xop01 commented Oct 3, 2026

Copy link
Copy Markdown

Summary

  • ClientImpl::redirect ran decode_path_component on the Location path before sending the next request.
  • That decoder expands every %XX, including reserved characters. %2F became a path separator and %3F became a query delimiter, so the client requested a different URI from the one named in Location (RFC 3986 sections 2.2 and 6.2.2.2).
  • The path is now sent with its original percent-encoding. encode_request_target still encodes raw controls when path encoding is on, and write_request_line still rejects them when it is off.

Test plan

  • Local client/server: Location: /a%2Fb is requested as /a%2Fb, and Location: /x%3Fy is requested as /x%3Fy with no query parameter y
  • RedirectLocationTest.PreservesEncodedSlashAndQuestion
  • Existing redirect tests (PostMethod303Redirect and the relative-location cases) still pass

decode_path_component turned %2F and %3F into real delimiters, so the follow-up request-target was a different URI from the one the redirect named.

Co-authored-by: Cursor <cursoragent@cursor.com>
yhirose added a commit that referenced this pull request Oct 3, 2026
…#2607)

A 303 response turns the follow-up request into a GET, but only the buffered body and headers were cleared. A content provider (sized or chunked) stayed on the request, so the original payload was sent again, and for a chunked provider the unframed chunks also broke the keep-alive connection.

The redirect also percent-decoded the Location path before sending it. That turned %23, %3F and %25 into a fragment, a query delimiter and a different octet, so the client requested a different resource than the one named, and made set_path_encode(false) fail on any Location containing %20. The path is now sent as given.
@yhirose

yhirose commented Oct 3, 2026

Copy link
Copy Markdown
Owner

Thanks for finding this. The bug is real, and an equivalent fix is in master as 09fa682. The test there also covers %23 and set_path_encode(false). Closing in favor of that commit.

@yhirose yhirose closed this Oct 3, 2026
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.

2 participants