Commit 4897b675 authored by Ben Kelly's avatar Ben Kelly Committed by Commit Bot

CacheStorage: Set the Response mime type based on stored content-header.

Previously the Response mime type was never set when reading from a
Cache.  This resulted in empty string blob.type values and could also
prevent code cache from being generated if a script Response was put
back into a Cache.

This CL makes us at least generate a mime type from the current
content-type header.  This is a partial solution since the mime type
should technically be frozen at initial Response construction time
even if the content-type header is later changed.  To support that we
will need to explicitly store a mime type on disk in the cache.  This
will be done later in crbug.com/938939.

Bug: 937963,938939
Change-Id: Iabfe3909ff35957501ef33132af2a0c1f70c5c94
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1506213
Commit-Queue: Ben Kelly <wanderview@chromium.org>
Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarHiroshige Hayashizaki <hiroshige@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638581}
parent 72958b29
......@@ -97,6 +97,14 @@ FetchResponseData* CreateFetchResponseDataFromFetchAPIResponse(
for (const auto& header : fetch_api_response.headers)
response->HeaderList()->Append(header.key, header.value);
// TODO(wanderview): This sets the mime type of the Response based on the
// current headers. This should be correct for most cases, but technically
// the mime type should really be frozen at the initial Response
// construction. We should plumb the value through the cache_storage
// persistence layer and include the explicit mime type in FetchAPIResponse
// to set here. See: crbug.com/938939
response->SetMIMEType(response->HeaderList()->ExtractMIMEType());
if (fetch_api_response.blob) {
response->ReplaceBodyStreamBuffer(MakeGarbageCollected<BodyStreamBuffer>(
script_state,
......
......@@ -356,4 +356,62 @@ cache_test(async (cache) => {
assert_equals(headers.get('set-cookie'), null);
}, 'cors-exposed header should be stored correctly.');
cache_test(async (cache) => {
// A URL that should load a resource with a known mime type.
const url = '/service-workers/cache-storage/resources/blank.html';
const expected_mime_type = 'text/html';
// Verify we get the expected mime type from the network. Note,
// we cannot use an exact match here since some browsers append
// character encoding information to the blob.type value.
const net_response = await fetch(url);
const net_mime_type = (await net_response.blob()).type;
assert_true(net_mime_type.includes(expected_mime_type),
'network response should include the expected mime type');
// Verify we get the exact same mime type when reading the same
// URL resource back out of the cache.
await cache.add(url);
const cache_response = await cache.match(url);
const cache_mime_type = (await cache_response.blob()).type;
assert_equals(cache_mime_type, net_mime_type,
'network and cache response mime types should match');
}, 'MIME type should be set from content-header correctly.');
cache_test(async (cache) => {
const url = '/dummy';
const original_type = 'text/html';
const init_with_headers = {
headers: {
'content-type': original_type
}
}
// Verify constructing a synthetic response with a content-type header
// gets the correct mime type.
const response = new Response('hello world', init_with_headers);
const original_response_type = (await response.blob()).type;
assert_true(original_response_type.includes(original_type),
'original response should include the expected mime type');
// Verify overwriting the content-type header does not change the mime
// type. It should be fixed at Response construction time.
const overwritten_response = new Response('hello world', init_with_headers);
overwritten_response.headers.set('content-type', 'text/plain');
const overwritten_response_type = (await overwritten_response.blob()).type;
assert_equals(overwritten_response_type, original_response_type,
'original and overwritten response mime types should match');
// Verify the Response read from Cache uses the original mime type
// computed when it was first constructed.
const tmp = new Response('hello world', init_with_headers);
tmp.headers.set('content-type', 'text/plain');
await cache.put(url, tmp);
const cache_response = await cache.match(url);
const cache_mime_type = (await cache_response.blob()).type;
assert_equals(cache_mime_type, original_response_type,
'original and cached overwritten response mime types ' +
'should match');
}, 'MIME type should be frozen at response construction.');
done();
This is a testharness.js-based test.
PASS Cache.match
PASS Cache.match with no matching entries
PASS Cache.match with URL
PASS Cache.match with Request
PASS Cache.match with multiple cache hits
PASS Cache.match with new Request
PASS Cache.match with HEAD
PASS Cache.match with ignoreSearch option (request with no search parameters)
PASS Cache.match with ignoreSearch option (request with search parameter)
PASS Cache.match supports ignoreMethod
PASS Cache.match supports ignoreVary
PASS Cache.match does not support cacheName option
PASS Cache.match with URL containing fragment
PASS Cache.match with string fragment "http" as query
PASS Cache.match with responses containing "Vary" header
PASS Cache.match with Request and Response objects with different URLs
PASS Cache.match invoked multiple times for the same Request/Response
PASS Cache.match blob should be sliceable
PASS Cache.match with POST Request
PASS Cache.match with a non-2xx Response
PASS Cache.match with a network error Response
PASS Cache produces large Responses that can be cloned and read correctly.
PASS cors-exposed header should be stored correctly.
PASS MIME type should be set from content-header correctly.
FAIL MIME type should be frozen at response construction. assert_equals: original and cached overwritten response mime types should match expected "text/html" but got "text/plain"
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Cache.match with no matching entries
PASS Cache.match with URL
PASS Cache.match with Request
PASS Cache.match with multiple cache hits
PASS Cache.match with new Request
PASS Cache.match with HEAD
PASS Cache.match with ignoreSearch option (request with no search parameters)
PASS Cache.match with ignoreSearch option (request with search parameter)
PASS Cache.match supports ignoreMethod
PASS Cache.match supports ignoreVary
PASS Cache.match does not support cacheName option
PASS Cache.match with URL containing fragment
PASS Cache.match with string fragment "http" as query
PASS Cache.match with responses containing "Vary" header
PASS Cache.match with Request and Response objects with different URLs
PASS Cache.match invoked multiple times for the same Request/Response
PASS Cache.match blob should be sliceable
PASS Cache.match with POST Request
PASS Cache.match with a non-2xx Response
PASS Cache.match with a network error Response
PASS Cache produces large Responses that can be cloned and read correctly.
PASS cors-exposed header should be stored correctly.
PASS MIME type should be set from content-header correctly.
FAIL MIME type should be frozen at response construction. assert_equals: original and cached overwritten response mime types should match expected "text/html" but got "text/plain"
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Cache.match with no matching entries
PASS Cache.match with URL
PASS Cache.match with Request
PASS Cache.match with multiple cache hits
PASS Cache.match with new Request
PASS Cache.match with HEAD
PASS Cache.match with ignoreSearch option (request with no search parameters)
PASS Cache.match with ignoreSearch option (request with search parameter)
PASS Cache.match supports ignoreMethod
PASS Cache.match supports ignoreVary
PASS Cache.match does not support cacheName option
PASS Cache.match with URL containing fragment
PASS Cache.match with string fragment "http" as query
PASS Cache.match with responses containing "Vary" header
PASS Cache.match with Request and Response objects with different URLs
PASS Cache.match invoked multiple times for the same Request/Response
PASS Cache.match blob should be sliceable
PASS Cache.match with POST Request
PASS Cache.match with a non-2xx Response
PASS Cache.match with a network error Response
PASS Cache produces large Responses that can be cloned and read correctly.
PASS cors-exposed header should be stored correctly.
PASS MIME type should be set from content-header correctly.
FAIL MIME type should be frozen at response construction. assert_equals: original and cached overwritten response mime types should match expected "text/html" but got "text/plain"
Harness: the test ran to completion.
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