Title: [207086] trunk
Revision
207086
Author
commit-qu...@webkit.org
Date
2016-10-11 03:53:22 -0700 (Tue, 11 Oct 2016)

Log Message

[Fetch API] Support Request cache mode
https://bugs.webkit.org/show_bug.cgi?id=162281

Patch by Youenn Fablet <you...@apple.com> on 2016-10-11
Reviewed by Alex Christensen.

LayoutTests/imported/w3c:

* web-platform-tests/fetch/api/request/request-cache-expected.txt: Rebasing test now that more tests are passing.
* web-platform-tests/fetch/api/request/request-error-expected.txt:
* web-platform-tests/fetch/api/request/request-error.html: Adding test to ensure only-if-cached is used with same-origin fetch mode.

Source/WebCore:

Covered by updated test.

Added support for only-if-cached mode at Request level.

Added support for cache mode at CachedResourceLoader, by setting HTTP headers and ResourceRequest cache policy
based on https://fetch.spec.whatwg.org/#concept-request-cache-mode and https://fetch.spec.whatwg.org/#http-network-or-cache-fetch.

Disabled default cache policy computation (done in FrameLoader) when cache mode is different from the default.
Activated no-store cache mode for EventSource as per https://html.spec.whatwg.org/#the-eventsource-interface.

* Modules/fetch/FetchRequest.cpp:
(WebCore::setCache): Adding support for only-if-cached.
(WebCore::buildOptions): Throw if only-if-cached and fetch mode is not same-origin.
* loader/FetchOptions.h: Adding support for only-if-cached.
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::defaultRequestCachingPolicy): Introduced to ease readability.
(WebCore::FrameLoader::addExtraFieldsToRequest): Updating cache policy only if request has the default cache policy.
This allows bypassing the default behavior for fetch cache mode different from "default".
* loader/FrameLoader.h:
* loader/cache/CachedResourceLoader.cpp:
(WebCore::updateRequestAccordingCacheMode): Introduced to set headers and request cache policy according fetch cache mode.
(WebCore::CachedResourceLoader::requestResource):
(WebCore::CachedResourceLoader::loadResource):
(WebCore::CachedResourceLoader::determineRevalidationPolicy): Ensure bypassing the memory cache in no-store and reload cases.
We reload in case of cache mode=reload to refresh the meory cache entry.
* loader/cache/CachedResourceRequest.h:
(WebCore::CachedResourceRequest::setCacheModeToNoStore):
* page/EventSource.cpp:
(WebCore::EventSource::connect): Use no-store cache mode as per https://html.spec.whatwg.org/#the-eventsource-interface.
* platform/network/HTTPHeaderMap.cpp:
(WebCore::HTTPHeaderMap::addIfNotPresent): Helper routine.
* platform/network/HTTPHeaderMap.h:
* platform/network/HTTPHeaderValues.cpp:
* platform/network/HTTPHeaderValues.h:
* platform/network/ResourceRequestBase.cpp:
(WebCore::ResourceRequestBase::addHTTPHeaderFieldIfNotPresent):
(WebCore::ResourceRequestBase::addHTTPHeaderField):
(WebCore::ResourceRequestBase::hasHTTPHeaderField):
* platform/network/ResourceRequestBase.h:

LayoutTests:

Activating request-cache.html tests for WK1, but not yet for WK2.

* TestExpectations:
* platform/mac/TestExpectations:
* platform/wk2/TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (207085 => 207086)


--- trunk/LayoutTests/ChangeLog	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/ChangeLog	2016-10-11 10:53:22 UTC (rev 207086)
@@ -1,3 +1,16 @@
+2016-10-11  Youenn Fablet  <you...@apple.com>
+
+        [Fetch API] Support Request cache mode
+        https://bugs.webkit.org/show_bug.cgi?id=162281
+
+        Reviewed by Alex Christensen.
+
+        Activating request-cache.html tests for WK1, but not yet for WK2.
+
+        * TestExpectations:
+        * platform/mac/TestExpectations:
+        * platform/wk2/TestExpectations:
+
 2016-10-11  Chris Dumez  <cdu...@apple.com>
 
         Update IDBVersionChangeEvent to stop using legacy [ConstructorTemplate=Event]

Modified: trunk/LayoutTests/TestExpectations (207085 => 207086)


--- trunk/LayoutTests/TestExpectations	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/TestExpectations	2016-10-11 10:53:22 UTC (rev 207086)
@@ -282,8 +282,6 @@
 # Failing assertion with dynamic message
 imported/w3c/web-platform-tests/XMLHttpRequest/responsexml-document-properties.htm [ Failure ]
 
-imported/w3c/web-platform-tests/fetch/api/request/request-cache.html [ Skip ]
-
 webkit.org/b/161176 [ Debug ] imported/w3c/web-platform-tests/url/url-setters.html [ Skip ]
 
 webkit.org/b/157068 imported/w3c/web-platform-tests/fetch/nosniff/importscripts.html [ Skip ]

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (207085 => 207086)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2016-10-11 10:53:22 UTC (rev 207086)
@@ -1,3 +1,14 @@
+2016-10-11  Youenn Fablet  <you...@apple.com>
+
+        [Fetch API] Support Request cache mode
+        https://bugs.webkit.org/show_bug.cgi?id=162281
+
+        Reviewed by Alex Christensen.
+
+        * web-platform-tests/fetch/api/request/request-cache-expected.txt: Rebasing test now that more tests are passing.
+        * web-platform-tests/fetch/api/request/request-error-expected.txt:
+        * web-platform-tests/fetch/api/request/request-error.html: Adding test to ensure only-if-cached is used with same-origin fetch mode.
+
 2016-10-10  Chris Dumez  <cdu...@apple.com>
 
         Add support for languagechange event

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-cache-expected.txt (207085 => 207086)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-cache-expected.txt	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-cache-expected.txt	2016-10-11 10:53:22 UTC (rev 207086)
@@ -5,10 +5,10 @@
 PASS RequestCache "default" mode checks the cache for previously cached content and avoids going to the network if a fresh response exists with date and fresh response 
 PASS RequestCache "no-cache" mode revalidates stale responses found in the cache with Etag and stale response 
 PASS RequestCache "no-cache" mode revalidates stale responses found in the cache with date and stale response 
-FAIL RequestCache "no-cache" mode revalidates fresh responses found in the cache with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "no-cache" mode revalidates fresh responses found in the cache with date and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for stale responses with Etag and stale response assert_equals: expected 1 but got 2
-FAIL RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for stale responses with date and stale response assert_equals: expected 1 but got 2
+PASS RequestCache "no-cache" mode revalidates fresh responses found in the cache with Etag and fresh response 
+PASS RequestCache "no-cache" mode revalidates fresh responses found in the cache with date and fresh response 
+PASS RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for stale responses with Etag and stale response 
+PASS RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for stale responses with date and stale response 
 PASS RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for fresh responses with Etag and fresh response 
 PASS RequestCache "force-cache" mode checks the cache for previously cached content and avoid revalidation for fresh responses with date and fresh response 
 PASS RequestCache "force-cache" mode checks the cache for previously cached content and goes to the network if a cached response is not found with Etag and stale response 
@@ -23,10 +23,10 @@
 PASS RequestCache "force-cache" stores the response in the cache if it goes to the network with date and stale response 
 PASS RequestCache "force-cache" stores the response in the cache if it goes to the network with Etag and fresh response 
 PASS RequestCache "force-cache" stores the response in the cache if it goes to the network with date and fresh response 
-FAIL RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for stale responses with Etag and stale response promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for stale responses with date and stale response promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for fresh responses with Etag and fresh response promise_test: Unhandled rejection with value: object "TypeError: Type error"
-FAIL RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for fresh responses with date and fresh response promise_test: Unhandled rejection with value: object "TypeError: Type error"
+PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for stale responses with Etag and stale response 
+PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for stale responses with date and stale response 
+PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for fresh responses with Etag and fresh response 
+PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for fresh responses with date and fresh response 
 PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and does not go to the network if a cached response is not found with Etag and fresh response 
 PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and does not go to the network if a cached response is not found with date and fresh response 
 FAIL RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content with Etag and fresh response promise_test: Unhandled rejection with value: object "TypeError: Type error"
@@ -37,14 +37,14 @@
 PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with date and fresh response 
 PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with Etag and stale response 
 PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with date and stale response 
-FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.04196530864700354\""
-FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response assert_equals: expected (undefined) undefined but got (string) "Fri, 09 Sep 2016 08:49:10 GMT"
-FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with date and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "no-store" mode does not store the response in the cache with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.12846053184726147\""
-FAIL RequestCache "no-store" mode does not store the response in the cache with date and stale response assert_equals: expected (undefined) undefined but got (string) "Fri, 09 Sep 2016 08:49:10 GMT"
-FAIL RequestCache "no-store" mode does not store the response in the cache with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "no-store" mode does not store the response in the cache with date and fresh response assert_equals: expected 2 but got 1
+PASS RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response 
+PASS RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response 
+PASS RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response 
+PASS RequestCache "no-store" mode does not check the cache for previously cached content and goes to the network regardless with date and fresh response 
+PASS RequestCache "no-store" mode does not store the response in the cache with Etag and stale response 
+PASS RequestCache "no-store" mode does not store the response in the cache with date and stale response 
+PASS RequestCache "no-store" mode does not store the response in the cache with Etag and fresh response 
+PASS RequestCache "no-store" mode does not store the response in the cache with date and fresh response 
 PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with Etag and stale response 
 PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with date and stale response 
 PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with Etag and fresh response 
@@ -51,7 +51,7 @@
 PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with date and fresh response 
 PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with Etag and stale response 
 PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with date and stale response 
-FAIL RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with Etag and fresh response assert_equals: expected 2 but got 1
+PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with Etag and fresh response 
 PASS RequestCache "default" mode with an If-Modified-Since header is treated similarly to "no-store" with date and fresh response 
 PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with Etag and stale response 
 PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with date and stale response 
@@ -59,8 +59,8 @@
 PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with date and fresh response 
 PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with Etag and stale response 
 PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with date and stale response 
-FAIL RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with date and fresh response assert_equals: expected 2 but got 1
+PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with Etag and fresh response 
+PASS RequestCache "default" mode with an If-None-Match header is treated similarly to "no-store" with date and fresh response 
 PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with Etag and stale response 
 PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with date and stale response 
 PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with Etag and fresh response 
@@ -67,8 +67,8 @@
 PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with date and fresh response 
 PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with Etag and stale response 
 PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with date and stale response 
-FAIL RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with date and fresh response assert_equals: expected 2 but got 1
+PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with Etag and fresh response 
+PASS RequestCache "default" mode with an If-Unmodified-Since header is treated similarly to "no-store" with date and fresh response 
 PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with Etag and stale response 
 PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with date and stale response 
 PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with Etag and fresh response 
@@ -75,8 +75,8 @@
 PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with date and fresh response 
 PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with Etag and stale response 
 PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with date and stale response 
-FAIL RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with date and fresh response assert_equals: expected 2 but got 1
+PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with Etag and fresh response 
+PASS RequestCache "default" mode with an If-Match header is treated similarly to "no-store" with date and fresh response 
 PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with Etag and stale response 
 PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with date and stale response 
 PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with Etag and fresh response 
@@ -83,22 +83,22 @@
 PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with date and fresh response 
 PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with Etag and stale response 
 PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with date and stale response 
-FAIL RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with date and fresh response assert_equals: expected 2 but got 1
+PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with Etag and fresh response 
+PASS RequestCache "default" mode with an If-Range header is treated similarly to "no-store" with date and fresh response 
 PASS Responses with the "Cache-Control: no-store" header are not stored in the cache with Etag and stale response 
 PASS Responses with the "Cache-Control: no-store" header are not stored in the cache with date and stale response 
 PASS Responses with the "Cache-Control: no-store" header are not stored in the cache with Etag and fresh response 
 PASS Responses with the "Cache-Control: no-store" header are not stored in the cache with date and fresh response 
-FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.7894894845056666\""
-FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response assert_equals: expected (undefined) undefined but got (string) "Fri, 09 Sep 2016 08:49:10 GMT"
-FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with date and fresh response assert_equals: expected 2 but got 1
+PASS RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with Etag and stale response 
+PASS RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with date and stale response 
+PASS RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with Etag and fresh response 
+PASS RequestCache "reload" mode does not check the cache for previously cached content and goes to the network regardless with date and fresh response 
 PASS RequestCache "reload" mode does store the response in the cache with Etag and stale response 
 PASS RequestCache "reload" mode does store the response in the cache with date and stale response 
-PASS RequestCache "reload" mode does store the response in the cache with Etag and fresh response 
-PASS RequestCache "reload" mode does store the response in the cache with date and fresh response 
-FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with Etag and stale response assert_equals: expected (undefined) undefined but got (string) "\"0.49509960167414313\""
-FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with date and stale response assert_equals: expected (undefined) undefined but got (string) "Fri, 09 Sep 2016 08:49:10 GMT"
-FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with Etag and fresh response assert_equals: expected 2 but got 1
-FAIL RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with date and fresh response assert_equals: expected 2 but got 1
+FAIL RequestCache "reload" mode does store the response in the cache with Etag and fresh response assert_equals: expected 1 but got 2
+FAIL RequestCache "reload" mode does store the response in the cache with date and fresh response assert_equals: expected 1 but got 2
+PASS RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with Etag and stale response 
+PASS RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with date and stale response 
+PASS RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with Etag and fresh response 
+PASS RequestCache "reload" mode does store the response in the cache even if a previous response is already stored with date and fresh response 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error-expected.txt (207085 => 207086)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error-expected.txt	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error-expected.txt	2016-10-11 10:53:22 UTC (rev 207086)
@@ -19,4 +19,8 @@
 PASS Bad credentials init parameter value 
 PASS Bad cache init parameter value 
 PASS Bad redirect init parameter value 
+PASS Request with cache mode: only-if-cached and fetch mode: same-origin 
+PASS Request with cache mode: only-if-cached and fetch mode: cors 
+PASS Request with cache mode: only-if-cached and fetch mode: no-cors 
+PASS Request should not get its content-type from the init request if init headers are provided 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error.html (207085 => 207086)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error.html	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-error.html	2016-10-11 10:53:22 UTC (rev 207086)
@@ -105,6 +105,28 @@
           assert_throws(new TypeError(), function() { new Request("", options); });
         },"Bad " + parameter +" init parameter value");
       });
+
+      function testOnlyIfCachedMode(fetchMode, ok) {
+        test(function() {
+          var options = {"cache": "only-if-cached", "mode": fetchMode};
+          if (ok)
+            new Request("test", options);
+          else
+            assert_throws(new TypeError(), function() { new Request("test", options); });
+        }, "Request with cache mode: only-if-cached and fetch mode: " + fetchMode);
+      }
+      testOnlyIfCachedMode("same-origin", true);
+      testOnlyIfCachedMode("cors", false);
+      testOnlyIfCachedMode("no-cors", false);
+
+      test(function() {
+        var initialHeaders = new Headers([["Content-Type", "potato"]]);
+        var initialRequest = new Request("", {"headers" : initialHeaders});
+        var headers = new Headers([]);
+        var request = new Request(initialRequest, {"headers" : headers});
+        assert_false(request.headers.has("Content-Type"));
+      }, "Request should not get its content-type from the init request if init headers are provided");
+
     </script>
   </body>
 </html>

Modified: trunk/LayoutTests/platform/mac/TestExpectations (207085 => 207086)


--- trunk/LayoutTests/platform/mac/TestExpectations	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/platform/mac/TestExpectations	2016-10-11 10:53:22 UTC (rev 207086)
@@ -1403,8 +1403,6 @@
 # See also https://bugs.webkit.org/show_bug.cgi?id=162494
 webkit.org/b/151287 [ ElCapitan+ ] media/controls/inline-elements-dropoff-order.html [ Failure ]
 
-webkit.org/b/159683 imported/w3c/web-platform-tests/fetch/api/request/request-cache.html [ Pass Failure ]
-
 webkit.org/b/158500 storage/indexeddb/database-close-private.html [ Pass Failure ]
 
 webkit.org/b/163122 imported/blink/storage/indexeddb/blob-valid-after-deletion.html [ Pass Timeout ]

Modified: trunk/LayoutTests/platform/wk2/TestExpectations (207085 => 207086)


--- trunk/LayoutTests/platform/wk2/TestExpectations	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/LayoutTests/platform/wk2/TestExpectations	2016-10-11 10:53:22 UTC (rev 207086)
@@ -684,6 +684,9 @@
 # DumpRenderTree does not implement setWillSendRequestHTTPBody
 http/tests/misc/will-send-request-with-client-provided-http-body.html [ Pass ]
 
+# bug 162281
+imported/w3c/web-platform-tests/fetch/api/request/request-cache.html [ Skip ]
+
 ### END OF (5) Progressions, expected successes that are expected failures in WebKit1.
 ########################################
 

Modified: trunk/Source/WebCore/ChangeLog (207085 => 207086)


--- trunk/Source/WebCore/ChangeLog	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/ChangeLog	2016-10-11 10:53:22 UTC (rev 207086)
@@ -1,3 +1,50 @@
+2016-10-11  Youenn Fablet  <you...@apple.com>
+
+        [Fetch API] Support Request cache mode
+        https://bugs.webkit.org/show_bug.cgi?id=162281
+
+        Reviewed by Alex Christensen.
+
+        Covered by updated test.
+
+        Added support for only-if-cached mode at Request level.
+
+        Added support for cache mode at CachedResourceLoader, by setting HTTP headers and ResourceRequest cache policy
+        based on https://fetch.spec.whatwg.org/#concept-request-cache-mode and https://fetch.spec.whatwg.org/#http-network-or-cache-fetch.
+
+        Disabled default cache policy computation (done in FrameLoader) when cache mode is different from the default.
+        Activated no-store cache mode for EventSource as per https://html.spec.whatwg.org/#the-eventsource-interface.
+
+        * Modules/fetch/FetchRequest.cpp:
+        (WebCore::setCache): Adding support for only-if-cached.
+        (WebCore::buildOptions): Throw if only-if-cached and fetch mode is not same-origin.
+        * loader/FetchOptions.h: Adding support for only-if-cached.
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::defaultRequestCachingPolicy): Introduced to ease readability.
+        (WebCore::FrameLoader::addExtraFieldsToRequest): Updating cache policy only if request has the default cache policy.
+        This allows bypassing the default behavior for fetch cache mode different from "default".
+        * loader/FrameLoader.h:
+        * loader/cache/CachedResourceLoader.cpp:
+        (WebCore::updateRequestAccordingCacheMode): Introduced to set headers and request cache policy according fetch cache mode.
+        (WebCore::CachedResourceLoader::requestResource):
+        (WebCore::CachedResourceLoader::loadResource):
+        (WebCore::CachedResourceLoader::determineRevalidationPolicy): Ensure bypassing the memory cache in no-store and reload cases.
+        We reload in case of cache mode=reload to refresh the meory cache entry.
+        * loader/cache/CachedResourceRequest.h:
+        (WebCore::CachedResourceRequest::setCacheModeToNoStore):
+        * page/EventSource.cpp:
+        (WebCore::EventSource::connect): Use no-store cache mode as per https://html.spec.whatwg.org/#the-eventsource-interface.
+        * platform/network/HTTPHeaderMap.cpp:
+        (WebCore::HTTPHeaderMap::addIfNotPresent): Helper routine.
+        * platform/network/HTTPHeaderMap.h:
+        * platform/network/HTTPHeaderValues.cpp:
+        * platform/network/HTTPHeaderValues.h:
+        * platform/network/ResourceRequestBase.cpp:
+        (WebCore::ResourceRequestBase::addHTTPHeaderFieldIfNotPresent):
+        (WebCore::ResourceRequestBase::addHTTPHeaderField):
+        (WebCore::ResourceRequestBase::hasHTTPHeaderField):
+        * platform/network/ResourceRequestBase.h:
+
 2016-10-10  Antti Koivisto  <an...@apple.com>
 
         Stop copying author shadow pseudo rules into shadow tree style resolver

Modified: trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp (207085 => 207086)


--- trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/Modules/fetch/FetchRequest.cpp	2016-10-11 10:53:22 UTC (rev 207086)
@@ -98,6 +98,8 @@
         options.cache = FetchOptions::Cache::NoCache;
     else if (cache == "force-cache")
         options.cache = FetchOptions::Cache::ForceCache;
+    else if (cache == "only-if-cached")
+        options.cache = FetchOptions::Cache::OnlyIfCached;
     else
         return Exception { TypeError, ASCIILiteral("Bad cache mode value.") };
     return Nullopt;
@@ -195,6 +197,9 @@
             return exception;
     }
 
+    if (request.options.cache == FetchOptions::Cache::OnlyIfCached && request.options.mode != FetchOptions::Mode::SameOrigin)
+        return Exception { TypeError, ASCIILiteral("only-if-cached cache option requires fetch mode to be same-origin.")  };
+
     if (init.get("redirect", value)) {
         exception = setRedirect(request.options, value);
         if (exception)

Modified: trunk/Source/WebCore/loader/FetchOptions.h (207085 => 207086)


--- trunk/Source/WebCore/loader/FetchOptions.h	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/FetchOptions.h	2016-10-11 10:53:22 UTC (rev 207086)
@@ -43,7 +43,7 @@
     enum class Credentials { Omit, SameOrigin, Include };
     Credentials credentials { Credentials::Omit };
 
-    enum class Cache { Default, NoStore, Reload, NoCache, ForceCache };
+    enum class Cache { Default, NoStore, Reload, NoCache, ForceCache, OnlyIfCached };
     Cache cache { Cache::Default };
 
     enum class Redirect { Follow, Error, Manual };

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (207085 => 207086)


--- trunk/Source/WebCore/loader/FrameLoader.cpp	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp	2016-10-11 10:53:22 UTC (rev 207086)
@@ -2562,36 +2562,14 @@
     addHTTPUpgradeInsecureRequestsIfNeeded(request);
 }
 
-void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadType loadType, bool mainResource)
+ResourceRequestCachePolicy FrameLoader::defaultRequestCachingPolicy(const ResourceRequest& request, FrameLoadType loadType, bool isMainResource)
 {
-    Page* page = frame().page();
-    bool cachingDisabled = page && page->isResourceCachingDisabled();
-
-    if (cachingDisabled)
-        request.setCachePolicy(ReloadIgnoringCacheData);
-
-    // Don't set the cookie policy URL if it's already been set.
-    // But make sure to set it on all requests regardless of protocol, as it has significance beyond the cookie policy (<rdar://problem/6616664>).
-    if (request.firstPartyForCookies().isEmpty()) {
-        if (mainResource && m_frame.isMainFrame())
-            request.setFirstPartyForCookies(request.url());
-        else if (Document* document = m_frame.document())
-            request.setFirstPartyForCookies(document->firstPartyForCookies());
-    }
-
-    // The remaining modifications are only necessary for HTTP and HTTPS.
-    if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily())
-        return;
-
-    applyUserAgent(request);
-
-    if (cachingDisabled) {
-        // Cache policy was already set above in the non-HTTP-specific code.
-        loadType = FrameLoadType::ReloadFromOrigin;
-    } else if (!mainResource) {
+    if (m_overrideCachePolicyForTesting)
+        return m_overrideCachePolicyForTesting.value();
+    if (!isMainResource) {
         if (request.isConditional())
-            request.setCachePolicy(ReloadIgnoringCacheData);
-        else if (documentLoader()->isLoadingInAPISense()) {
+            return ReloadIgnoringCacheData;
+        if (documentLoader()->isLoadingInAPISense()) {
             // If we inherit cache policy from a main resource, we use the DocumentLoader's
             // original request cache policy for two reasons:
             // 1. For POST requests, we mutate the cache policy for the main resource,
@@ -2602,22 +2580,41 @@
             ResourceRequestCachePolicy mainDocumentOriginalCachePolicy = documentLoader()->originalRequest().cachePolicy();
             // Back-forward navigations try to load main resource from cache only to avoid re-submitting form data, and start over (with a warning dialog) if that fails.
             // This policy is set on initial request too, but should not be inherited.
-            ResourceRequestCachePolicy subresourceCachePolicy = (mainDocumentOriginalCachePolicy == ReturnCacheDataDontLoad) ? ReturnCacheDataElseLoad : mainDocumentOriginalCachePolicy;
-            request.setCachePolicy(subresourceCachePolicy);
-        } else
-            request.setCachePolicy(UseProtocolCachePolicy);
-
+            return (mainDocumentOriginalCachePolicy == ReturnCacheDataDontLoad) ? ReturnCacheDataElseLoad : mainDocumentOriginalCachePolicy;
+        }
     // FIXME: Other FrameLoader functions have duplicated code for setting cache policy of main request when reloading.
     // It seems better to manage it explicitly than to hide the logic inside addExtraFieldsToRequest().
     } else if (loadType == FrameLoadType::Reload || loadType == FrameLoadType::ReloadFromOrigin || request.isConditional())
+        return ReloadIgnoringCacheData;
+
+    return UseProtocolCachePolicy;
+}
+
+void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadType loadType, bool isMainResource)
+{
+    // Don't set the cookie policy URL if it's already been set.
+    // But make sure to set it on all requests regardless of protocol, as it has significance beyond the cookie policy (<rdar://problem/6616664>).
+    if (request.firstPartyForCookies().isEmpty()) {
+        if (isMainResource && m_frame.isMainFrame())
+            request.setFirstPartyForCookies(request.url());
+        else if (Document* document = m_frame.document())
+            request.setFirstPartyForCookies(document->firstPartyForCookies());
+    }
+
+    Page* page = frame().page();
+    bool hasSpecificCachePolicy = request.cachePolicy() != UseProtocolCachePolicy;
+
+    if (page && page->isResourceCachingDisabled()) {
         request.setCachePolicy(ReloadIgnoringCacheData);
+        loadType = FrameLoadType::ReloadFromOrigin;
+    } else if (!hasSpecificCachePolicy)
+        request.setCachePolicy(defaultRequestCachingPolicy(request, loadType, isMainResource));
 
-    if (m_overrideCachePolicyForTesting)
-        request.setCachePolicy(m_overrideCachePolicyForTesting.value());
-    if (m_overrideResourceLoadPriorityForTesting)
-        request.setPriority(m_overrideResourceLoadPriorityForTesting.value());
+    // The remaining modifications are only necessary for HTTP and HTTPS.
+    if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily())
+        return;
 
-    if (request.cachePolicy() == ReloadIgnoringCacheData) {
+    if (!hasSpecificCachePolicy && request.cachePolicy() == ReloadIgnoringCacheData) {
         if (loadType == FrameLoadType::Reload)
             request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "max-age=0");
         else if (loadType == FrameLoadType::ReloadFromOrigin) {
@@ -2626,7 +2623,12 @@
         }
     }
 
-    if (mainResource)
+    if (m_overrideResourceLoadPriorityForTesting)
+        request.setPriority(m_overrideResourceLoadPriorityForTesting.value());
+
+    applyUserAgent(request);
+
+    if (isMainResource)
         request.setHTTPAccept(defaultAcceptHeader);
 
     // Make sure we send the Origin header.

Modified: trunk/Source/WebCore/loader/FrameLoader.h (207085 => 207086)


--- trunk/Source/WebCore/loader/FrameLoader.h	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/FrameLoader.h	2016-10-11 10:53:22 UTC (rev 207086)
@@ -311,16 +311,17 @@
     bool allChildrenAreComplete() const; // immediate children, not all descendants
 
     void checkTimerFired();
-    
+
     void loadSameDocumentItem(HistoryItem&);
     void loadDifferentDocumentItem(HistoryItem&, FrameLoadType, FormSubmissionCacheLoadPolicy);
-    
+
     void loadProvisionalItemFromCachedPage();
 
     void updateFirstPartyForCookies();
     void setFirstPartyForCookies(const URL&);
-    
+
     void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType, bool isMainResource);
+    ResourceRequestCachePolicy defaultRequestCachingPolicy(const ResourceRequest&, FrameLoadType, bool isMainResource);
 
     void clearProvisionalLoad();
     void transitionToCommitted(CachedPage*);

Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp (207085 => 207086)


--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp	2016-10-11 10:53:22 UTC (rev 207086)
@@ -51,6 +51,7 @@
 #include "FrameLoaderClient.h"
 #include "HTMLElement.h"
 #include "HTMLFrameOwnerElement.h"
+#include "HTTPHeaderValues.h"
 #include "LoaderStrategy.h"
 #include "LocalizedStrings.h"
 #include "Logging.h"
@@ -663,6 +664,49 @@
     // FIXME: Decide whether to support client hints
 }
 
+static inline void updateRequestAccordingCacheMode(CachedResourceRequest& request)
+{
+    if (request.options().cache == FetchOptions::Cache::Default
+            && (request.resourceRequest().hasHTTPHeaderField(HTTPHeaderName::IfModifiedSince)
+                || request.resourceRequest().hasHTTPHeaderField(HTTPHeaderName::IfNoneMatch)
+                || request.resourceRequest().hasHTTPHeaderField(HTTPHeaderName::IfUnmodifiedSince)
+                || request.resourceRequest().hasHTTPHeaderField(HTTPHeaderName::IfMatch)
+                || request.resourceRequest().hasHTTPHeaderField(HTTPHeaderName::IfRange)))
+        request.setCacheModeToNoStore();
+
+    switch (request.options().cache) {
+    case FetchOptions::Cache::NoCache:
+        request.mutableResourceRequest().setCachePolicy(ReloadIgnoringCacheData);
+        request.mutableResourceRequest().addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::CacheControl, HTTPHeaderValues::maxAge0());
+        break;
+    case FetchOptions::Cache::NoStore:
+        request.setCachingPolicy(CachingPolicy::DisallowCaching);
+        request.mutableResourceRequest().setCachePolicy(ReloadIgnoringCacheData);
+        request.mutableResourceRequest().addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::Pragma, HTTPHeaderValues::noCache());
+        request.mutableResourceRequest().addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::CacheControl, HTTPHeaderValues::noCache());
+        break;
+    case FetchOptions::Cache::Reload:
+        request.mutableResourceRequest().setCachePolicy(ReloadIgnoringCacheData);
+        request.mutableResourceRequest().addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::Pragma, HTTPHeaderValues::noCache());
+        request.mutableResourceRequest().addHTTPHeaderFieldIfNotPresent(HTTPHeaderName::CacheControl, HTTPHeaderValues::noCache());
+        break;
+    case FetchOptions::Cache::Default:
+        break;
+    case FetchOptions::Cache::ForceCache:
+        request.mutableResourceRequest().setCachePolicy(ReturnCacheDataElseLoad);
+        break;
+    case FetchOptions::Cache::OnlyIfCached:
+        request.mutableResourceRequest().setCachePolicy(ReturnCacheDataDontLoad);
+        break;
+    }
+}
+
+void CachedResourceLoader::updateHTTPRequestHeaders(CachedResourceRequest& resourceRequest)
+{
+    // Implementing steps 10 to 12 of https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
+    updateRequestAccordingCacheMode(resourceRequest);
+}
+
 CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(CachedResource::Type type, CachedResourceRequest&& request, ForPreload forPreload, DeferOption defer)
 {
     if (Document* document = this->document())
@@ -720,6 +764,9 @@
     loadTiming.markStartTimeAndFetchStart();
 #endif
 
+    if (request.resourceRequest().url().protocolIsInHTTPFamily())
+        updateHTTPRequestHeaders(request);
+
     auto& memoryCache = MemoryCache::singleton();
     if (request.allowsCaching() && memoryCache.disabled()) {
         DocumentResourceMap::iterator it = m_documentResources.find(url.string());
@@ -844,7 +891,8 @@
 CachedResourceHandle<CachedResource> CachedResourceLoader::loadResource(CachedResource::Type type, CachedResourceRequest&& request)
 {
     auto& memoryCache = MemoryCache::singleton();
-    ASSERT(!request.allowsCaching() || !memoryCache.resourceForRequest(request.resourceRequest(), sessionID()));
+    ASSERT(!request.allowsCaching() || !memoryCache.resourceForRequest(request.resourceRequest(), sessionID())
+        || request.options().cache == FetchOptions::Cache::NoCache || request.options().cache == FetchOptions::Cache::NoStore || request.options().cache == FetchOptions::Cache::Reload);
 
     LOG(ResourceLoading, "Loading CachedResource for '%s'.", request.resourceRequest().url().stringCenterEllipsizedToLength().latin1().data());
 
@@ -897,6 +945,12 @@
     if (!existingResource)
         return Load;
 
+    if (cachedResourceRequest.options().cache == FetchOptions::Cache::NoStore)
+        return Load;
+
+    if (cachedResourceRequest.options().cache == FetchOptions::Cache::Reload)
+        return Reload;
+
     // We already have a preload going for this URL.
     if (forPreload == ForPreload::Yes && existingResource->isPreloaded())
         return Use;
@@ -931,10 +985,12 @@
     if (defer == DeferOption::DeferredByClient)
         return Reload;
 
-    // Don't reload resources while pasting.
-    if (m_allowStaleResources)
+    // Don't reload resources while pasting or if cache mode allows stale resources.
+    if (m_allowStaleResources || cachedResourceRequest.options().cache == FetchOptions::Cache::ForceCache || cachedResourceRequest.options().cache == FetchOptions::Cache::OnlyIfCached)
         return Use;
 
+    ASSERT(cachedResourceRequest.options().cache == FetchOptions::Cache::Default || cachedResourceRequest.options().cache == FetchOptions::Cache::NoCache);
+
     // Always use preloads.
     if (existingResource->isPreloaded())
         return Use;

Modified: trunk/Source/WebCore/loader/cache/CachedResourceLoader.h (207085 => 207086)


--- trunk/Source/WebCore/loader/cache/CachedResourceLoader.h	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/cache/CachedResourceLoader.h	2016-10-11 10:53:22 UTC (rev 207086)
@@ -154,6 +154,7 @@
     enum class ForPreload { Yes, No };
     enum class DeferOption { NoDefer, DeferredByClient };
 
+    void updateHTTPRequestHeaders(CachedResourceRequest&);
     CachedResourceHandle<CachedResource> requestResource(CachedResource::Type, CachedResourceRequest&&, ForPreload = ForPreload::No, DeferOption = DeferOption::NoDefer);
     void prepareFetch(CachedResource::Type, CachedResourceRequest&);
     CachedResourceHandle<CachedResource> revalidateResource(CachedResourceRequest&&, CachedResource&);

Modified: trunk/Source/WebCore/loader/cache/CachedResourceRequest.h (207085 => 207086)


--- trunk/Source/WebCore/loader/cache/CachedResourceRequest.h	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/loader/cache/CachedResourceRequest.h	2016-10-11 10:53:22 UTC (rev 207086)
@@ -60,6 +60,8 @@
     RefPtr<SecurityOrigin> releaseOrigin() { return WTFMove(m_origin); }
     SecurityOrigin* origin() const { return m_origin.get(); }
 
+    void setCacheModeToNoStore() { m_options.cache = FetchOptions::Cache::NoStore; }
+
 private:
     ResourceRequest m_resourceRequest;
     String m_charset;

Modified: trunk/Source/WebCore/page/EventSource.cpp (207085 => 207086)


--- trunk/Source/WebCore/page/EventSource.cpp	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/page/EventSource.cpp	2016-10-11 10:53:22 UTC (rev 207086)
@@ -108,6 +108,7 @@
     options.credentials = m_withCredentials ? FetchOptions::Credentials::Include : FetchOptions::Credentials::SameOrigin;
     options.preflightPolicy = PreventPreflight;
     options.mode = FetchOptions::Mode::Cors;
+    options.cache = FetchOptions::Cache::NoStore;
     options.dataBufferingPolicy = DoNotBufferData;
     options.contentSecurityPolicyEnforcement = scriptExecutionContext()->shouldBypassMainWorldContentSecurityPolicy() ? ContentSecurityPolicyEnforcement::DoNotEnforce : ContentSecurityPolicyEnforcement::EnforceConnectSrcDirective;
 

Modified: trunk/Source/WebCore/platform/network/HTTPHeaderMap.cpp (207085 => 207086)


--- trunk/Source/WebCore/platform/network/HTTPHeaderMap.cpp	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderMap.cpp	2016-10-11 10:53:22 UTC (rev 207086)
@@ -103,6 +103,11 @@
     add(headerName, value);
 }
 
+bool HTTPHeaderMap::addIfNotPresent(HTTPHeaderName headerName, const String& value)
+{
+    return m_commonHeaders.add(headerName, value).isNewEntry;
+}
+
 bool HTTPHeaderMap::contains(const String& name) const
 {
     HTTPHeaderName headerName;

Modified: trunk/Source/WebCore/platform/network/HTTPHeaderMap.h (207085 => 207086)


--- trunk/Source/WebCore/platform/network/HTTPHeaderMap.h	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderMap.h	2016-10-11 10:53:22 UTC (rev 207086)
@@ -141,6 +141,7 @@
     WEBCORE_EXPORT String get(HTTPHeaderName) const;
     void set(HTTPHeaderName, const String& value);
     void add(HTTPHeaderName, const String& value);
+    bool addIfNotPresent(HTTPHeaderName, const String&);
     bool contains(HTTPHeaderName) const;
     WEBCORE_EXPORT bool remove(HTTPHeaderName);
 

Modified: trunk/Source/WebCore/platform/network/HTTPHeaderValues.cpp (207085 => 207086)


--- trunk/Source/WebCore/platform/network/HTTPHeaderValues.cpp	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderValues.cpp	2016-10-11 10:53:22 UTC (rev 207086)
@@ -44,6 +44,18 @@
     return contentType;
 }
 
+const String& noCache()
+{
+    static NeverDestroyed<const String> value(ASCIILiteral("no-cache"));
+    return value;
 }
 
+const String& maxAge0()
+{
+    static NeverDestroyed<const String> value(ASCIILiteral("max-age=0"));
+    return value;
 }
+
+}
+
+}

Modified: trunk/Source/WebCore/platform/network/HTTPHeaderValues.h (207085 => 207086)


--- trunk/Source/WebCore/platform/network/HTTPHeaderValues.h	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderValues.h	2016-10-11 10:53:22 UTC (rev 207086)
@@ -32,7 +32,8 @@
 
 const String& textPlainContentType();
 const String& formURLEncodedContentType();
-
+const String& noCache();
+const String& maxAge0();
 }
 
 }

Modified: trunk/Source/WebCore/platform/network/ResourceRequestBase.cpp (207085 => 207086)


--- trunk/Source/WebCore/platform/network/ResourceRequestBase.cpp	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/ResourceRequestBase.cpp	2016-10-11 10:53:22 UTC (rev 207086)
@@ -464,6 +464,17 @@
         m_platformRequestUpdated = false;
 }
 
+void ResourceRequestBase::addHTTPHeaderFieldIfNotPresent(HTTPHeaderName name, const String& value)
+{
+    updateResourceRequest();
+
+    if (!m_httpHeaderFields.addIfNotPresent(name, value))
+        return;
+
+    if (url().protocolIsInHTTPFamily())
+        m_platformRequestUpdated = false;
+}
+
 void ResourceRequestBase::addHTTPHeaderField(HTTPHeaderName name, const String& value)
 {
     updateResourceRequest();
@@ -477,13 +488,18 @@
 void ResourceRequestBase::addHTTPHeaderField(const String& name, const String& value)
 {
     updateResourceRequest();
-    
+
     m_httpHeaderFields.add(name, value);
-    
+
     if (url().protocolIsInHTTPFamily())
         m_platformRequestUpdated = false;
 }
-    
+
+bool ResourceRequestBase::hasHTTPHeaderField(HTTPHeaderName headerName) const
+{
+    return m_httpHeaderFields.contains(headerName);
+}
+
 void ResourceRequestBase::setHTTPHeaderFields(HTTPHeaderMap headerFields)
 {
     updateResourceRequest();

Modified: trunk/Source/WebCore/platform/network/ResourceRequestBase.h (207085 => 207086)


--- trunk/Source/WebCore/platform/network/ResourceRequestBase.h	2016-10-11 10:51:32 UTC (rev 207085)
+++ trunk/Source/WebCore/platform/network/ResourceRequestBase.h	2016-10-11 10:53:22 UTC (rev 207086)
@@ -85,7 +85,10 @@
     WEBCORE_EXPORT void setHTTPHeaderField(HTTPHeaderName, const String& value);
     void addHTTPHeaderField(HTTPHeaderName, const String& value);
     void addHTTPHeaderField(const String& name, const String& value);
+    void addHTTPHeaderFieldIfNotPresent(HTTPHeaderName, const String&);
 
+    bool hasHTTPHeaderField(HTTPHeaderName) const;
+
     // Instead of passing a string literal to any of these functions, just use a HTTPHeaderName instead.
     template<size_t length> String httpHeaderField(const char (&)[length]) const = delete;
     template<size_t length> void setHTTPHeaderField(const char (&)[length], const String&) = delete;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to