<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[198741] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/198741">198741</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2016-03-28 09:04:33 -0700 (Mon, 28 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Disk cache speculative validation requests do not have the 'Referer' HTTP header set
https://bugs.webkit.org/show_bug.cgi?id=155890
&lt;rdar://problem/25279962&gt;

Reviewed by Antti Koivisto.

Source/WebCore:

Export a couple more symbols so we can use them from WebKit2.

* platform/network/HTTPHeaderMap.h:
* platform/network/ResourceRequestBase.h:

Source/WebKit2:

Disk cache speculative validation requests did not have the 'Referer'
HTTP header set. This was breaking some streaming sites (such as
twitch.tv).

We now store all the original request's HTTP headers in the disk cache
so we can re-use them for the speculative validation requests. When the
actual request comes later on, we also make sure that the HTTP headers
used in the speculative validation request match the ones from the
effective request. If they don't we don't use the speculatively
validated resource as the server may return a different resource in
such case.

* NetworkProcess/cache/NetworkCache.cpp:
(WebKit::NetworkCache::Cache::retrieve):
Pass the effective ResourceRequest to the NetworkCacheSpeculativeLoadManager
so it can check that the speculative validation request's HTTP headers
match the effective request's headers.

* NetworkProcess/cache/NetworkCacheSpeculativeLoad.h:
* NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
(WebKit::NetworkCache::constructRevalidationRequest):
(WebKit::NetworkCache::SpeculativeLoadManager::PreloadedEntry::PreloadedEntry):
(WebKit::NetworkCache::SpeculativeLoadManager::PreloadedEntry::revalidationRequest):
(WebKit::NetworkCache::SpeculativeLoadManager::PreloadedEntry::wasRevalidated):
We now have a member in PreloadedEntry to keep the request used for validation, if
speculative validation was done. This is so that we can compare its HTTP headers
with the ones of the effective request later on.

(WebKit::NetworkCache::dumpHTTPHeadersDiff):
Debug function that prints which HTTP headers did not match in the speculative
validation request and in the effective request.

(WebKit::NetworkCache::requestsHeadersMatch):
New utility function to check that the speculative validation request's HTTP
headers match the ones of the effective requests. Note that we allow for
headers related to validation to differ.

(WebKit::NetworkCache::SpeculativeLoadManager::canUsePreloadedEntry):
(WebKit::NetworkCache::SpeculativeLoadManager::canUsePendingPreload):
(WebKit::NetworkCache::SpeculativeLoadManager::retrieve):
Check that the speculative validation request's HTTP headers match the
ones of the effective request. If they don't then do not use the
speculatively validated resource.

(WebKit::NetworkCache::SpeculativeLoadManager::addPreloadedEntry):
(WebKit::NetworkCache::SpeculativeLoadManager::revalidateEntry):
(WebKit::NetworkCache::SpeculativeLoadManager::preloadEntry):
(WebKit::NetworkCache::SpeculativeLoadManager::startSpeculativeRevalidation):
* NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h:

* NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp:
(WebKit::NetworkCache::SubresourceInfo::encode):
(WebKit::NetworkCache::SubresourceInfo::decode):
(WebKit::NetworkCache::SubresourcesEntry::encodeAsStorageRecord):
(WebKit::NetworkCache::SubresourcesEntry::decodeStorageRecord):
* NetworkProcess/cache/NetworkCacheSubresourcesEntry.h:
(WebKit::NetworkCache::SubresourceInfo::SubresourceInfo):
- Keep all the request's headers in SubresourceInfo instead of just the
  'User-Agent' one.
- Drop the custom copy constructor / assignment operator for
  SubresourceInfo that were making isolated copies on the members.
  We technically don't need to use SubresourceInfo objects in other
  threads than the main one. In SpeculativeLoadManager::preloadEntry(),
  we now make capture a SubresourceInfo* in the lambda to avoid calling
  the copy constructor. We also make sure that the object gets destroyed
  in the lambda function, which is executed in the main thread.

LayoutTests:

Update existing layout test to make sure that speculative validation
requests have their HTTP 'Referer' header set.

* http/tests/cache/disk-cache/speculative-validation/validation-request-expected.txt:
* http/tests/cache/disk-cache/speculative-validation/validation-request.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestshttptestscachediskcachespeculativevalidationvalidationrequestexpectedtxt">trunk/LayoutTests/http/tests/cache/disk-cache/speculative-validation/validation-request-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestscachediskcachespeculativevalidationvalidationrequesthtml">trunk/LayoutTests/http/tests/cache/disk-cache/speculative-validation/validation-request.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkHTTPHeaderMaph">trunk/Source/WebCore/platform/network/HTTPHeaderMap.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkResourceRequestBaseh">trunk/Source/WebCore/platform/network/ResourceRequestBase.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCachecpp">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheSpeculativeLoadh">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheSpeculativeLoadManagercpp">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheSpeculativeLoadManagerh">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheSubresourcesEntrycpp">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheSubresourcesEntryh">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/LayoutTests/ChangeLog        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-03-28  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Disk cache speculative validation requests do not have the 'Referer' HTTP header set
+        https://bugs.webkit.org/show_bug.cgi?id=155890
+        &lt;rdar://problem/25279962&gt;
+
+        Reviewed by Antti Koivisto.
+
+        Update existing layout test to make sure that speculative validation
+        requests have their HTTP 'Referer' header set.
+
+        * http/tests/cache/disk-cache/speculative-validation/validation-request-expected.txt:
+        * http/tests/cache/disk-cache/speculative-validation/validation-request.html:
+
</ins><span class="cx"> 2016-03-28  Gyuyoung Kim  &lt;gyuyoung.kim@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [EFL] Mark failing indexeddb tests to failure
</span></span></pre></div>
<a id="trunkLayoutTestshttptestscachediskcachespeculativevalidationvalidationrequestexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/cache/disk-cache/speculative-validation/validation-request-expected.txt (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/cache/disk-cache/speculative-validation/validation-request-expected.txt        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/LayoutTests/http/tests/cache/disk-cache/speculative-validation/validation-request-expected.txt        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -4,7 +4,12 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> PASS validationRequestHeader('If-None-Match') is &quot;123456789&quot;
</span><del>-PASS validationRequestHeader('User-Agent') is initialUserAgent
</del><ins>+PASS validationRequestHeader('Accept') is initialHeaderValues['Accept']
+PASS validationRequestHeader('Accept-Encoding') is initialHeaderValues['Accept-Encoding']
+PASS validationRequestHeader('Accept-Language') is initialHeaderValues['Accept-Language']
+PASS validationRequestHeader('Connection') is initialHeaderValues['Connection']
+PASS validationRequestHeader('Referer') is initialHeaderValues['Referer']
+PASS validationRequestHeader('User-Agent') is initialHeaderValues['User-Agent']
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestshttptestscachediskcachespeculativevalidationvalidationrequesthtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/cache/disk-cache/speculative-validation/validation-request.html (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/cache/disk-cache/speculative-validation/validation-request.html        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/LayoutTests/http/tests/cache/disk-cache/speculative-validation/validation-request.html        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -5,6 +5,9 @@
</span><span class="cx"> 
</span><span class="cx"> state = &quot;warmup&quot;;
</span><span class="cx"> 
</span><ins>+var headersToCheck = [&quot;Accept&quot;, &quot;Accept-Encoding&quot;, &quot;Accept-Language&quot;, &quot;Connection&quot;, &quot;Referer&quot;, &quot;User-Agent&quot;];
+var headerToCheck;
+
</ins><span class="cx"> function validationRequestHeader(headerName)
</span><span class="cx"> {
</span><span class="cx">     return frames[0].allRequestHeaders[headerName];
</span><span class="lines">@@ -14,7 +17,11 @@
</span><span class="cx"> function frameLoaded()
</span><span class="cx"> {
</span><span class="cx">     if (state == &quot;warmup&quot;) {
</span><del>-        initialUserAgent = validationRequestHeader('User-Agent');
</del><ins>+        initialHeaderValues = [];
+        for (var i = 0; i &lt; headersToCheck.length; i++) {
+            headerToCheck = headersToCheck[i];
+            initialHeaderValues[headerToCheck] = validationRequestHeader(headerToCheck);
+        }
</ins><span class="cx">         // Navigate frame to 'about:blank' to flush to subresource loads metadata to disk.
</span><span class="cx">         state = &quot;flushingMetadata&quot;;
</span><span class="cx">         document.getElementById(&quot;testFrame&quot;).src = &quot;about:blank&quot;;
</span><span class="lines">@@ -30,7 +37,11 @@
</span><span class="cx">     if (state == &quot;speculativeRevalidation&quot;) {
</span><span class="cx">         // Validate the HTTP headers of the speculative validation request.
</span><span class="cx">         shouldBeEqualToString(&quot;validationRequestHeader('If-None-Match')&quot;, &quot;123456789&quot;);
</span><del>-        shouldBe(&quot;validationRequestHeader('User-Agent')&quot;, &quot;initialUserAgent&quot;);
</del><ins>+
+        for (var i = 0; i &lt; headersToCheck.length; i++) {
+            headerToCheck = headersToCheck[i];
+            shouldBe(&quot;validationRequestHeader('&quot; + headerToCheck + &quot;')&quot;, &quot;initialHeaderValues['&quot; + headerToCheck + &quot;']&quot;);
+        }
</ins><span class="cx">         finishJSTest();
</span><span class="cx">         return;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/Source/WebCore/ChangeLog        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-03-28  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Disk cache speculative validation requests do not have the 'Referer' HTTP header set
+        https://bugs.webkit.org/show_bug.cgi?id=155890
+        &lt;rdar://problem/25279962&gt;
+
+        Reviewed by Antti Koivisto.
+
+        Export a couple more symbols so we can use them from WebKit2.
+
+        * platform/network/HTTPHeaderMap.h:
+        * platform/network/ResourceRequestBase.h:
+
</ins><span class="cx"> 2016-03-24  Timothy Hatcher  &lt;timothy@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Automation: Add commands to compute layout of an element
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPHeaderMaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPHeaderMap.h (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPHeaderMap.h        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderMap.h        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -139,7 +139,7 @@
</span><span class="cx">     WEBCORE_EXPORT String get(const String&amp; name) const;
</span><span class="cx">     WEBCORE_EXPORT void set(const String&amp; name, const String&amp; value);
</span><span class="cx">     void add(const String&amp; name, const String&amp; value);
</span><del>-    bool contains(const String&amp;) const;
</del><ins>+    WEBCORE_EXPORT bool contains(const String&amp;) const;
</ins><span class="cx">     bool remove(const String&amp;);
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT String get(HTTPHeaderName) const;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkResourceRequestBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/ResourceRequestBase.h (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/ResourceRequestBase.h        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/Source/WebCore/platform/network/ResourceRequestBase.h        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -130,7 +130,7 @@
</span><span class="cx">         WEBCORE_EXPORT void setPriority(ResourceLoadPriority);
</span><span class="cx"> 
</span><span class="cx">         WEBCORE_EXPORT bool isConditional() const;
</span><del>-        void makeUnconditional();
</del><ins>+        WEBCORE_EXPORT void makeUnconditional();
</ins><span class="cx"> 
</span><span class="cx">         // Whether the associated ResourceHandleClient needs to be notified of
</span><span class="cx">         // upload progress made for that resource.
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/Source/WebKit2/ChangeLog        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -1,3 +1,78 @@
</span><ins>+2016-03-28  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Disk cache speculative validation requests do not have the 'Referer' HTTP header set
+        https://bugs.webkit.org/show_bug.cgi?id=155890
+        &lt;rdar://problem/25279962&gt;
+
+        Reviewed by Antti Koivisto.
+
+        Disk cache speculative validation requests did not have the 'Referer'
+        HTTP header set. This was breaking some streaming sites (such as
+        twitch.tv).
+
+        We now store all the original request's HTTP headers in the disk cache
+        so we can re-use them for the speculative validation requests. When the
+        actual request comes later on, we also make sure that the HTTP headers
+        used in the speculative validation request match the ones from the
+        effective request. If they don't we don't use the speculatively
+        validated resource as the server may return a different resource in
+        such case.
+
+        * NetworkProcess/cache/NetworkCache.cpp:
+        (WebKit::NetworkCache::Cache::retrieve):
+        Pass the effective ResourceRequest to the NetworkCacheSpeculativeLoadManager
+        so it can check that the speculative validation request's HTTP headers
+        match the effective request's headers.
+
+        * NetworkProcess/cache/NetworkCacheSpeculativeLoad.h:
+        * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
+        (WebKit::NetworkCache::constructRevalidationRequest):
+        (WebKit::NetworkCache::SpeculativeLoadManager::PreloadedEntry::PreloadedEntry):
+        (WebKit::NetworkCache::SpeculativeLoadManager::PreloadedEntry::revalidationRequest):
+        (WebKit::NetworkCache::SpeculativeLoadManager::PreloadedEntry::wasRevalidated):
+        We now have a member in PreloadedEntry to keep the request used for validation, if
+        speculative validation was done. This is so that we can compare its HTTP headers
+        with the ones of the effective request later on.
+
+        (WebKit::NetworkCache::dumpHTTPHeadersDiff):
+        Debug function that prints which HTTP headers did not match in the speculative
+        validation request and in the effective request.
+
+        (WebKit::NetworkCache::requestsHeadersMatch):
+        New utility function to check that the speculative validation request's HTTP
+        headers match the ones of the effective requests. Note that we allow for
+        headers related to validation to differ.
+
+        (WebKit::NetworkCache::SpeculativeLoadManager::canUsePreloadedEntry):
+        (WebKit::NetworkCache::SpeculativeLoadManager::canUsePendingPreload):
+        (WebKit::NetworkCache::SpeculativeLoadManager::retrieve):
+        Check that the speculative validation request's HTTP headers match the
+        ones of the effective request. If they don't then do not use the
+        speculatively validated resource.
+
+        (WebKit::NetworkCache::SpeculativeLoadManager::addPreloadedEntry):
+        (WebKit::NetworkCache::SpeculativeLoadManager::revalidateEntry):
+        (WebKit::NetworkCache::SpeculativeLoadManager::preloadEntry):
+        (WebKit::NetworkCache::SpeculativeLoadManager::startSpeculativeRevalidation):
+        * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h:
+
+        * NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp:
+        (WebKit::NetworkCache::SubresourceInfo::encode):
+        (WebKit::NetworkCache::SubresourceInfo::decode):
+        (WebKit::NetworkCache::SubresourcesEntry::encodeAsStorageRecord):
+        (WebKit::NetworkCache::SubresourcesEntry::decodeStorageRecord):
+        * NetworkProcess/cache/NetworkCacheSubresourcesEntry.h:
+        (WebKit::NetworkCache::SubresourceInfo::SubresourceInfo):
+        - Keep all the request's headers in SubresourceInfo instead of just the
+          'User-Agent' one.
+        - Drop the custom copy constructor / assignment operator for
+          SubresourceInfo that were making isolated copies on the members.
+          We technically don't need to use SubresourceInfo objects in other
+          threads than the main one. In SpeculativeLoadManager::preloadEntry(),
+          we now make capture a SubresourceInfo* in the lambda to avoid calling
+          the copy constructor. We also make sure that the object gets destroyed
+          in the lambda function, which is executed in the main thread.
+
</ins><span class="cx"> 2016-03-25  Timothy Hatcher  &lt;timothy@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Automation: Add Automation protocol commands to handle JavaScript dialogs
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCachecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -368,7 +368,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
</span><del>-    if (m_speculativeLoadManager &amp;&amp; m_speculativeLoadManager-&gt;retrieve(frameID, storageKey, [request, completionHandler](std::unique_ptr&lt;Entry&gt; entry) {
</del><ins>+    if (m_speculativeLoadManager &amp;&amp; m_speculativeLoadManager-&gt;retrieve(frameID, storageKey, request, [request, completionHandler](std::unique_ptr&lt;Entry&gt; entry) {
</ins><span class="cx">         if (entry &amp;&amp; verifyVaryingRequestHeaders(entry-&gt;varyingRequestHeaders(), request))
</span><span class="cx">             completionHandler(WTFMove(entry));
</span><span class="cx">         else
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheSpeculativeLoadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -49,6 +49,8 @@
</span><span class="cx"> 
</span><span class="cx">     virtual ~SpeculativeLoad();
</span><span class="cx"> 
</span><ins>+    const WebCore::ResourceRequest&amp; originalRequest() const { return m_originalRequest; }
+
</ins><span class="cx"> private:
</span><span class="cx">     // NetworkLoadClient.
</span><span class="cx">     void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override { }
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheSpeculativeLoadManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -84,24 +84,25 @@
</span><span class="cx">     return Key(resourceKey.partition(), subresourcesType(), resourceKey.range(), resourceKey.identifier());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline ResourceRequest constructRevalidationRequest(const Entry&amp; entry, const SubresourceInfo&amp; subResourceInfo)
</del><ins>+static inline std::unique_ptr&lt;ResourceRequest&gt; constructRevalidationRequest(const Entry&amp; entry, const SubresourceInfo&amp; subResourceInfo)
</ins><span class="cx"> {
</span><del>-    ResourceRequest revalidationRequest(entry.key().identifier());
-    revalidationRequest.setHTTPUserAgent(subResourceInfo.httpUserAgent);
-    revalidationRequest.setFirstPartyForCookies(subResourceInfo.firstPartyForCookies);
</del><ins>+    auto revalidationRequest = std::make_unique&lt;ResourceRequest&gt;(entry.key().identifier());
+    revalidationRequest-&gt;setHTTPHeaderFields(subResourceInfo.requestHeaders);
+    revalidationRequest-&gt;setFirstPartyForCookies(subResourceInfo.firstPartyForCookies);
</ins><span class="cx"> #if ENABLE(CACHE_PARTITIONING)
</span><span class="cx">     if (entry.key().hasPartition())
</span><del>-        revalidationRequest.setCachePartition(entry.key().partition());
</del><ins>+        revalidationRequest-&gt;setCachePartition(entry.key().partition());
</ins><span class="cx"> #endif
</span><span class="cx">     ASSERT_WITH_MESSAGE(entry.key().range().isEmpty(), &quot;range is not supported&quot;);
</span><span class="cx"> 
</span><ins>+    revalidationRequest-&gt;makeUnconditional();
</ins><span class="cx">     String eTag = entry.response().httpHeaderField(HTTPHeaderName::ETag);
</span><span class="cx">     if (!eTag.isEmpty())
</span><del>-        revalidationRequest.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag);
</del><ins>+        revalidationRequest-&gt;setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag);
</ins><span class="cx"> 
</span><span class="cx">     String lastModified = entry.response().httpHeaderField(HTTPHeaderName::LastModified);
</span><span class="cx">     if (!lastModified.isEmpty())
</span><del>-        revalidationRequest.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified);
</del><ins>+        revalidationRequest-&gt;setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified);
</ins><span class="cx"> 
</span><span class="cx">     return revalidationRequest;
</span><span class="cx"> }
</span><span class="lines">@@ -132,10 +133,10 @@
</span><span class="cx"> class SpeculativeLoadManager::PreloadedEntry : private ExpiringEntry {
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><del>-    PreloadedEntry(std::unique_ptr&lt;Entry&gt; entry, WasRevalidated wasRevalidated, std::function&lt;void()&gt;&amp;&amp; lifetimeReachedHandler)
</del><ins>+    PreloadedEntry(std::unique_ptr&lt;Entry&gt; entry, std::unique_ptr&lt;ResourceRequest&gt; speculativeValidationRequest, std::function&lt;void()&gt;&amp;&amp; lifetimeReachedHandler)
</ins><span class="cx">         : ExpiringEntry(WTFMove(lifetimeReachedHandler))
</span><span class="cx">         , m_entry(WTFMove(entry))
</span><del>-        , m_wasRevalidated(wasRevalidated == WasRevalidated::Yes)
</del><ins>+        , m_speculativeValidationRequest(WTFMove(speculativeValidationRequest))
</ins><span class="cx">     { }
</span><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;Entry&gt; takeCacheEntry()
</span><span class="lines">@@ -144,11 +145,12 @@
</span><span class="cx">         return WTFMove(m_entry);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool wasRevalidated() const { return m_wasRevalidated; }
</del><ins>+    ResourceRequest* revalidationRequest() const { return m_speculativeValidationRequest.get(); }
+    bool wasRevalidated() const { return !!m_speculativeValidationRequest; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     std::unique_ptr&lt;Entry&gt; m_entry;
</span><del>-    bool m_wasRevalidated;
</del><ins>+    std::unique_ptr&lt;ResourceRequest&gt; m_speculativeValidationRequest;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class SpeculativeLoadManager::PendingFrameLoad : public RefCounted&lt;PendingFrameLoad&gt; {
</span><span class="lines">@@ -246,22 +248,89 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool SpeculativeLoadManager::retrieve(const GlobalFrameID&amp; frameID, const Key&amp; storageKey, const RetrieveCompletionHandler&amp; completionHandler)
</del><ins>+#if !LOG_DISABLED
+
+static void dumpHTTPHeadersDiff(const HTTPHeaderMap&amp; headersA, const HTTPHeaderMap&amp; headersB)
</ins><span class="cx"> {
</span><ins>+    auto aEnd = headersA.end();
+    for (auto it = headersA.begin(); it != aEnd; ++it) {
+        String valueB = headersB.get(it-&gt;key);
+        if (valueB.isNull())
+            LOG(NetworkCacheSpeculativePreloading, &quot;* '%s' HTTP header is only in first request (value: %s)&quot;, it-&gt;key.utf8().data(), it-&gt;value.utf8().data());
+        else if (it-&gt;value != valueB)
+            LOG(NetworkCacheSpeculativePreloading, &quot;* '%s' HTTP header differs in both requests: %s != %s&quot;, it-&gt;key.utf8().data(), it-&gt;value.utf8().data(), valueB.utf8().data());
+    }
+    auto bEnd = headersB.end();
+    for (auto it = headersB.begin(); it != bEnd; ++it) {
+        if (!headersA.contains(it-&gt;key))
+            LOG(NetworkCacheSpeculativePreloading, &quot;* '%s' HTTP header is only in second request (value: %s)&quot;, it-&gt;key.utf8().data(), it-&gt;value.utf8().data());
+    }
+}
+
+#endif
+
+static bool requestsHeadersMatch(const ResourceRequest&amp; a, const ResourceRequest&amp; b)
+{
+    static const HTTPHeaderName headersAllowedToMismatch[] = {
+        HTTPHeaderName::IfMatch,
+        HTTPHeaderName::IfModifiedSince,
+        HTTPHeaderName::IfNoneMatch,
+        HTTPHeaderName::IfRange,
+        HTTPHeaderName::IfUnmodifiedSince,
+        HTTPHeaderName::CacheControl
+    };
+
+    HTTPHeaderMap headersA = a.httpHeaderFields();
+    HTTPHeaderMap headersB = b.httpHeaderFields();
+    for (auto headerName : headersAllowedToMismatch) {
+        headersA.remove(headerName);
+        headersB.remove(headerName);
+    }
+
+    if (headersA != headersB) {
+        LOG(NetworkCacheSpeculativePreloading, &quot;Cannot reuse speculatively validated entry because HTTP headers used for validation do not match&quot;);
+#if !LOG_DISABLED
+        dumpHTTPHeadersDiff(headersA, headersB);
+#endif
+        return false;
+    }
+    return true;
+}
+
+bool SpeculativeLoadManager::canUsePreloadedEntry(const PreloadedEntry&amp; entry, const ResourceRequest&amp; actualRequest)
+{
+    if (!entry.wasRevalidated())
+        return true;
+
+    ASSERT(entry.revalidationRequest());
+    return requestsHeadersMatch(*entry.revalidationRequest(), actualRequest);
+}
+
+bool SpeculativeLoadManager::canUsePendingPreload(const SpeculativeLoad&amp; load, const ResourceRequest&amp; actualRequest)
+{
+    return requestsHeadersMatch(load.originalRequest(), actualRequest);
+}
+
+bool SpeculativeLoadManager::retrieve(const GlobalFrameID&amp; frameID, const Key&amp; storageKey, const WebCore::ResourceRequest&amp; request, const RetrieveCompletionHandler&amp; completionHandler)
+{
</ins><span class="cx">     // Check already preloaded entries.
</span><span class="cx">     if (auto preloadedEntry = m_preloadedEntries.take(storageKey)) {
</span><ins>+        if (!canUsePreloadedEntry(*preloadedEntry, request)) {
+            LOG(NetworkCacheSpeculativePreloading, &quot;(NetworkProcess) Retrieval: Could not use preloaded entry to satisfy request for '%s' due to HTTP headers mismatch:&quot;, storageKey.identifier().utf8().data());
+            logSpeculativeLoadingDiagnosticMessage(frameID, preloadedEntry-&gt;wasRevalidated() ? DiagnosticLoggingKeys::wastedSpeculativeWarmupWithRevalidationKey() : DiagnosticLoggingKeys::wastedSpeculativeWarmupWithoutRevalidationKey());
+            return false;
+        }
+
</ins><span class="cx">         LOG(NetworkCacheSpeculativePreloading, &quot;(NetworkProcess) Retrieval: Using preloaded entry to satisfy request for '%s':&quot;, storageKey.identifier().utf8().data());
</span><del>-        if (preloadedEntry-&gt;wasRevalidated())
-            logSpeculativeLoadingDiagnosticMessage(frameID, DiagnosticLoggingKeys::successfulSpeculativeWarmupWithRevalidationKey());
-        else
-            logSpeculativeLoadingDiagnosticMessage(frameID, DiagnosticLoggingKeys::successfulSpeculativeWarmupWithoutRevalidationKey());
</del><ins>+        logSpeculativeLoadingDiagnosticMessage(frameID, preloadedEntry-&gt;wasRevalidated() ? DiagnosticLoggingKeys::successfulSpeculativeWarmupWithRevalidationKey() : DiagnosticLoggingKeys::successfulSpeculativeWarmupWithoutRevalidationKey());
</ins><span class="cx"> 
</span><span class="cx">         completionHandler(preloadedEntry-&gt;takeCacheEntry());
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Check pending speculative revalidations.
</span><del>-    if (!m_pendingPreloads.contains(storageKey)) {
</del><ins>+    auto* pendingPreload = m_pendingPreloads.get(storageKey);
+    if (!pendingPreload) {
</ins><span class="cx">         if (m_notPreloadedEntries.remove(storageKey))
</span><span class="cx">             logSpeculativeLoadingDiagnosticMessage(frameID, DiagnosticLoggingKeys::entryWronglyNotWarmedUpKey());
</span><span class="cx">         else
</span><span class="lines">@@ -270,6 +339,12 @@
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (!canUsePendingPreload(*pendingPreload, request)) {
+        LOG(NetworkCacheSpeculativePreloading, &quot;(NetworkProcess) Retrieval: revalidation already in progress for '%s' but unusable due to HTTP headers mismatch:&quot;, storageKey.identifier().utf8().data());
+        logSpeculativeLoadingDiagnosticMessage(frameID, DiagnosticLoggingKeys::wastedSpeculativeWarmupWithRevalidationKey());
+        return false;
+    }
+
</ins><span class="cx">     LOG(NetworkCacheSpeculativePreloading, &quot;(NetworkProcess) Retrieval: revalidation already in progress for '%s':&quot;, storageKey.identifier().utf8().data());
</span><span class="cx"> 
</span><span class="cx">     // FIXME: This breaks incremental loading when the revalidation is not successful.
</span><span class="lines">@@ -316,12 +391,12 @@
</span><span class="cx">         pendingFrameLoad-&gt;registerSubresourceLoad(request, resourceKey);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SpeculativeLoadManager::addPreloadedEntry(std::unique_ptr&lt;Entry&gt; entry, const GlobalFrameID&amp; frameID, WasRevalidated wasRevalidated)
</del><ins>+void SpeculativeLoadManager::addPreloadedEntry(std::unique_ptr&lt;Entry&gt; entry, const GlobalFrameID&amp; frameID, std::unique_ptr&lt;ResourceRequest&gt; revalidationRequest)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(entry);
</span><span class="cx">     ASSERT(!entry-&gt;needsValidation());
</span><span class="cx">     auto key = entry-&gt;key();
</span><del>-    m_preloadedEntries.add(key, std::make_unique&lt;PreloadedEntry&gt;(WTFMove(entry), wasRevalidated, [this, key, frameID] {
</del><ins>+    m_preloadedEntries.add(key, std::make_unique&lt;PreloadedEntry&gt;(WTFMove(entry), WTFMove(revalidationRequest), [this, key, frameID] {
</ins><span class="cx">         auto preloadedEntry = m_preloadedEntries.take(key);
</span><span class="cx">         ASSERT(preloadedEntry);
</span><span class="cx">         if (preloadedEntry-&gt;wasRevalidated())
</span><span class="lines">@@ -381,13 +456,15 @@
</span><span class="cx">     if (!key.range().isEmpty())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    ResourceRequest revalidationRequest = constructRevalidationRequest(*entry, subresourceInfo);
</del><ins>+    ResourceRequest* revalidationRequestPtr = constructRevalidationRequest(*entry, subresourceInfo).release();
</ins><span class="cx"> 
</span><span class="cx">     LOG(NetworkCacheSpeculativePreloading, &quot;(NetworkProcess) Speculatively revalidating '%s':&quot;, key.identifier().utf8().data());
</span><del>-    auto revalidator = std::make_unique&lt;SpeculativeLoad&gt;(frameID, revalidationRequest, WTFMove(entry), [this, key, frameID](std::unique_ptr&lt;Entry&gt; revalidatedEntry) {
</del><ins>+
+    auto revalidator = std::make_unique&lt;SpeculativeLoad&gt;(frameID, *revalidationRequestPtr, WTFMove(entry), [this, key, revalidationRequestPtr, frameID](std::unique_ptr&lt;Entry&gt; revalidatedEntry) {
</ins><span class="cx">         ASSERT(!revalidatedEntry || !revalidatedEntry-&gt;needsValidation());
</span><span class="cx">         ASSERT(!revalidatedEntry || revalidatedEntry-&gt;key() == key);
</span><span class="cx"> 
</span><ins>+        auto revalidationRequest = std::unique_ptr&lt;ResourceRequest&gt;(revalidationRequestPtr);
</ins><span class="cx">         auto protectRevalidator = m_pendingPreloads.take(key);
</span><span class="cx">         LOG(NetworkCacheSpeculativePreloading, &quot;(NetworkProcess) Speculative revalidation completed for '%s':&quot;, key.identifier().utf8().data());
</span><span class="cx"> 
</span><span class="lines">@@ -398,7 +475,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (revalidatedEntry)
</span><del>-            addPreloadedEntry(WTFMove(revalidatedEntry), frameID, WasRevalidated::Yes);
</del><ins>+            addPreloadedEntry(WTFMove(revalidatedEntry), frameID, WTFMove(revalidationRequest));
</ins><span class="cx">     });
</span><span class="cx">     m_pendingPreloads.add(key, WTFMove(revalidator));
</span><span class="cx"> }
</span><span class="lines">@@ -406,7 +483,9 @@
</span><span class="cx"> void SpeculativeLoadManager::preloadEntry(const Key&amp; key, const SubresourceInfo&amp; subResourceInfo, const GlobalFrameID&amp; frameID)
</span><span class="cx"> {
</span><span class="cx">     m_pendingPreloads.add(key, nullptr);
</span><del>-    retrieveEntryFromStorage(key, [this, key, subResourceInfo, frameID](std::unique_ptr&lt;Entry&gt; entry) {
</del><ins>+    auto* subResourceInfoPtr = new SubresourceInfo(subResourceInfo);
+    retrieveEntryFromStorage(key, [this, key, subResourceInfoPtr, frameID](std::unique_ptr&lt;Entry&gt; entry) {
+        auto subResourceInfo = std::unique_ptr&lt;SubresourceInfo&gt;(subResourceInfoPtr);
</ins><span class="cx">         m_pendingPreloads.remove(key);
</span><span class="cx"> 
</span><span class="cx">         if (satisfyPendingRequests(key, entry.get())) {
</span><span class="lines">@@ -419,17 +498,17 @@
</span><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         if (entry-&gt;needsValidation())
</span><del>-            revalidateEntry(WTFMove(entry), subResourceInfo, frameID);
</del><ins>+            revalidateEntry(WTFMove(entry), *subResourceInfo, frameID);
</ins><span class="cx">         else
</span><del>-            addPreloadedEntry(WTFMove(entry), frameID, WasRevalidated::No);
</del><ins>+            addPreloadedEntry(WTFMove(entry), frameID);
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SpeculativeLoadManager::startSpeculativeRevalidation(const GlobalFrameID&amp; frameID, SubresourcesEntry&amp; entry)
</span><span class="cx"> {
</span><span class="cx">     for (auto&amp; subresourcePair : entry.subresources()) {
</span><del>-        auto key = subresourcePair.key;
-        auto subresourceInfo = subresourcePair.value;
</del><ins>+        auto&amp; key = subresourcePair.key;
+        auto&amp; subresourceInfo = subresourcePair.value;
</ins><span class="cx">         if (!subresourceInfo.isTransient)
</span><span class="cx">             preloadEntry(key, subresourceInfo, frameID);
</span><span class="cx">         else {
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheSpeculativeLoadManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -51,11 +51,12 @@
</span><span class="cx">     void registerLoad(const GlobalFrameID&amp;, const WebCore::ResourceRequest&amp;, const Key&amp; resourceKey);
</span><span class="cx"> 
</span><span class="cx">     typedef std::function&lt;void (std::unique_ptr&lt;Entry&gt;)&gt; RetrieveCompletionHandler;
</span><del>-    bool retrieve(const GlobalFrameID&amp;, const Key&amp; storageKey, const RetrieveCompletionHandler&amp;);
</del><ins>+    bool retrieve(const GlobalFrameID&amp;, const Key&amp; storageKey, const WebCore::ResourceRequest&amp;, const RetrieveCompletionHandler&amp;);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    enum class WasRevalidated { No, Yes };
-    void addPreloadedEntry(std::unique_ptr&lt;Entry&gt;, const GlobalFrameID&amp;, WasRevalidated);
</del><ins>+    class PreloadedEntry;
+
+    void addPreloadedEntry(std::unique_ptr&lt;Entry&gt;, const GlobalFrameID&amp;, std::unique_ptr&lt;WebCore::ResourceRequest&gt; revalidationRequest = nullptr);
</ins><span class="cx">     void preloadEntry(const Key&amp;, const SubresourceInfo&amp;, const GlobalFrameID&amp;);
</span><span class="cx">     void retrieveEntryFromStorage(const Key&amp;, const RetrieveCompletionHandler&amp;);
</span><span class="cx">     void revalidateEntry(std::unique_ptr&lt;Entry&gt;, const SubresourceInfo&amp;, const GlobalFrameID&amp;);
</span><span class="lines">@@ -63,6 +64,9 @@
</span><span class="cx">     void retrieveSubresourcesEntry(const Key&amp; storageKey, std::function&lt;void (std::unique_ptr&lt;SubresourcesEntry&gt;)&gt;);
</span><span class="cx">     void startSpeculativeRevalidation(const GlobalFrameID&amp;, SubresourcesEntry&amp;);
</span><span class="cx"> 
</span><ins>+    static bool canUsePreloadedEntry(const PreloadedEntry&amp;, const WebCore::ResourceRequest&amp; actualRequest);
+    static bool canUsePendingPreload(const SpeculativeLoad&amp;, const WebCore::ResourceRequest&amp; actualRequest);
+
</ins><span class="cx">     Storage&amp; m_storage;
</span><span class="cx"> 
</span><span class="cx">     class PendingFrameLoad;
</span><span class="lines">@@ -71,7 +75,6 @@
</span><span class="cx">     HashMap&lt;Key, std::unique_ptr&lt;SpeculativeLoad&gt;&gt; m_pendingPreloads;
</span><span class="cx">     HashMap&lt;Key, std::unique_ptr&lt;Vector&lt;RetrieveCompletionHandler&gt;&gt;&gt; m_pendingRetrieveRequests;
</span><span class="cx"> 
</span><del>-    class PreloadedEntry;
</del><span class="cx">     HashMap&lt;Key, std::unique_ptr&lt;PreloadedEntry&gt;&gt; m_preloadedEntries;
</span><span class="cx"> 
</span><span class="cx">     class ExpiringEntry;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheSubresourcesEntrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> {
</span><span class="cx">     encoder &lt;&lt; firstPartyForCookies;
</span><span class="cx">     encoder &lt;&lt; isTransient;
</span><del>-    encoder &lt;&lt; httpUserAgent;
</del><ins>+    requestHeaders.encode(encoder);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool SubresourceInfo::decode(Decoder&amp; decoder, SubresourceInfo&amp; info)
</span><span class="lines">@@ -49,26 +49,11 @@
</span><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(info.isTransient))
</span><span class="cx">         return false;
</span><del>-    if (!decoder.decode(info.httpUserAgent))
</del><ins>+    if (!WebCore::HTTPHeaderMap::decode(decoder, info.requestHeaders))
</ins><span class="cx">         return false;
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SubresourceInfo::SubresourceInfo(const SubresourceInfo&amp; subresourceInfo)
-    : firstPartyForCookies(subresourceInfo.firstPartyForCookies.isolatedCopy())
-    , httpUserAgent(subresourceInfo.httpUserAgent.isolatedCopy())
-    , isTransient(subresourceInfo.isTransient)
-{
-}
-
-SubresourceInfo&amp; SubresourceInfo::operator=(const SubresourceInfo&amp; other)
-{
-    firstPartyForCookies = other.firstPartyForCookies.isolatedCopy();
-    httpUserAgent = other.httpUserAgent.isolatedCopy();
-    isTransient = other.isTransient;
-    return *this;
-}
-
</del><span class="cx"> Storage::Record SubresourcesEntry::encodeAsStorageRecord() const
</span><span class="cx"> {
</span><span class="cx">     Encoder encoder;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheSubresourcesEntryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h (198740 => 198741)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h        2016-03-28 15:57:49 UTC (rev 198740)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h        2016-03-28 16:04:33 UTC (rev 198741)
</span><span class="lines">@@ -39,23 +39,21 @@
</span><span class="cx"> namespace NetworkCache {
</span><span class="cx"> 
</span><span class="cx"> struct SubresourceInfo {
</span><ins>+    WTF_MAKE_FAST_ALLOCATED;
+public:
+
</ins><span class="cx">     void encode(Encoder&amp;) const;
</span><span class="cx">     static bool decode(Decoder&amp;, SubresourceInfo&amp;);
</span><span class="cx"> 
</span><span class="cx">     SubresourceInfo() = default;
</span><span class="cx">     SubresourceInfo(const WebCore::ResourceRequest&amp; request, bool isTransient = false)
</span><span class="cx">         : firstPartyForCookies(request.firstPartyForCookies())
</span><del>-        , httpUserAgent(request.httpUserAgent())
</del><ins>+        , requestHeaders(request.httpHeaderFields())
</ins><span class="cx">         , isTransient(isTransient)
</span><span class="cx">     { }
</span><span class="cx"> 
</span><del>-    SubresourceInfo(const SubresourceInfo&amp;);
-    SubresourceInfo(SubresourceInfo&amp;&amp;) = default;
-    SubresourceInfo&amp; operator=(const SubresourceInfo&amp;);
-    SubresourceInfo&amp; operator=(SubresourceInfo&amp;&amp;) = default;
-
</del><span class="cx">     WebCore::URL firstPartyForCookies;
</span><del>-    String httpUserAgent;
</del><ins>+    WebCore::HTTPHeaderMap requestHeaders;
</ins><span class="cx">     bool isTransient { false };
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>