Commit cd40220a authored by Yutaka Hirano's avatar Yutaka Hirano Committed by Commit Bot

Fix as=fetch preload where preload is used before response arrives

[1] broke link rel="preload" as="fetch" handling for the case where
 - It's attached with XHR (not fetch()), and
 - The response body arrives after matching.

1: https://crrev.com/740fabd5a1a6868121315649aa760007c88a180f

Bug: 894819
Change-Id: I8d15639a4f63f41bc3ee1e0a704e1fb6510f7f56
Reviewed-on: https://chromium-review.googlesource.com/c/1476875Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Commit-Queue: Kinuko Yasuda <kinuko@chromium.org>
Auto-Submit: Yutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/master@{#633052}
parent f333c2fb
......@@ -271,12 +271,18 @@ void RawResource::ResponseReceived(const ResourceResponse& response) {
void RawResource::ResponseBodyReceived(
ResponseBodyLoaderDrainableInterface& body_loader) {
DCHECK_LE(Clients().size(), 1u);
RawResourceClient* client =
ResourceClientWalker<RawResourceClient>(Clients()).Next();
if (IsUnusedPreload()) {
// For preload, we want to store the body while dispatching
// onload and onerror events.
bytes_consumer_for_preload_ = MakeGarbageCollected<BufferingBytesConsumer>(
&body_loader.DrainAsBytesConsumer());
return;
}
if (!client) {
return;
}
......@@ -285,6 +291,14 @@ void RawResource::ResponseBodyReceived(
// The loading was initiated as a preload (hence UseStreamOnResponse is
// set), but this resource has been matched with a request without
// UseStreamOnResponse set.
auto* bytes_consumer_for_preload =
MakeGarbageCollected<BufferingBytesConsumer>(
&body_loader.DrainAsBytesConsumer());
auto* bytes_consumer_client =
MakeGarbageCollected<PreloadBytesConsumerClient>(
*bytes_consumer_for_preload, *this, *client);
bytes_consumer_for_preload->SetClient(bytes_consumer_client);
bytes_consumer_client->OnStateChange();
return;
}
......@@ -292,12 +306,7 @@ void RawResource::ResponseBodyReceived(
return;
}
BytesConsumer& bytes_consumer = body_loader.DrainAsBytesConsumer();
DCHECK_LE(Clients().size(), 1u);
ResourceClientWalker<RawResourceClient> w(Clients());
while (RawResourceClient* c = w.Next()) {
c->ResponseBodyReceived(this, bytes_consumer);
}
client->ResponseBodyReceived(this, body_loader.DrainAsBytesConsumer());
}
CachedMetadataHandler* RawResource::CreateCachedMetadataHandler(
......
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script src="/preload/resources/preload_helper.js"></script>
<script>
const dummyContent = '<?xml version="1.0" encoding="utf-8"?>\n<root>Text.me</root>\n';
promise_test(async (t) => {
const url = `resources/dummy.xml?token=${token()}`;
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'fetch';
link.href = url;
link.crossOrigin = 'anonymous';
document.head.appendChild(link);
const xhr = new XMLHttpRequest();
await new Promise((resolve, reject) => {
xhr.onloadend = resolve;
xhr.onloaderror = reject;
xhr.open('GET', url);
xhr.send();
});
verifyNumberOfResourceTimingEntries(url, 1);
assert_equals(xhr.status, 200);
assert_equals(xhr.responseText, dummyContent);
}, 'Make an XHR request immediately after creating link rel=preload.');
promise_test(async (t) => {
const url = `resources/dummy.xml?token=${token()}`;
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'fetch';
link.href = url;
link.crossOrigin = 'anonymous';
await new Promise((resolve, reject) => {
link.addEventListener('load', resolve, {once: true});
link.addEventListener('error', reject, {once: true});
document.head.appendChild(link);
});
const xhr = new XMLHttpRequest();
await new Promise((resolve, reject) => {
xhr.onloadend = resolve;
xhr.onloaderror = reject;
xhr.open('GET', url);
xhr.send();
});
verifyNumberOfResourceTimingEntries(url, 1);
assert_equals(xhr.status, 200);
assert_equals(xhr.responseText, dummyContent);
}, 'Make an XHR request after loading link rel=preload.');
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment