Skip to content

feat(conformance): support GatewayPort8080 - #79

Merged
perbu merged 9 commits into
varnish:mainfrom
KealanAU:feat/gateway-port-8080
Jul 28, 2026
Merged

feat(conformance): support GatewayPort8080#79
perbu merged 9 commits into
varnish:mainfrom
KealanAU:feat/gateway-port-8080

Conversation

@KealanAU

@KealanAU KealanAU commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Closes #30.

The operator change matched the issue's prediction—a one-line feature declaration—but enabling it exposed an unrelated redirect bug.

  • Declare features.SupportGatewayPort8080. No operator changes were required because listener ports already propagate to the Service and container ports.
  • Enabling the feature un-skips HTTPRouteRedirectPortAndScheme, which is gated on both this feature and HTTPRoutePortRedirect.
  • This exposed a bug: a RequestRedirect with no scheme or port derived the redirect port from the client's Host header. For example, curl -H 'Host: example.org' http://gw:8080/ redirected to http://example.org/.
  • Fix the root cause by deriving the redirect port from the authoritative Varnish socket name (for example, http-8080), matching the existing scheme behavior.
  • Rename RedirectConfig.original_scheme/original_port to listener_scheme/listener_port to reflect their actual purpose: the values come from the listener, not the request.
  • Merged main after fix(ghost): use well-known redirect port when scheme is unchanged #80 landed the complementary spec fix (a non-empty redirect scheme always takes its well-known port). The resolution keeps fix(ghost): use well-known redirect port when scheme is unchanged #80's semantics verbatim on the renamed fields: filter.portwell_known_port(scheme)listener_port, in the spec's own order.
  • Fix kind-metallb.sh to work on OrbStack. It assumed Kind's usual /16 network, but OrbStack uses /24, causing the address pool to be off-network and all traffic conformance tests to time out.

Behavior change: Deployments that perform port translation in front of the Gateway now use the listener port for redirects when no explicit redirect port is configured. To preserve the previous behavior, set requestRedirect.port.

Tests: test_redirect_listener_port.vtc proves scheme and port derive from the socket name end-to-end (http-8080, https-8443). Unit coverage for the port rules is #80's test_build_location_same_scheme_uses_well_known_port plus the pre-existing build_location tests. cargo test --release: 97 passed, 0 failed. Full conformance suite re-run post-merge: PASS (make test-conformance).

Declare features.SupportGatewayPort8080. The multi-listener architecture
already maps listener ports straight through to Service and container
ports, so no operator change is needed.

Enabling the feature also un-skips HTTPRouteRedirectPortAndScheme, which
surfaced a redirect bug: a RequestRedirect filter with no scheme and no
port built the Location port from the client's Host header rather than
the Gateway listener port. A portless Host against a listener on 8080
redirected to port 80. The listener socket name is authoritative, per
spec; fall back to the Host header only for sockets that carry no port
(e.g. ghost-reload).

Closes varnish#30
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 71.91%. Comparing base (31580b9) to head (f2ab03e).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #79      +/-   ##
==========================================
+ Coverage   71.87%   71.91%   +0.04%     
==========================================
  Files          41       41              
  Lines        6716     6716              
==========================================
+ Hits         4827     4830       +3     
+ Misses       1545     1543       -2     
+ Partials      344      343       -1     

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

The pool was built from the subnet's first two octets with a hardcoded
.255.x range, assuming the /16 kind usually creates. OrbStack hands kind
a /24, so the pool landed off-network and every LoadBalancer IP was
unroutable from the host — all traffic-based conformance tests timed out
locally.

Derive the third octet from the prefix length instead: .255 on a /16, so
the pool stays clear of Docker IPAM (which allocates upward from the
bottom), and the subnet's own third octet on anything smaller.
@KealanAU
KealanAU force-pushed the feat/gateway-port-8080 branch from 28ea8eb to d8040d3 Compare July 28, 2026 09:16
KealanAU and others added 3 commits July 28, 2026 12:17
The redirect path added a second private strip_port alongside the
bracket-aware one in director.rs, and the two disagreed: on a malformed
`[2001:db8::1]:foo` Host the new one returned the whole string, which
would have landed a stray `:foo` inside the Location header.

Make director::strip_port pub(crate) and import it, so the tested
implementation is the only one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
test_listener_port covers the helper, but nothing exercised the redirect
itself: varnishtest names its socket "a0", so every assertion in
test_request_redirect.vtc went through the 80/443 fallback and the new
code path only ran under the out-of-tree conformance suite.

Name the VTC sockets the way the chaperone does and connect to each
explicitly. The ports live in the socket names only — varnishtest binds
each to a random port, which is the point: nothing reads the real bound
port. Each case sends a Host with a conflicting port to prove it is
ignored. Verified as a regression guard: hardcoding the port back to the
Host value fails c_http8080.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@KealanAU
KealanAU force-pushed the feat/gateway-port-8080 branch from 232a322 to 9f13b14 Compare July 28, 2026 10:18
KealanAU added 4 commits July 28, 2026 12:58
The VTC in 9f13b14 is the end-to-end guard, but VTC tests only run in
release mode, so a debug 'cargo test --lib' had no coverage of a redirect
on a listener that isn't on 80/443. Add the build_location case, plus the
two that must not change with it: an explicit filter port still wins, and
a scheme change still resets to that scheme's well-known port.

Also note the behaviour change in the changelog — deployments that
port-translate in front of the Gateway now get the listener port in a
portless redirect, and must set requestRedirect.port to pin the old
value.
# Conflicts:
#	CHANGELOG.md
#	ghost/src/redirect_backend.rs
The merge of varnish#80 brought test_build_location_same_scheme_uses_well_known_port,
whose no-scheme case asserts exactly what test_build_location_keeps_listener_port
did; its other sub-cases repeated test_build_location_basic and
test_build_location_default_ports. The vtc keeps http-8080 and https-8443 as the
end-to-end proof that scheme and port derive from the socket name; the
default-port-omission and portless-socket clients re-ran pure functions already
unit-tested (test_should_omit_port, test_listener_port).
@KealanAU
KealanAU marked this pull request as ready for review July 28, 2026 11:40
@perbu
perbu merged commit ff7844c into varnish:main Jul 28, 2026
5 checks passed
@perbu

perbu commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Thanks!

@KealanAU

Copy link
Copy Markdown
Contributor Author

Tack, Appreciate the review and merge!

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.

Support GatewayPort8080

2 participants