[Private Network Access] Store redirect info when redirect mode is manual
When a redirected navigation request needs a preflight because of
Private Network Access, the redirect_info is not properly stored in
CorsURLLoader. In FollowRedirect, the request URL and methods, etc will
be overwritten with the stored redirect_info which is currently empty,
causing the ERR_INVALID_URL in the associated bug.
This CL stores the redirect_info properly for this case.
The "missing cors headers" test cases are expected to fail because
kPrivateNetworkAccessForNavigationsWarningOnly is by default enabled so
requests actually succeeds
.
When kPrivateNetworkAccessForNavigations is disabled
(virtual/pna-navigations-disabled), the preflight aren't sent so we
expect failures too.
Bug: 327017904,327022946
Change-Id: I5631a2ba865c9a39dde7095888d7df24539194f2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5331430
Reviewed-by: Yifan Luo <lyf@chromium.org>
Reviewed-by: Adam Rice <ricea@chromium.org>
Commit-Queue: Jonathan Hao <phao@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1266894}
diff --git a/fetch/private-network-access/anchor.tentative.https.window.js b/fetch/private-network-access/anchor.tentative.https.window.js
index 4e860ad..f547386 100644
--- a/fetch/private-network-access/anchor.tentative.https.window.js
+++ b/fetch/private-network-access/anchor.tentative.https.window.js
@@ -149,6 +149,44 @@
expected: NavigationTestResult.SUCCESS,
}), "public to public: no preflight required.");
+subsetTestByKey(
+ 'from-public', promise_test_parallel,
+ t => anchorTest(t, {
+ source: {server: Server.HTTPS_PUBLIC},
+ target: {
+ server: Server.HTTPS_PUBLIC,
+ behavior: {
+ redirect: preflightUrl({
+ server: Server.HTTPS_PRIVATE,
+ behavior: {
+ preflight: PreflightBehavior.noCorsHeader(token()),
+ }
+ }),
+ }
+ },
+ expected: NavigationTestResult.FAILURE,
+ }),
+ 'public to public redirected to private: missing CORS headers.');
+
+subsetTestByKey(
+ 'from-public', promise_test_parallel,
+ t => anchorTest(t, {
+ source: {server: Server.HTTPS_PUBLIC},
+ target: {
+ server: Server.HTTPS_PUBLIC,
+ behavior: {
+ redirect: preflightUrl({
+ server: Server.HTTPS_PRIVATE,
+ behavior: {
+ preflight: PreflightBehavior.navigation(token()),
+ }
+ }),
+ }
+ },
+ expected: NavigationTestResult.SUCCESS,
+ }),
+ 'public to public to private: success.');
+
// The following tests verify that `CSP: treat-as-public-address` makes
// documents behave as if they had been served from a public IP address.
diff --git a/fetch/private-network-access/resources/support.sub.js b/fetch/private-network-access/resources/support.sub.js
index 46a9d9e..35f39b1 100644
--- a/fetch/private-network-access/resources/support.sub.js
+++ b/fetch/private-network-access/resources/support.sub.js
@@ -480,6 +480,13 @@
};
async function windowOpenTest(t, { source, target, expected }) {
+ if (target.behavior && target.behavior.redirect) {
+ target.behavior.redirect.searchParams.set('file', 'openee.html');
+ target.behavior.redirect.searchParams.set(
+ 'file-if-no-preflight-received',
+ 'no-preflight-received.html',
+ );
+ }
const targetUrl = preflightUrl(target);
targetUrl.searchParams.set("file", "openee.html");
targetUrl.searchParams.set(
@@ -507,6 +514,13 @@
}
async function windowOpenExistingTest(t, { source, target, expected }) {
+ if (target.behavior && target.behavior.redirect) {
+ target.behavior.redirect.searchParams.set('file', 'openee.html');
+ target.behavior.redirect.searchParams.set(
+ 'file-if-no-preflight-received',
+ 'no-preflight-received.html',
+ );
+ }
const targetUrl = preflightUrl(target);
targetUrl.searchParams.set("file", "openee.html");
targetUrl.searchParams.set(
@@ -535,6 +549,13 @@
}
async function anchorTest(t, { source, target, expected }) {
+ if (target.behavior && target.behavior.redirect) {
+ target.behavior.redirect.searchParams.set('file', 'openee.html');
+ target.behavior.redirect.searchParams.set(
+ 'file-if-no-preflight-received',
+ 'no-preflight-received.html',
+ );
+ }
const targetUrl = preflightUrl(target);
targetUrl.searchParams.set("file", "openee.html");
targetUrl.searchParams.set(
diff --git a/fetch/private-network-access/window-open-existing.tentative.https.window.js b/fetch/private-network-access/window-open-existing.tentative.https.window.js
index 6a2a624..565a211 100644
--- a/fetch/private-network-access/window-open-existing.tentative.https.window.js
+++ b/fetch/private-network-access/window-open-existing.tentative.https.window.js
@@ -167,6 +167,44 @@
}),
'public to public: no preflight required.');
+subsetTestByKey(
+ 'from-public', promise_test_parallel,
+ t => windowOpenExistingTest(t, {
+ source: {server: Server.HTTPS_PUBLIC},
+ target: {
+ server: Server.HTTPS_PUBLIC,
+ behavior: {
+ redirect: preflightUrl({
+ server: Server.HTTPS_PRIVATE,
+ behavior: {
+ preflight: PreflightBehavior.noCorsHeader(token()),
+ }
+ }),
+ }
+ },
+ expected: NavigationTestResult.FAILURE,
+ }),
+ 'public to public redirected to private: missing CORS headers.');
+
+subsetTestByKey(
+ 'from-public', promise_test_parallel,
+ t => windowOpenExistingTest(t, {
+ source: {server: Server.HTTPS_PUBLIC},
+ target: {
+ server: Server.HTTPS_PUBLIC,
+ behavior: {
+ redirect: preflightUrl({
+ server: Server.HTTPS_PRIVATE,
+ behavior: {
+ preflight: PreflightBehavior.navigation(token()),
+ }
+ }),
+ }
+ },
+ expected: NavigationTestResult.SUCCESS,
+ }),
+ 'public to public to private: success.');
+
// The following tests verify that `CSP: treat-as-public-address` makes
// documents behave as if they had been served from a public IP address.
diff --git a/fetch/private-network-access/window-open.tentative.https.window.js b/fetch/private-network-access/window-open.tentative.https.window.js
index 6793d1f..42d70af 100644
--- a/fetch/private-network-access/window-open.tentative.https.window.js
+++ b/fetch/private-network-access/window-open.tentative.https.window.js
@@ -149,6 +149,44 @@
expected: NavigationTestResult.SUCCESS,
}), "public to public: no preflight required.");
+subsetTestByKey(
+ 'from-public', promise_test_parallel,
+ t => windowOpenTest(t, {
+ source: {server: Server.HTTPS_PUBLIC},
+ target: {
+ server: Server.HTTPS_PUBLIC,
+ behavior: {
+ redirect: preflightUrl({
+ server: Server.HTTPS_PRIVATE,
+ behavior: {
+ preflight: PreflightBehavior.noCorsHeader(token()),
+ }
+ }),
+ }
+ },
+ expected: NavigationTestResult.FAILURE,
+ }),
+ 'public to public redirected to private: missing CORS headers.');
+
+subsetTestByKey(
+ 'from-public', promise_test_parallel,
+ t => windowOpenTest(t, {
+ source: {server: Server.HTTPS_PUBLIC},
+ target: {
+ server: Server.HTTPS_PUBLIC,
+ behavior: {
+ redirect: preflightUrl({
+ server: Server.HTTPS_PRIVATE,
+ behavior: {
+ preflight: PreflightBehavior.navigation(token()),
+ }
+ }),
+ }
+ },
+ expected: NavigationTestResult.SUCCESS,
+ }),
+ 'public to public to private: success.');
+
// The following tests verify that `CSP: treat-as-public-address` makes
// documents behave as if they had been served from a public IP address.