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: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: Hiroshige Hayashizaki <hiroshige@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638581}
diff --git a/service-workers/cache-storage/script-tests/cache-match.js b/service-workers/cache-storage/script-tests/cache-match.js
index b2b731c..8bf7fda 100644
--- a/service-workers/cache-storage/script-tests/cache-match.js
+++ b/service-workers/cache-storage/script-tests/cache-match.js
@@ -356,4 +356,62 @@
     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();