Skip to content

feat(listener): make normalize_path and path_with_escaped_slashes_act… - #7703

Open
agentdanabol wants to merge 5 commits into
projectcontour:mainfrom
agentdanabol:fix/7694-normalize-path-and-path-with-escaped-slashes
Open

feat(listener): make normalize_path and path_with_escaped_slashes_act…#7703
agentdanabol wants to merge 5 commits into
projectcontour:mainfrom
agentdanabol:fix/7694-normalize-path-and-path-with-escaped-slashes

Conversation

@agentdanabol

@agentdanabol agentdanabol commented Aug 28, 2026

Copy link
Copy Markdown

Fixes #7694 by adding two new listener settings for exposing Envoy path transformations that Contour previously hardcoded

@agentdanabol
agentdanabol requested a review from a team as a code owner August 28, 2026 11:19
@agentdanabol
agentdanabol requested review from sunjayBhatia and tsaarni and removed request for a team August 28, 2026 11:19
@agentdanabol
agentdanabol force-pushed the fix/7694-normalize-path-and-path-with-escaped-slashes branch 2 times, most recently from 9202469 to f0a93b4 Compare August 28, 2026 11:52
…ion configurable

Signed-off-by: sheiko <sheiko@tochka.com>
@agentdanabol
agentdanabol force-pushed the fix/7694-normalize-path-and-path-with-escaped-slashes branch from f0a93b4 to 5a4f8e2 Compare August 28, 2026 11:55
@tsaarni tsaarni added the release-note/small A small change that needs one line of explanation in the release notes. label Aug 28, 2026
@codecov

codecov Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.98246% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.04%. Comparing base (7c4ef54) to head (6949f85).
⚠️ Report is 11 commits behind head on main.

Files with missing lines Patch % Lines
cmd/contour/serve.go 0.00% 2 Missing ⚠️
cmd/contour/servecontext.go 75.00% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #7703      +/-   ##
==========================================
+ Coverage   82.33%   84.04%   +1.71%     
==========================================
  Files         131      131              
  Lines       15915    14225    -1690     
==========================================
- Hits        13103    11956    -1147     
+ Misses       2523     2269     -254     
+ Partials      289        0     -289     
Files with missing lines Coverage Δ
internal/contourconfig/contourconfiguration.go 99.35% <100.00%> (+0.64%) ⬆️
internal/envoy/v3/listener.go 95.73% <100.00%> (+0.85%) ⬆️
internal/xdscache/v3/listener.go 94.24% <100.00%> (+3.02%) ⬆️
pkg/config/parameters.go 91.22% <100.00%> (+4.68%) ⬆️
cmd/contour/serve.go 24.22% <0.00%> (+0.46%) ⬆️
cmd/contour/servecontext.go 91.45% <75.00%> (+4.65%) ⬆️

... and 125 files with indirect coverage changes

🚀 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.

@agentdanabol
agentdanabol marked this pull request as draft August 31, 2026 10:55
sheiko added 3 commits August 31, 2026 15:01
Two failures from the previous run:

- unescape_and_redirect expected 301, but Envoy answers escaped-slash
  redirects with 307 and a path-only Location header. See the
  NormalizePathAction::Redirect handling in Envoy's conn_manager_impl.cc,
  which uses Code::TemporaryRedirect.

- disableNormalizePath asserted on which backend answered, which depends
  on route matching. Assert on the ":path" the upstream actually receives
  instead, using a single catch-all route. This is what normalize_path
  documents ("This affects the upstream :path header as well") and removes
  route matching from the assertion.

  The previous run showed the un-normalized path still being collapsed, so
  also log Envoy's own /config_dump normalize_path counts. That makes a
  future failure self-diagnosing: it distinguishes "the setting never
  reached Envoy" from "Envoy did not honor the setting". Best effort, since
  the admin listener is not what this spec asserts.

Signed-off-by: sheiko <sheiko@tochka.com>
The previous assertion could not distinguish the two cases it was meant to
tell apart. The echo fixture is a Go ServeMux server, and ServeMux cleans
the request path itself, answering 301 to the cleaned target. Because the
test client follows redirects, "/foo/../bar" ended up re-requested as
"/bar" either way:

  - Envoy normalizes    -> backend gets "/bar",        200, path "/bar"
  - Envoy does not      -> backend gets "/foo/../bar", 301 -> follow
                           -> re-request "/bar",       200, path "/bar"

Both produced "upstream saw /bar, status 200", which is why the earlier
route-matching variant reported echo-1: the followed request for "/bar"
matched the "/bar" prefix route. Note "/foo%2Fbar" is not cleaned by
ServeMux, which is why the escaped-slashes specs were unaffected.

Stop following redirects and assert on the first response instead, which
makes the backend's behavior the signal: 301 with Location "/bar" proves
Envoy forwarded the dot segments verbatim, 200 proves it normalized them.

Also drop the /config_dump diagnostic: it reported the admin listener as
unreachable from this suite, so it added nothing.

Signed-off-by: sheiko <sheiko@tochka.com>
check-changefile-exists.go requires changelogs/unreleased/PR#-author-category.
The file was named after issue 7694 instead of PR 7703, so the Release Note
Label Check failed on the missing changelog. The category still matches the
release-note/small label on the PR.

Signed-off-by: sheiko <sheiko@tochka.com>
@agentdanabol
agentdanabol marked this pull request as ready for review August 31, 2026 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note/small A small change that needs one line of explanation in the release notes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make Envoy's normalize_path and path_with_escaped_slashes_action configurable

2 participants