-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support credentials mode in <script type=webbundle>
The current <script>-based API doesn't allow to specify a credential mode, while <link>-based APIs allowed that by its `crossorigin` attribute. This is one of the gaps between two APIs. This CL supports credentials for <script type=webbundle>. Now <script type=webbundle> can have a `credentials` to specify a request's credentials mode, such as: <script type="webbundle"> { source: "subresources.wbn", credentials: "omit", resources: ["a.js", "b.js", "c.png"], } </script> Regarding 're-using webbundle resources', we also check an equality of credentials mode of two script elements, in addition to their bundle URLs so that we don't re-use webbundle resources wrongly. See [1] for details. The related spec and explainer are: - The spec issue is WICG/webpackage#692. - PR is WICG/webpackage#694, which was already merged. - Updataed Explainer: https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md#requests-mode-and-credentials-mode [1] https://docs.google.com/document/d/1q_SodTcLuwya4cXt1gIRaVrkiaBfwWyPvkY1fqRKkgM/edit?resourcekey=0-dqrFOGVCYsg8WRZ4RFgwuw#heading=h.mnfqu6560twe Bug: 1262005 Change-Id: I897e272962219ae10adf3dcd9c0c0e689b6c1d7b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3234563 Reviewed-by: Kunihiko Sakamoto <[email protected]> Reviewed-by: Takashi Toyoshima <[email protected]> Reviewed-by: Hiroshige Hayashizaki <[email protected]> Commit-Queue: Hayato Ito <[email protected]> Cr-Commit-Position: refs/heads/main@{#934410}
- Loading branch information
1 parent
4287b41
commit 590d697
Showing
7 changed files
with
266 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import os | ||
|
||
|
||
def main(request, response): | ||
origin = request.headers.get(b"origin") | ||
|
||
if origin is not None: | ||
response.headers.set(b"Access-Control-Allow-Origin", origin) | ||
response.headers.set(b"Access-Control-Allow-Methods", b"GET") | ||
response.headers.set(b"Access-Control-Allow-Credentials", b"true") | ||
|
||
headers = [ | ||
(b"Content-Type", b"application/webbundle"), | ||
(b"X-Content-Type-Options", b"nosniff"), | ||
] | ||
|
||
cookie = request.cookies.first(b"milk", None) | ||
if (cookie is not None) and cookie.value == b"1": | ||
if request.GET.get(b"bundle", None) == b"cross-origin": | ||
bundle = "./wbn/simple-cross-origin.wbn" | ||
else: | ||
bundle = "./wbn/subresource.wbn" | ||
with open( | ||
os.path.join(os.path.dirname(__file__), bundle), | ||
"rb", | ||
) as f: | ||
return (200, headers, f.read()) | ||
else: | ||
return (400, [], "") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"log": { | ||
"entries": [ | ||
{ | ||
"request": { | ||
"method": "GET", | ||
"url": "https://www1.web-platform.test:8444/web-bundle/resources/wbn/simple-cross-origin.txt", | ||
"headers": [] | ||
}, | ||
"response": { | ||
"status": 200, | ||
"headers": [ | ||
{ | ||
"name": "Content-type", | ||
"value": "text/plain" | ||
}, | ||
{ | ||
"name": "Access-Control-Allow-Origin", | ||
"value": "*" | ||
} | ||
], | ||
"content": { | ||
"text": "hello from simple-cross-origin.txt" | ||
} | ||
} | ||
} | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
151 changes: 151 additions & 0 deletions
151
web-bundle/subresource-loading/script-credentials.https.tentative.sub.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
<!DOCTYPE html> | ||
<title> | ||
Credentials in WebBundle subresource loading | ||
</title> | ||
<link | ||
rel="help" | ||
href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md#requests-mode-and-credentials-mode" | ||
/> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="../resources/test-helpers.js"></script> | ||
<body> | ||
<script> | ||
// In this wpt, we test a request's credential mode, which controls | ||
// whether UA sends a credential or not to fetch a bundle. | ||
|
||
// If UA sends a credential, check-cookie-and-return-{cross-oriigin}-bundle.py | ||
// returns a valid format webbundle. Then, a subresource fetch should be successful. | ||
// Otherwise, a subresource fetch should be rejected. | ||
|
||
window.TEST_WEB_BUNDLE_ELEMENT_TYPE = "script"; | ||
setup(() => { | ||
assert_true(HTMLScriptElement.supports("webbundle")); | ||
}); | ||
|
||
document.cookie = "milk=1; path=/"; | ||
|
||
// Make sure to set a cookie for a cross-origin domain from where a cross | ||
// origin bundle is served. | ||
const setCookiePromise = fetch( | ||
"https://{{domains[www1]}}:{{ports[https][0]}}/cookies/resources/set-cookie.py?name=milk&path=/web-bundle/resources/", | ||
{ | ||
mode: "no-cors", | ||
credentials: "include", | ||
} | ||
); | ||
|
||
const same_origin_bundle = "../resources/check-cookie-and-return-bundle.py"; | ||
const cross_origin_bundle = "https://{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/check-cookie-and-return-bundle.py?bundle=cross-origin"; | ||
|
||
const same_origin_bundle_subresource = "../resources/wbn/root.js"; | ||
const cross_origin_bundle_subresource = "https://{{domains[www1]}}:{{ports[https][0]}}/web-bundle/resources/wbn/simple-cross-origin.txt"; | ||
|
||
async function assertSubresourceCanBeFetched() { | ||
const response = await fetch(same_origin_bundle_subresource); | ||
const text = await response.text(); | ||
assert_equals(text, "export * from './submodule.js';\n"); | ||
} | ||
|
||
async function assertCrossOriginSubresourceCanBeFetched() { | ||
const response = await fetch(cross_origin_bundle_subresource); | ||
const text = await response.text(); | ||
assert_equals(text, "hello from simple-cross-origin.txt"); | ||
} | ||
|
||
function createScriptWebBundle(credentials) { | ||
const options = {}; | ||
if (credentials) { | ||
options.credentials = credentials; | ||
} | ||
return createWebBundleElement(same_origin_bundle, [same_origin_bundle_subresource], options); | ||
} | ||
|
||
function createScriptWebBundleCrossOrigin(credentials) { | ||
const options = {}; | ||
if (credentials) { | ||
options.credentials = credentials; | ||
} | ||
return createWebBundleElement(cross_origin_bundle, [cross_origin_bundle_subresource], options); | ||
} | ||
|
||
promise_test(async (t) => { | ||
const script = createScriptWebBundle(); | ||
document.body.append(script); | ||
t.add_cleanup(() => script.remove()); | ||
|
||
await assertSubresourceCanBeFetched(); | ||
}, "The default should send a credential to a same origin bundle"); | ||
|
||
promise_test(async (t) => { | ||
const script = createScriptWebBundle("invalid"); | ||
document.body.append(script); | ||
t.add_cleanup(() => script.remove()); | ||
|
||
await assertSubresourceCanBeFetched(); | ||
}, "An invalid value should send a credential to a same origin bundle"); | ||
|
||
promise_test(async (t) => { | ||
const script = createScriptWebBundle("omit"); | ||
document.body.append(script); | ||
t.add_cleanup(() => script.remove()); | ||
|
||
return promise_rejects_js(t, TypeError, fetch(same_origin_bundle_subresource)) | ||
}, "'omit' should not send a credential to a same origin bundle"); | ||
|
||
promise_test(async (t) => { | ||
const script = createScriptWebBundle("same-origin"); | ||
document.body.append(script); | ||
t.add_cleanup(() => script.remove()); | ||
|
||
await assertSubresourceCanBeFetched(); | ||
}, "'same-origin' should send a credential to a same origin bundle"); | ||
|
||
promise_test(async (t) => { | ||
const script = createScriptWebBundle("include"); | ||
document.body.append(script); | ||
t.add_cleanup(() => script.remove()); | ||
|
||
await assertSubresourceCanBeFetched(); | ||
}, "'include' should send a credential to a same origin bundle"); | ||
|
||
promise_test(async (t) => { | ||
await setCookiePromise; | ||
|
||
const script = createScriptWebBundleCrossOrigin("omit"); | ||
document.body.append(script); | ||
t.add_cleanup(() => script.remove()); | ||
|
||
return promise_rejects_js(t, TypeError, fetch(cross_origin_bundle_subresource)) | ||
}, "'omit' should not send a credential to a cross origin bundle"); | ||
|
||
promise_test(async (t) => { | ||
await setCookiePromise; | ||
|
||
const script = createScriptWebBundleCrossOrigin("same-origin"); | ||
document.body.append(script); | ||
t.add_cleanup(() => script.remove()); | ||
|
||
return promise_rejects_js(t, TypeError, fetch(cross_origin_bundle_subresource)) | ||
}, "'same-origin' should not send a credential to a cross origin bundle"); | ||
|
||
promise_test(async (t) => { | ||
await setCookiePromise; | ||
|
||
const script = createScriptWebBundleCrossOrigin("include"); | ||
document.body.append(script); | ||
t.add_cleanup(() => script.remove()); | ||
|
||
await assertCrossOriginSubresourceCanBeFetched(); | ||
}, "'include' should send a credential to a cross origin bundle"); | ||
|
||
|
||
promise_test(async (t) => { | ||
const script = createScriptWebBundleCrossOrigin("invalid"); | ||
document.body.append(script); | ||
t.add_cleanup(() => script.remove()); | ||
|
||
return promise_rejects_js(t, TypeError, fetch(cross_origin_bundle_subresource)) | ||
}, "An invalid value should not send a credential to a cross origin bundle"); | ||
</script> | ||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters