Skip to content

Rewrite publisher origin URLs in proxied response headers - #1238

Open
dhruv8sh wants to merge 11 commits into
mainfrom
fix/rewrite-origin-urls-in-response-headers
Open

dhruv8sh wants to merge 11 commits into
mainfrom
fix/rewrite-origin-urls-in-response-headers

Conversation

@dhruv8sh

@dhruv8sh dhruv8sh commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Publisher pages had origin URLs rewritten in the body but not in response headers. Browsers then followed Location/Refresh off the appliance, preloaded Link targets straight from the origin, and blocked rewritten resources under a CSP that only allowed the origin.
  • Response headers now get the same origin-to-serving-host mapping as the body. Location, Content-Location, Refresh and Link (including imagesrcset) are rewritten. For CSP, a serving-host source is added beside each origin source, and no origin source is removed. Each response's own header values are rewritten, so per-page policies survive; this is not one static replacement.
  • An origin redirect to the current URL under a different scheme (for example, an http:// origin forcing HTTPS) is left unchanged so it can't loop. So is a cookieless GET/HEAD redirect to the current URL under the same scheme, which loops when the origin redirects on something sent unchanged (such as an origin Host override); it is logged at warn. Same-scheme redirects to the current URL after a form POST, or that set a cookie, are still rewritten.
  • Templates cached before this change are not replayed after deploy: the core build digest from Fold a build-time core source digest into the template fingerprint #1210 already changes the template fingerprint, so no schema bump is needed.

Changes

File Change
crates/trusted-server-core/src/response_header_rewrite.rs New module that rewrites URLs in Location, Content-Location, Refresh, Link (<target> and quoted imagesrcset) and CSP/CSP-Report-Only. CSP is additive with de-duplication, and report-uri/report-to are skipped. Includes the scheme-change and cookieless same-URL GET/HEAD loop guards and unit tests.
crates/trusted-server-core/src/publisher.rs Calls the rewrite on every publisher route, right after the origin response and before the template-cache gate, so cached templates replay the rewritten policy headers. Adds handler tests: a 302 with an HTML body, a bodiless 301, scheme-upgrade, same-scheme POST and cookieless GET redirects to the current URL, and a template-cache hit replaying the rewritten CSP/Link. Reuses the captured request path and query for the readthrough reader URL and the template key.
crates/trusted-server-core/src/lib.rs Registers the module (pub(crate)).
docs/guide/configuration.md Documents the header behavior, the loop exceptions, that <meta http-equiv> refresh/CSP tags in the body are not rewritten, that a serving-host CSP source also allows /first-party/proxy, that [response_headers] still overrides the rewrite, and that host rewriting cannot authorize inline inserts that lack a nonce.

Closes

Closes #1128

Test plan

  • cargo test-fastly && cargo test-axum (also cargo test-cloudflare, cargo test-spin, and the parity integration test)
  • cargo clippy-fastly && cargo clippy-axum (also clippy-cloudflare, clippy-cloudflare-wasm, clippy-spin-native, clippy-spin-wasm)
  • cargo fmt --all -- --check
  • JS tests: cd crates/trusted-server-js/lib && npx vitest run (Node 24.12.0, per .tool-versions)
  • JS format: cd crates/trusted-server-js/lib && npm run format
  • Docs format: cd docs && npm run format (plus the markdown check outside docs/)
  • WASM build: cargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1
  • Manual testing via fastly compute serve
  • Other: mutation check. Moving the rewrite after the template-cache policy capture makes the cache-hit replay test fail.

Not yet done: re-running the issue's browser checks (Chrome against the Axum dev server) for Location, Refresh, Link preload and the CSP img-src case.

Checklist

  • Changes follow AGENTS.md conventions
  • No unwrap() in production code — use expect("should ...")
  • Uses log macros (not println!)
  • New code has tests
  • No secrets or credentials committed

Publisher pages had origin URLs rewritten in the body but not in headers, so browsers followed Location and Refresh to the origin, preloaded Link targets from it, and blocked rewritten resources under the forwarded CSP.

Map origin URLs in Location, Content-Location, Refresh, and Link (including imagesrcset) to the serving host on every publisher response, and add serving-host sources beside origin sources in Content-Security-Policy and its report-only variant. Rewriting runs before the template-cache gate so cached templates replay the rewritten policy headers; bump the template schema to 6 so entries stored with origin-only policy metadata are not replayed.

Leave a Location or Refresh target unchanged when it names the current request URL under a different scheme than the origin, so an origin scheme upgrade cannot loop the browser.

Closes #1128

Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
@dhruv8sh dhruv8sh self-assigned this Oct 5, 2026
@dhruv8sh
dhruv8sh requested review from ChristianPavilonis, aram356 and prk-Jr and removed request for aram356 and prk-Jr October 5, 2026 11:59

@prk-Jr prk-Jr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Summary

Solid, well-tested change. Rewrites origin URLs in Location, Content-Location, Refresh, Link, and both CSP headers; Set-Cookie/Vary untouched. Host matching is strict and case-insensitive, multi-value headers preserve order, and the rewrite runs before template-cache capture (with the schema bump to 6) in the shared handle_publisher_request path used by all adapters. No blocking findings.

Non-blocking

  • 🤔 Loop-guard escape logs only at debug (inline, suggestion)
  • 🤔 Same-URL cookie-setting redirect can loop when the cookie has Domain=<origin host> (inline)
  • 🌱 CSP :* / explicit default-port sources not matched (inline)
  • ⛏ Docs row omits report-to (inline, suggestion)

📌 Out of scope

Set-Cookie Domain, Reporting-Endpoints/Report-To, and Access-Control-Allow-Origin still pass through unchanged. Leaving report endpoints alone matches the report-uri choice; the Set-Cookie Domain gap (see inline comment) is worth a follow-up issue. Asset-proxy routes (handle_asset_proxy_request) also bypass this rewrite, consistent with the docs saying "publisher response".

📝 Note

The PR checklist says "Uses tracing macros", but the code correctly uses log — only the checklist wording is off.

Verification

  • cargo fmt --all -- --check ✅
  • cargo clippy-fastly ✅ (no warnings)
  • cargo test -p trusted-server-core (host) ✅ 2916 passed, 0 failed (includes 18 new response_header_rewrite tests and 5 new publisher tests)
  • Both suggestions scratch-verified (fmt/clippy/tests; docs prettier check)
  • CI: all 20 checks passing

Comment thread crates/trusted-server-core/src/response_header_rewrite.rs Outdated
Comment thread crates/trusted-server-core/src/response_header_rewrite.rs Outdated
Comment thread crates/trusted-server-core/src/response_header_rewrite.rs
Comment thread docs/guide/configuration.md Outdated
Comment thread crates/trusted-server-core/src/response_header_rewrite.rs
Comment thread crates/trusted-server-core/src/response_header_rewrite.rs

@ChristianPavilonis ChristianPavilonis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Review summary

Reviewed 7871acdd56324d20c182e0c3093e5bd535dd96e9 against 80483011e30a446ac741b4423e36f8d142c5d2ac, branch fix/rewrite-origin-urls-in-response-headers into main. Approving with two P2 edge-case findings posted inline.

Inspected all five changed files and traced the rewrite through publisher response modes, cache capture/replay, all four adapters, and final header overrides. Cache-hit, repeated-policy-header, and previous-schema rejection tests confirm rewritten policy replay for the tested core cache implementation.

Validation and review context

  • cargo test -p trusted-server-core response_header_rewrite --locked: 18 passed. Initial compilation timed out; rerun completed.
  • cargo test -p trusted-server-core publisher::tests --locked: 372 passed.
  • cargo test -p trusted-server-core platform::template_cache --locked: 32 passed.
  • cargo test -p trusted-server-core --locked --quiet: 2,916 unit tests passed; 4 doctests passed, 5 ignored.
  • cargo fmt --all -- --check: passed.
  • An exact-module scratch executable and two node --input-type=module Chromium fixtures reproduced the inline findings.
  • CI: All 20 reported checks passed; none reported failed or skipped.
  • Existing feedback: Inspected the review, inline comments, unresolved threads, replies, and issue comments. Neither finding duplicates existing feedback.
  • Residual risk: Browser fixtures exercised the exact rewrite module, not a deployed adapter. Adapter suites, production Fastly cache, and lint checks were not rerun locally.
  • Revision remained unchanged; working tree is clean. No repository files were edited and no review work was delegated.

Comment thread crates/trusted-server-core/src/response_header_rewrite.rs Outdated
Comment thread crates/trusted-server-core/src/response_header_rewrite.rs Outdated
dhruv8sh and others added 7 commits October 7, 2026 18:10
A scheme-change redirect such as https://origin.example.com?x=1 or one with dot segments was compared to the request path as raw text, so it did not match /?x=1 and was rewritten back to the URL the browser had just requested, looping. Parse the target as a URL so the comparison sees the same path and query the browser will follow.

Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Deduplication compared whole source expressions case-insensitively, so a policy listing origin paths /A.js and /a.js gained a serving-host sibling only for /A.js and the rewritten /a.js stayed blocked. Compare scheme and host case-insensitively and the path exactly, as CSP path matching does.

Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
When the origin forces a different scheme than publisher.origin_url, every navigation leaves the serving host and bypasses Trusted Server. That almost always means origin_url has the wrong scheme, so surface it as a warning naming the setting to check.

Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Same-scheme redirects to the current URL are now kept on the serving host, but Set-Cookie Domain attributes are not rewritten. A cookie scoped to the origin host is rejected on the serving host, so a cookie-gated self-redirect repeats. State this in the navigation rewrite docs and the configuration guide.

Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
…ls-in-response-headers

Signed-off-by: dhruv8sh <dhruv8sh@proton.me>

@aram356 aram356 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Summary

Rewrites publisher-origin URLs in Location, Content-Location, Refresh, Link, and CSP headers so the browser stays on the serving host (closes #1128). The rewrite holds up in a real browser, but the branch now conflicts with main after #1210, and #1210 changes the right resolution for the schema bump.

2 of the inline comments below carry a one-click GitHub suggestion. Use Commit suggestion (or Add suggestion to batch for both) to apply them as commits on the PR branch. The remaining comments describe the fix in prose because the change touches multiple files or lines outside the diff and can't be auto-applied.

Blocking

🔧 wrench

  • Conflicts with main; drop the v6 schema bump: see inline at crates/trusted-server-core/src/platform/template_cache.rs:41

Non-blocking

🤔 thinking / 📌 out of scope / ⛏ nitpick

  • 🤔 A Host override turns a canonical-host redirect into a loop: see inline at crates/trusted-server-core/src/response_header_rewrite.rs:92
  • 🤔 A serving-host CSP source also allows /first-party/proxy (suggestion): see inline at docs/guide/configuration.md:828
  • 📌 <meta http-equiv> refresh and CSP in the page body are not rewritten: see inline at docs/guide/configuration.md:783
  • ⛏ Allocate lazily in rewrite_link (suggestion): see inline at crates/trusted-server-core/src/response_header_rewrite.rs:296
  • ⛏ Reuse request_path_and_query: see inline at crates/trusted-server-core/src/publisher.rs:4523

Cross-cutting / body-level findings

  • 🏕 CHANGELOG entry: operators upgrading will see changed Location values and wider CSP headers on proxied pages. A suggested line under ### Fixed:

    • Publisher responses now map origin URLs in Location, Content-Location, Refresh, and Link headers to the serving host, and each CSP source naming the origin gains a serving-host source beside it. A redirect to the current URL under a different scheme is left unchanged to avoid a loop. See "Origin URLs in proxied response headers" in the configuration guide.

Verification

  • Browser checks from the test plan's unchecked item, run with the Axum dev server and Chrome at 0d0689aca. Location, Refresh, and the Link preload stay on the serving host, and the origin log shows no direct hits. In the CSP img-src case, the rewritten image loads with no violation. The scheme-upgrade redirect is left unchanged, with one hop and no loop. On main, the same headers pass through unrewritten.
  • A scratch merge with origin/main (da31a215e), resolved as described in the 🔧 comment, passes fmt, clippy-fastly, test-fastly (2,919 core tests), test-axum, test-cloudflare, test-spin, and parity.
  • Both suggestions are scratch-verified. The docs one passes the docs prettier check. The Rust one passes fmt, all six adapter clippy aliases, the four adapter test suites, and parity.

CI Status

All checks ran on head 0d0689aca, which predates #1210. Nothing has run on a merge with current main.

  • Analyze (actions): PASS
  • Analyze (javascript-typescript): PASS
  • Analyze (javascript-typescript): PASS
  • Analyze (python): PASS
  • Analyze (rust): PASS
  • browser integration tests: PASS
  • cargo check (cloudflare native + wasm32-unknown-unknown): PASS
  • cargo check/build/test (spin native + wasm32-wasip1): PASS
  • cargo fmt: PASS (required)
  • cargo test: PASS (required)
  • cargo test (axum native): PASS
  • cargo test (cross-adapter parity): PASS
  • cargo test (ts CLI, native) (macos-latest): PASS
  • cargo test (ts CLI, native) (ubuntu-latest): PASS
  • CLAUDE.md symlink guard: PASS
  • CodeQL: PASS
  • format-docs: PASS (required)
  • format-typescript: PASS (required)
  • integration tests: PASS
  • integration tests (Fastly EC lifecycle): PASS
  • prepare integration artifacts: PASS
  • vitest: PASS

Comment thread crates/trusted-server-core/src/platform/template_cache.rs Outdated
Comment thread crates/trusted-server-core/src/response_header_rewrite.rs Outdated
Comment thread docs/guide/configuration.md
Comment thread docs/guide/configuration.md
Comment thread crates/trusted-server-core/src/response_header_rewrite.rs Outdated
Comment thread crates/trusted-server-core/src/publisher.rs
Keep template schema version 5 from main. The core build digest added in #1210 already invalidates templates stored before the response header rewrite, so the version 6 bump is no longer needed.

Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
A GET or HEAD redirect to the current URL that sets no cookie loops through Trusted Server when the origin redirects on something sent unchanged, such as an origin Host override. Leave its Location unchanged and log a warning.

Also allocate lazily when rewriting Link values, reuse the captured request path and query, document the meta tag gap and the proxy reach of serving-host CSP sources, and add a changelog entry.

Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
@aram356 aram356 added this to the 202610 milestone Oct 12, 2026
aram356 added a commit that referenced this pull request Oct 12, 2026
Brings #1238 at d824a42.

Integration decisions:
- CHANGELOG.md, lib.rs and publisher.rs imports keep both sides: the
  RC's request_timing module and #1238's response_header_rewrite module
  sit side by side.
- The header rewrite runs where #1238 placed it, after the RC's trace
  extension and unexpected-304 handling and before the template-cache
  gate.

@aram356 aram356 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Summary

Round 2 at d824a42d3. Every round-1 finding is addressed. The schema bump is gone, the CSP warning and meta-tag note are in the guide with #1265 tracking the meta tags, both nits are applied, and the CHANGELOG has an entry. The new loop guard fixes the round-1 repro, but only when the redirect sets no cookie, so the same loop comes back for origins that set a cookie on every response.

1 of the inline comments below carries a one-click GitHub suggestion. Use Commit suggestion to apply it as a commit on the PR branch. The remaining comments describe the fix in prose because the change touches multiple files and can't be auto-applied.

Blocking

🔧 wrench

  • A cookie on the canonical-host redirect reopens the override loop: see inline at crates/trusted-server-core/src/response_header_rewrite.rs:130

Non-blocking

📝 note / ⛏ nitpick

  • 📝 Conflicts with main in CHANGELOG.md only; keep both lines: see inline at CHANGELOG.md:36
  • ⛏ No test covers the HEAD half of is_get_or_head (suggestion): see inline at crates/trusted-server-core/src/publisher.rs:16434

Verification

  • Browser checks with the Axum dev server and Chrome at d824a42d3:
    • The round-1 cases still pass. Location, Refresh, and the Link preload stay on the serving host, the CSP img-src image loads, and the scheme-upgrade redirect is left unchanged after one hop.
    • The new guard works for a cookieless canonical-host 301 and for HEAD.
    • A cookie-gate redirect without an override is still rewritten and ends at 200 on the serving host.
    • A POST-redirect-GET stays on the serving host, and an origin self-loop leaves after one hop through TS.
  • A scratch merge with origin/main (9cf305589), resolved as in the 📝 comment, passes every CI-equivalent gate.
  • The suggestion is scratch-verified. It passes fmt, all six clippy aliases, the four adapter test suites, and parity, and it fails under the is_get mutation.

CI Status

All checks ran on head d824a42d3, which merged main at 695ab669a. Main has moved since, and nothing has run on a merge with current main.

  • Analyze (actions): PASS
  • Analyze (javascript-typescript): PASS
  • Analyze (javascript-typescript): PASS
  • Analyze (python): PASS
  • Analyze (rust): PASS
  • browser integration tests: PASS
  • cargo check (cloudflare native + wasm32-unknown-unknown): PASS
  • cargo check/build/test (spin native + wasm32-wasip1): PASS
  • cargo fmt: PASS (required)
  • cargo test: PASS (required)
  • cargo test (axum native): PASS
  • cargo test (cross-adapter parity): PASS
  • cargo test (ts CLI, native) (macos-latest): PASS
  • cargo test (ts CLI, native) (ubuntu-latest): PASS
  • CLAUDE.md symlink guard: PASS
  • CodeQL: PASS
  • format-docs: PASS (required)
  • format-typescript: PASS (required)
  • integration tests: PASS
  • integration tests (Fastly EC lifecycle): PASS
  • prepare integration artifacts: PASS
  • vitest: PASS

/// unchanged, such as `publisher.origin_host_header_override`.
fn rewrite_location(&self, url: &str, response_sets_cookie: bool) -> Option<String> {
let rewritten = self.rewrite_navigation_url(url)?;
if self.request_is_get_or_head && !response_sets_cookie && self.targets_current_request(url)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🔧 wrench — The cookie check reopens the round-1 loop for any origin that sets a cookie on the redirect, and many set one on every response: load-balancer stickiness (AWSALB, F5 BIG-IP) or Cloudflare __cf_bm. I re-ran the round-1 setup in Chrome at d824a42d3 (Axum dev server, origin http://127.0.0.1:8301, origin_host_header_override = "www.example.com"):

  • Canonical-host 301 with no cookie: the Location is kept and Chrome loads the page from the origin. The fix works for this case.
  • The same 301 plus Set-Cookie: AWSALB=<random>; Path=/; Max-Age=604800: the Location is rewritten to http://127.0.0.1:3031/canon-sticky on every hop. Chrome made 20 requests to that URL and stopped at ERR_TOO_MANY_REDIRECTS. The origin saw 20 hits through TS, all with Host: www.example.com, each carrying the cookie from the previous hop. A constant AWSALB=constant loops the same way.

This handler test reproduces it. At this head it fails with left: Some("https://publisher.example/redirect"), which is the URL just requested:

#[tokio::test]
async fn overridden_host_redirect_with_cookie_is_not_rewritten_into_a_loop() {
    let mut settings = create_test_settings();
    settings.publisher.origin_host_header_override = Some("publisher.example".to_string());
    let stub = Arc::new(StubHttpClient::new());
    stub.push_response_with_headers(
        301,
        Vec::new(),
        vec![
            (
                header::LOCATION.as_str(),
                "https://origin.test-publisher.com/redirect",
            ),
            (header::SET_COOKIE.as_str(), "AWSALB=abc123; Path=/"),
        ],
    );
    let services = build_services_with_http_client(
        Arc::clone(&stub) as Arc<dyn crate::platform::PlatformHttpClient>
    );

    let response = run_publisher_proxy(&settings, &services, publisher_page_request()).await;

    assert_eq!(
        proxy_response_headers(&response)
            .get(header::LOCATION)
            .and_then(|value| value.to_str().ok()),
        Some("https://origin.test-publisher.com/redirect"),
        "should not send a host-change redirect back to the URL it requested"
    );
}

The cookie doesn't tell us anything in this case. When the Host TS sends differs from the origin host, a Location on the origin host with the current path is a host change from the origin's point of view: the origin is saying the Host was wrong, and the retry through TS sends the same Host. The new bullet in the configuration guide names exactly this case as handled. Proposed fix: pass the outbound Host in and skip the cookie condition when it differs.

// OriginHeaderRewrite
    /// `Host` header Trusted Server sends to the origin (`host` or `host:port`).
    ///
    /// When it differs from [`Self::origin_host`], a `Location` naming the
    /// origin host and the current path is a host change from the origin's
    /// point of view, so the retry through Trusted Server is redirected again
    /// whatever cookies the response sets.
    pub origin_host_header: &'a str,

// rewrite_location
        let host_redirect = !self
            .origin_host_header
            .eq_ignore_ascii_case(self.origin_host);
        if self.request_is_get_or_head
            && (host_redirect || !response_sets_cookie)
            && self.targets_current_request(url)
        {

// publisher.rs, the OriginHeaderRewrite literal
            origin_host_header: &origin_host_header,

The test struct literals need the field too ("origin.example.com" in REWRITE, "127.0.0.1:8301" in origin_with_port_requires_matching_port), and the "sets no cookie" wording in configuration.md and the CHANGELOG line should say the cookie check applies only without a Host override. Without an override, cookie-gate redirects are still rewritten. I applied this in a scratch tree. It passes the 49 existing tests that match redirect or response_header_rewrite, plus the handler test above and a unit-level twin.

Apply manually: the change spans response_header_rewrite.rs, publisher.rs, and the docs.

Comment thread CHANGELOG.md

### Fixed

- Publisher responses now map origin URLs in `Location`, `Content-Location`, `Refresh`, and `Link` headers to the serving host, and each CSP source naming the origin gains a serving-host source beside it (#1128). A redirect to the current URL under a different scheme, or a cookieless `GET`/`HEAD` redirect to the current URL, is left unchanged to avoid a loop. `<meta>` refresh and CSP tags in the page body are not rewritten. See "Origin URLs in proxied response headers" in the configuration guide.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

📝 note — The branch conflicts with main again, this time only here: #1221 (569ad862d) also added a line at the top of ### Fixed. Keeping both lines resolves it. I merged origin/main (9cf305589) into this head that way in a scratch tree, and the result passes fmt, all six clippy aliases, test-fastly (2,948 core tests), test-fastly-reuse, test-axum, test-cloudflare, test-spin, and parity.

Comment on lines +16424 to +16434
let location = redirect_location_for_current_url(
"https://origin.test-publisher.com",
Method::GET,
"https://origin.test-publisher.com/redirect",
)
.await;

assert_eq!(
location, "https://origin.test-publisher.com/redirect",
"should not redirect a cookieless GET back to the URL it requested"
);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

⛏ nitpick — Nothing exercises the HEAD half of is_get_or_head: with let is_get_or_head = is_get; every test still passes. Looping this test over both methods catches that mutation.

Suggested change
let location = redirect_location_for_current_url(
"https://origin.test-publisher.com",
Method::GET,
"https://origin.test-publisher.com/redirect",
)
.await;
assert_eq!(
location, "https://origin.test-publisher.com/redirect",
"should not redirect a cookieless GET back to the URL it requested"
);
for method in [Method::GET, Method::HEAD] {
let location = redirect_location_for_current_url(
"https://origin.test-publisher.com",
method.clone(),
"https://origin.test-publisher.com/redirect",
)
.await;
assert_eq!(
location, "https://origin.test-publisher.com/redirect",
"should not redirect a cookieless {method} back to the URL it requested"
);
}

This branch has not been deployed

No deployments
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.

URLs in the body are rewritten to the serving host, URLs in the response headers are not

4 participants