Diff
Modified: trunk/Source/WebCore/ChangeLog (197938 => 197939)
--- trunk/Source/WebCore/ChangeLog 2016-03-10 16:28:52 UTC (rev 197938)
+++ trunk/Source/WebCore/ChangeLog 2016-03-10 16:57:11 UTC (rev 197939)
@@ -1,3 +1,16 @@
+2016-03-10 Chris Dumez <[email protected]>
+
+ Speculative revalidation requests do not have their 'first party for cookies' URL set
+ https://bugs.webkit.org/show_bug.cgi?id=155284
+ <rdar://problem/25053203>
+
+ Reviewed by Antti Koivisto.
+
+ Export a few more symbols so they can be used in WebKit2.
+
+ * platform/URL.h:
+ * platform/network/ResourceRequestBase.h:
+
2016-02-22 Jer Noble <[email protected]>
Enable AVFoundationNSURLSessionEnabled by default
Modified: trunk/Source/WebCore/platform/URL.h (197938 => 197939)
--- trunk/Source/WebCore/platform/URL.h 2016-03-10 16:28:52 UTC (rev 197938)
+++ trunk/Source/WebCore/platform/URL.h 2016-03-10 16:57:11 UTC (rev 197939)
@@ -85,7 +85,7 @@
// Makes a deep copy. Helpful only if you need to use a URL on another
// thread. Since the underlying StringImpl objects are immutable, there's
// no other reason to ever prefer isolatedCopy() over plain old assignment.
- URL isolatedCopy() const;
+ WEBCORE_EXPORT URL isolatedCopy() const;
bool isNull() const;
bool isEmpty() const;
Modified: trunk/Source/WebCore/platform/network/ResourceRequestBase.h (197938 => 197939)
--- trunk/Source/WebCore/platform/network/ResourceRequestBase.h 2016-03-10 16:28:52 UTC (rev 197938)
+++ trunk/Source/WebCore/platform/network/ResourceRequestBase.h 2016-03-10 16:57:11 UTC (rev 197939)
@@ -74,7 +74,7 @@
void setTimeoutInterval(double timeoutInterval);
WEBCORE_EXPORT const URL& firstPartyForCookies() const;
- void setFirstPartyForCookies(const URL& firstPartyForCookies);
+ WEBCORE_EXPORT void setFirstPartyForCookies(const URL&);
WEBCORE_EXPORT const String& httpMethod() const;
WEBCORE_EXPORT void setHTTPMethod(const String& httpMethod);
Modified: trunk/Source/WebKit2/ChangeLog (197938 => 197939)
--- trunk/Source/WebKit2/ChangeLog 2016-03-10 16:28:52 UTC (rev 197938)
+++ trunk/Source/WebKit2/ChangeLog 2016-03-10 16:57:11 UTC (rev 197939)
@@ -1,3 +1,64 @@
+2016-03-10 Chris Dumez <[email protected]>
+
+ Speculative revalidation requests do not have their 'first party for cookies' URL set
+ https://bugs.webkit.org/show_bug.cgi?id=155284
+ <rdar://problem/25053203>
+
+ Reviewed by Antti Koivisto.
+
+ Speculative revalidation requests did not have their 'first party for cookies'
+ URL set. This means the underlying NSURLRequest has a nil mainDocumentURL.
+ Without a way to determine whether the cookie is in a third-party context,
+ CFNetwork defaults to accepting all cookies for these resources.
+
+ * NetworkProcess/cache/NetworkCacheCoders.cpp:
+ (WebKit::NetworkCache::Coder<WebCore::URL>::encode):
+ (WebKit::NetworkCache::Coder<WebCore::URL>::decode):
+ * NetworkProcess/cache/NetworkCacheCoders.h:
+ Add template specialization to support encoding / decoding WebCore::URL.
+
+ * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
+ (WebKit::NetworkCache::constructRevalidationRequest):
+ Set the "first party for cookies" URL on the revalidation request.
+
+ (WebKit::NetworkCache::SpeculativeLoadManager::PendingFrameLoad::registerSubresourceLoad):
+ (WebKit::NetworkCache::SpeculativeLoadManager::PendingFrameLoad::saveToDiskIfReady):
+ Now keep the subresources' ResourceRequests, in addition to their key, so we can later
+ extract the 'first party for cookies' URL from the request and save it to disk.
+
+ (WebKit::NetworkCache::SpeculativeLoadManager::registerLoad):
+ Pass the ResourceRequest in addition to the key to
+ PendingFrameLoad::registerSubresourceLoad().
+
+ (WebKit::NetworkCache::SpeculativeLoadManager::revalidateEntry):
+ Add an extra SubresourceInfo parameter, in addition to the Entry, so we
+ have access to the first party for cookies URL. Pass this URL to
+ constructRevalidationRequest().
+
+ (WebKit::NetworkCache::SpeculativeLoadManager::preloadEntry):
+ Add an extra SubresourceInfo parameter, in addition to the Entry, so we
+ have access to the first party for cookies URL.
+
+ (WebKit::NetworkCache::SpeculativeLoadManager::startSpeculativeRevalidation):
+ Pass the SubresourceInfo to preloadEntry().
+
+ * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h:
+
+ * NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp:
+ (WebKit::NetworkCache::SubresourcesEntry::SubresourceInfo::encode):
+ (WebKit::NetworkCache::SubresourcesEntry::SubresourceInfo::decode):
+ Encode / Decode new firstPartyForCookies member.
+
+ (WebKit::NetworkCache::SubresourcesEntry::SubresourcesEntry):
+ (WebKit::NetworkCache::SubresourcesEntry::updateSubresourceLoads):
+ Take SubresourceLoad objects in, instead of simple Key objects so we have
+ access to the ResourceRequest. We extract the first party for cookies URL
+ from the request and pass it to the SubresourceInfo constructor.
+
+ * NetworkProcess/cache/NetworkCacheSubresourcesEntry.h:
+ (WebKit::NetworkCache::SubresourcesEntry::SubresourceInfo::SubresourceInfo):
+ (WebKit::NetworkCache::SubresourcesEntry::SubresourceLoad::SubresourceLoad):
+
2016-02-22 Jer Noble <[email protected]>
Enable AVFoundationNSURLSessionEnabled by default
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheCoders.cpp (197938 => 197939)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheCoders.cpp 2016-03-10 16:28:52 UTC (rev 197938)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheCoders.cpp 2016-03-10 16:57:11 UTC (rev 197939)
@@ -145,6 +145,20 @@
return decodeStringText<UChar>(decoder, length, result);
}
+void Coder<WebCore::URL>::encode(Encoder& encoder, const WebCore::URL& url)
+{
+ encoder << url.string();
+}
+
+bool Coder<WebCore::URL>::decode(Decoder& decoder, WebCore::URL& url)
+{
+ String urlAsString;
+ if (!decoder.decode(urlAsString))
+ return false;
+ url = "" urlAsString);
+ return true;
+}
+
void Coder<WebCore::CertificateInfo>::encode(Encoder& encoder, const WebCore::CertificateInfo& certificateInfo)
{
// FIXME: Cocoa CertificateInfo is a CF object tree. Generalize CF type coding so we don't need to use ArgumentCoder here.
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheCoders.h (197938 => 197939)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheCoders.h 2016-03-10 16:28:52 UTC (rev 197938)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheCoders.h 2016-03-10 16:57:11 UTC (rev 197939)
@@ -31,6 +31,7 @@
#include "NetworkCacheDecoder.h"
#include "NetworkCacheEncoder.h"
#include <WebCore/CertificateInfo.h>
+#include <WebCore/URL.h>
#include <utility>
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
@@ -248,6 +249,11 @@
static bool decode(Decoder&, String&);
};
+template<> struct Coder<WebCore::URL> {
+ static void encode(Encoder&, const WebCore::URL&);
+ static bool decode(Decoder&, WebCore::URL&);
+};
+
template<> struct Coder<WebCore::CertificateInfo> {
static void encode(Encoder&, const WebCore::CertificateInfo&);
static bool decode(Decoder&, WebCore::CertificateInfo&);
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp (197938 => 197939)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp 2016-03-10 16:28:52 UTC (rev 197938)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp 2016-03-10 16:57:11 UTC (rev 197939)
@@ -84,9 +84,10 @@
return Key(resourceKey.partition(), subresourcesType(), resourceKey.range(), resourceKey.identifier());
}
-static inline ResourceRequest constructRevalidationRequest(const Entry& entry)
+static inline ResourceRequest constructRevalidationRequest(const Entry& entry, const URL& firstPartyForCookies)
{
ResourceRequest revalidationRequest(entry.key().identifier());
+ revalidationRequest.setFirstPartyForCookies(firstPartyForCookies);
#if ENABLE(CACHE_PARTITIONING)
if (entry.key().hasPartition())
revalidationRequest.setCachePartition(entry.key().partition());
@@ -162,10 +163,10 @@
ASSERT(m_didRetrieveExistingEntry);
}
- void registerSubresource(const Key& subresourceKey)
+ void registerSubresourceLoad(const ResourceRequest& request, const Key& subresourceKey)
{
ASSERT(RunLoop::isMain());
- m_subresourceKeys.append(subresourceKey);
+ m_subresourceLoads.append(std::make_unique<SubresourceLoad>(request, subresourceKey));
m_loadHysteresisActivity.impulse();
}
@@ -207,27 +208,27 @@
if (!m_didFinishLoad || !m_didRetrieveExistingEntry)
return;
- if (m_subresourceKeys.isEmpty())
+ if (m_subresourceLoads.isEmpty())
return;
#if !LOG_DISABLED
LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) Saving to disk list of subresources for '%s':", m_mainResourceKey.identifier().utf8().data());
- for (auto& subresourceKey : m_subresourceKeys)
- LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) * Subresource: '%s'.", subresourceKey.identifier().utf8().data());
+ for (auto& subresourceLoad : m_subresourceLoads)
+ LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) * Subresource: '%s'.", subresourceLoad->key.identifier().utf8().data());
#endif
if (m_existingEntry) {
- m_existingEntry->updateSubresourceKeys(m_subresourceKeys);
+ m_existingEntry->updateSubresourceLoads(m_subresourceLoads);
m_storage.store(m_existingEntry->encodeAsStorageRecord(), [](const Data&) { });
} else {
- SubresourcesEntry entry(makeSubresourcesKey(m_mainResourceKey), m_subresourceKeys);
+ SubresourcesEntry entry(makeSubresourcesKey(m_mainResourceKey), m_subresourceLoads);
m_storage.store(entry.encodeAsStorageRecord(), [](const Data&) { });
}
}
Storage& m_storage;
Key m_mainResourceKey;
- Vector<Key> m_subresourceKeys;
+ Vector<std::unique_ptr<SubresourceLoad>> m_subresourceLoads;
std::function<void()> m_loadCompletionHandler;
HysteresisActivity m_loadHysteresisActivity;
std::unique_ptr<SubresourcesEntry> m_existingEntry;
@@ -311,7 +312,7 @@
}
if (auto* pendingFrameLoad = m_pendingFrameLoads.get(frameID))
- pendingFrameLoad->registerSubresource(resourceKey);
+ pendingFrameLoad->registerSubresourceLoad(request, resourceKey);
}
void SpeculativeLoadManager::addPreloadedEntry(std::unique_ptr<Entry> entry, const GlobalFrameID& frameID, WasRevalidated wasRevalidated)
@@ -368,7 +369,7 @@
return true;
}
-void SpeculativeLoadManager::revalidateEntry(std::unique_ptr<Entry> entry, const GlobalFrameID& frameID)
+void SpeculativeLoadManager::revalidateEntry(std::unique_ptr<Entry> entry, const SubresourceInfo& subresourceInfo, const GlobalFrameID& frameID)
{
ASSERT(entry);
ASSERT(entry->needsValidation());
@@ -379,8 +380,10 @@
if (!key.range().isEmpty())
return;
+ ResourceRequest revalidationRequest = constructRevalidationRequest(*entry, subresourceInfo.firstPartyForCookies);
+
LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) Speculatively revalidating '%s':", key.identifier().utf8().data());
- auto revalidator = std::make_unique<SpeculativeLoad>(frameID, constructRevalidationRequest(*entry), WTFMove(entry), [this, key, frameID](std::unique_ptr<Entry> revalidatedEntry) {
+ auto revalidator = std::make_unique<SpeculativeLoad>(frameID, revalidationRequest, WTFMove(entry), [this, key, frameID](std::unique_ptr<Entry> revalidatedEntry) {
ASSERT(!revalidatedEntry || !revalidatedEntry->needsValidation());
ASSERT(!revalidatedEntry || revalidatedEntry->key() == key);
@@ -399,10 +402,11 @@
m_pendingPreloads.add(key, WTFMove(revalidator));
}
-void SpeculativeLoadManager::preloadEntry(const Key& key, const GlobalFrameID& frameID)
+void SpeculativeLoadManager::preloadEntry(const Key& key, const SubresourceInfo& subResourceInfo, const GlobalFrameID& frameID)
{
m_pendingPreloads.add(key, nullptr);
- retrieveEntryFromStorage(key, [this, key, frameID](std::unique_ptr<Entry> entry) {
+ URLCapture firstPartyForCookies(subResourceInfo.firstPartyForCookies);
+ retrieveEntryFromStorage(key, [this, key, firstPartyForCookies, frameID](std::unique_ptr<Entry> entry) {
m_pendingPreloads.remove(key);
if (satisfyPendingRequests(key, entry.get())) {
@@ -415,7 +419,7 @@
return;
if (entry->needsValidation())
- revalidateEntry(WTFMove(entry), frameID);
+ revalidateEntry(WTFMove(entry), firstPartyForCookies.url(), frameID);
else
addPreloadedEntry(WTFMove(entry), frameID, WasRevalidated::No);
});
@@ -423,12 +427,13 @@
void SpeculativeLoadManager::startSpeculativeRevalidation(const GlobalFrameID& frameID, SubresourcesEntry& entry)
{
- for (auto& subresource : entry.subresources()) {
- auto key = subresource.key;
- if (!subresource.value.isTransient)
- preloadEntry(key, frameID);
+ for (auto& subresourcePair : entry.subresources()) {
+ auto key = subresourcePair.key;
+ auto subresourceInfo = subresourcePair.value;
+ if (!subresourceInfo.isTransient)
+ preloadEntry(key, subresourceInfo, frameID);
else {
- LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) Not preloading '%s' because it is marked as transient", subresource.key.identifier().utf8().data());
+ LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) Not preloading '%s' because it is marked as transient", key.identifier().utf8().data());
m_notPreloadedEntries.add(key, std::make_unique<ExpiringEntry>([this, key, frameID] {
logSpeculativeLoadingDiagnosticMessage(frameID, DiagnosticLoggingKeys::entryRightlyNotWarmedUpKey());
m_notPreloadedEntries.remove(key);
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h (197938 => 197939)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h 2016-03-10 16:28:52 UTC (rev 197938)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h 2016-03-10 16:57:11 UTC (rev 197939)
@@ -41,6 +41,7 @@
class Entry;
class SpeculativeLoad;
class SubresourcesEntry;
+struct SubresourceInfo;
class SpeculativeLoadManager {
public:
@@ -55,9 +56,9 @@
private:
enum class WasRevalidated { No, Yes };
void addPreloadedEntry(std::unique_ptr<Entry>, const GlobalFrameID&, WasRevalidated);
- void preloadEntry(const Key&, const GlobalFrameID&);
+ void preloadEntry(const Key&, const SubresourceInfo&, const GlobalFrameID&);
void retrieveEntryFromStorage(const Key&, const RetrieveCompletionHandler&);
- void revalidateEntry(std::unique_ptr<Entry>, const GlobalFrameID&);
+ void revalidateEntry(std::unique_ptr<Entry>, const SubresourceInfo&, const GlobalFrameID&);
bool satisfyPendingRequests(const Key&, Entry*);
void retrieveSubresourcesEntry(const Key& storageKey, std::function<void (std::unique_ptr<SubresourcesEntry>)>);
void startSpeculativeRevalidation(const GlobalFrameID&, SubresourcesEntry&);
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp (197938 => 197939)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp 2016-03-10 16:28:52 UTC (rev 197938)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp 2016-03-10 16:57:11 UTC (rev 197939)
@@ -36,6 +36,21 @@
namespace WebKit {
namespace NetworkCache {
+void SubresourceInfo::encode(Encoder& encoder) const
+{
+ encoder << firstPartyForCookies;
+ encoder << isTransient;
+}
+
+bool SubresourceInfo::decode(Decoder& decoder, SubresourceInfo& info)
+{
+ if (!decoder.decode(info.firstPartyForCookies))
+ return false;
+ if (!decoder.decode(info.isTransient))
+ return false;
+ return true;
+}
+
Storage::Record SubresourcesEntry::encodeAsStorageRecord() const
{
Encoder encoder;
@@ -69,23 +84,23 @@
ASSERT(m_key.type() == "subresources");
}
-SubresourcesEntry::SubresourcesEntry(Key&& key, const Vector<Key>& subresourceKeys)
+SubresourcesEntry::SubresourcesEntry(Key&& key, const Vector<std::unique_ptr<SubresourceLoad>>& subresourceLoads)
: m_key(WTFMove(key))
, m_timeStamp(std::chrono::system_clock::now())
{
ASSERT(m_key.type() == "subresources");
- for (auto& key : subresourceKeys)
- m_subresources.add(key, SubresourceInfo());
+ for (auto& subresourceLoad : subresourceLoads)
+ m_subresources.add(subresourceLoad->key, SubresourceInfo(subresourceLoad->request.firstPartyForCookies()));
}
-void SubresourcesEntry::updateSubresourceKeys(const Vector<Key>& subresourceKeys)
+void SubresourcesEntry::updateSubresourceLoads(const Vector<std::unique_ptr<SubresourceLoad>>& subresourceLoads)
{
auto oldSubresources = WTFMove(m_subresources);
// Mark keys that are common with last load as non-Transient.
- for (auto& key : subresourceKeys) {
- bool isTransient = !oldSubresources.contains(key);
- m_subresources.add(key, SubresourceInfo(isTransient));
+ for (auto& subresourceLoad : subresourceLoads) {
+ bool isTransient = !oldSubresources.contains(subresourceLoad->key);
+ m_subresources.add(subresourceLoad->key, SubresourceInfo(subresourceLoad->request.firstPartyForCookies(), isTransient));
}
}
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h (197938 => 197939)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h 2016-03-10 16:28:52 UTC (rev 197938)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h 2016-03-10 16:57:11 UTC (rev 197939)
@@ -31,24 +31,43 @@
#include "NetworkCacheDecoder.h"
#include "NetworkCacheEncoder.h"
#include "NetworkCacheStorage.h"
+#include <WebCore/ResourceRequest.h>
+#include <WebCore/URL.h>
#include <wtf/HashMap.h>
namespace WebKit {
namespace NetworkCache {
+struct SubresourceInfo {
+ void encode(Encoder&) const;
+ static bool decode(Decoder&, SubresourceInfo&);
+
+ SubresourceInfo() = default;
+ SubresourceInfo(const WebCore::URL& firstPartyForCookies, bool isTransient = false)
+ : firstPartyForCookies(firstPartyForCookies)
+ , isTransient(isTransient)
+ { }
+
+ WebCore::URL firstPartyForCookies;
+ bool isTransient { false };
+};
+
+struct SubresourceLoad {
+ WTF_MAKE_NONCOPYABLE(SubresourceLoad); WTF_MAKE_FAST_ALLOCATED;
+public:
+ SubresourceLoad(const WebCore::ResourceRequest& request, const Key& key)
+ : request(request)
+ , key(key)
+ { }
+
+ WebCore::ResourceRequest request;
+ Key key;
+};
+
class SubresourcesEntry {
WTF_MAKE_NONCOPYABLE(SubresourcesEntry); WTF_MAKE_FAST_ALLOCATED;
public:
- struct SubresourceInfo {
- void encode(Encoder& encoder) const { encoder << isTransient; }
- static bool decode(Decoder& decoder, SubresourceInfo& info) { return decoder.decode(info.isTransient); }
-
- SubresourceInfo() = default;
- SubresourceInfo(bool isTransient) : isTransient(isTransient) { }
-
- bool isTransient { false };
- };
- SubresourcesEntry(Key&&, const Vector<Key>& subresourceKeys);
+ SubresourcesEntry(Key&&, const Vector<std::unique_ptr<SubresourceLoad>>&);
explicit SubresourcesEntry(const Storage::Record&);
Storage::Record encodeAsStorageRecord() const;
@@ -58,7 +77,7 @@
std::chrono::system_clock::time_point timeStamp() const { return m_timeStamp; }
const HashMap<Key, SubresourceInfo>& subresources() const { return m_subresources; }
- void updateSubresourceKeys(const Vector<Key>&);
+ void updateSubresourceLoads(const Vector<std::unique_ptr<SubresourceLoad>>&);
private:
Key m_key;