summaryrefslogtreecommitdiff
path: root/Source/WebKit2/WebProcess/Storage
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/WebProcess/Storage')
-rw-r--r--Source/WebKit2/WebProcess/Storage/StorageAreaImpl.cpp15
-rw-r--r--Source/WebKit2/WebProcess/Storage/StorageAreaImpl.h37
-rw-r--r--Source/WebKit2/WebProcess/Storage/StorageAreaMap.cpp78
-rw-r--r--Source/WebKit2/WebProcess/Storage/StorageAreaMap.h14
-rw-r--r--Source/WebKit2/WebProcess/Storage/StorageNamespaceImpl.cpp198
-rw-r--r--Source/WebKit2/WebProcess/Storage/StorageNamespaceImpl.h47
-rw-r--r--Source/WebKit2/WebProcess/Storage/WebStorageNamespaceProvider.cpp89
-rw-r--r--Source/WebKit2/WebProcess/Storage/WebStorageNamespaceProvider.h51
8 files changed, 400 insertions, 129 deletions
diff --git a/Source/WebKit2/WebProcess/Storage/StorageAreaImpl.cpp b/Source/WebKit2/WebProcess/Storage/StorageAreaImpl.cpp
index 1002c2141..be8507a31 100644
--- a/Source/WebKit2/WebProcess/Storage/StorageAreaImpl.cpp
+++ b/Source/WebKit2/WebProcess/Storage/StorageAreaImpl.cpp
@@ -28,10 +28,10 @@
#include "StorageAreaMap.h"
#include <WebCore/Document.h>
-#include <WebCore/ExceptionCode.h>
#include <WebCore/Frame.h>
#include <WebCore/Page.h>
#include <WebCore/SchemeRegistry.h>
+#include <WebCore/SecurityOriginData.h>
#include <WebCore/Settings.h>
using namespace WebCore;
@@ -44,14 +44,14 @@ static uint64_t generateStorageAreaID()
return ++storageAreaID;
}
-PassRefPtr<StorageAreaImpl> StorageAreaImpl::create(PassRefPtr<StorageAreaMap> storageAreaMap)
+Ref<StorageAreaImpl> StorageAreaImpl::create(Ref<StorageAreaMap>&& storageAreaMap)
{
- return adoptRef(new StorageAreaImpl(storageAreaMap));
+ return adoptRef(*new StorageAreaImpl(WTFMove(storageAreaMap)));
}
-StorageAreaImpl::StorageAreaImpl(PassRefPtr<StorageAreaMap> storageAreaMap)
+StorageAreaImpl::StorageAreaImpl(Ref<StorageAreaMap>&& storageAreaMap)
: m_storageAreaID(generateStorageAreaID())
- , m_storageAreaMap(storageAreaMap)
+ , m_storageAreaMap(WTFMove(storageAreaMap))
{
}
@@ -127,4 +127,9 @@ void StorageAreaImpl::closeDatabaseIfIdle()
ASSERT_NOT_REACHED();
}
+WebCore::SecurityOriginData StorageAreaImpl::securityOrigin() const
+{
+ return WebCore::SecurityOriginData::fromSecurityOrigin(m_storageAreaMap->securityOrigin());
+}
+
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/Storage/StorageAreaImpl.h b/Source/WebKit2/WebProcess/Storage/StorageAreaImpl.h
index a4d599a60..dda47c8d8 100644
--- a/Source/WebKit2/WebProcess/Storage/StorageAreaImpl.h
+++ b/Source/WebKit2/WebProcess/Storage/StorageAreaImpl.h
@@ -31,37 +31,42 @@
#include <wtf/HashCountedSet.h>
#include <wtf/HashMap.h>
+namespace WebCore {
+class SecurityOrigin;
+}
+
namespace WebKit {
class StorageAreaMap;
class StorageAreaImpl final : public WebCore::StorageArea {
public:
- static PassRefPtr<StorageAreaImpl> create(PassRefPtr<StorageAreaMap>);
+ static Ref<StorageAreaImpl> create(Ref<StorageAreaMap>&&);
virtual ~StorageAreaImpl();
uint64_t storageAreaID() const { return m_storageAreaID; }
private:
- StorageAreaImpl(PassRefPtr<StorageAreaMap>);
+ StorageAreaImpl(Ref<StorageAreaMap>&&);
// WebCore::StorageArea.
- virtual unsigned length() override;
- virtual String key(unsigned index) override;
- virtual String item(const String& key) override;
- virtual void setItem(WebCore::Frame* sourceFrame, const String& key, const String& value, bool& quotaException) override;
- virtual void removeItem(WebCore::Frame* sourceFrame, const String& key) override;
- virtual void clear(WebCore::Frame* sourceFrame) override;
- virtual bool contains(const String& key) override;
- virtual bool canAccessStorage(WebCore::Frame*) override;
- virtual WebCore::StorageType storageType() const override;
- virtual size_t memoryBytesUsedByCache() override;
- virtual void incrementAccessCount() override;
- virtual void decrementAccessCount() override;
- virtual void closeDatabaseIfIdle() override;
+ unsigned length() override;
+ String key(unsigned index) override;
+ String item(const String& key) override;
+ void setItem(WebCore::Frame* sourceFrame, const String& key, const String& value, bool& quotaException) override;
+ void removeItem(WebCore::Frame* sourceFrame, const String& key) override;
+ void clear(WebCore::Frame* sourceFrame) override;
+ bool contains(const String& key) override;
+ bool canAccessStorage(WebCore::Frame*) override;
+ WebCore::StorageType storageType() const override;
+ size_t memoryBytesUsedByCache() override;
+ void incrementAccessCount() override;
+ void decrementAccessCount() override;
+ void closeDatabaseIfIdle() override;
+ WebCore::SecurityOriginData securityOrigin() const override;
uint64_t m_storageAreaID;
- RefPtr<StorageAreaMap> m_storageAreaMap;
+ Ref<StorageAreaMap> m_storageAreaMap;
};
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/Storage/StorageAreaMap.cpp b/Source/WebKit2/WebProcess/Storage/StorageAreaMap.cpp
index 8d3b6397d..a2650d1b3 100644
--- a/Source/WebKit2/WebProcess/Storage/StorageAreaMap.cpp
+++ b/Source/WebKit2/WebProcess/Storage/StorageAreaMap.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "StorageAreaMap.h"
-#include "SecurityOriginData.h"
#include "StorageAreaImpl.h"
#include "StorageAreaMapMessages.h"
#include "StorageManagerMessages.h"
@@ -35,12 +34,15 @@
#include "WebPageGroupProxy.h"
#include "WebProcess.h"
#include <WebCore/DOMWindow.h>
+#include <WebCore/Document.h>
#include <WebCore/MainFrame.h>
#include <WebCore/Page.h>
#include <WebCore/PageGroup.h>
+#include <WebCore/SecurityOriginData.h>
#include <WebCore/Storage.h>
#include <WebCore/StorageEventDispatcher.h>
#include <WebCore/StorageMap.h>
+#include <WebCore/StorageType.h>
using namespace WebCore;
@@ -52,32 +54,52 @@ static uint64_t generateStorageMapID()
return ++storageMapID;
}
-PassRefPtr<StorageAreaMap> StorageAreaMap::create(StorageNamespaceImpl* storageNamespace, PassRefPtr<WebCore::SecurityOrigin> securityOrigin)
+Ref<StorageAreaMap> StorageAreaMap::create(StorageNamespaceImpl* storageNamespace, Ref<WebCore::SecurityOrigin>&& securityOrigin)
{
- return adoptRef(new StorageAreaMap(storageNamespace, securityOrigin));
+ return adoptRef(*new StorageAreaMap(storageNamespace, WTFMove(securityOrigin)));
}
-StorageAreaMap::StorageAreaMap(StorageNamespaceImpl* storageNamespace, PassRefPtr<WebCore::SecurityOrigin> securityOrigin)
- : m_storageMapID(generateStorageMapID())
+StorageAreaMap::StorageAreaMap(StorageNamespaceImpl* storageNamespace, Ref<WebCore::SecurityOrigin>&& securityOrigin)
+ : m_storageNamespace(*storageNamespace)
+ , m_storageMapID(generateStorageMapID())
, m_storageType(storageNamespace->storageType())
, m_storageNamespaceID(storageNamespace->storageNamespaceID())
, m_quotaInBytes(storageNamespace->quotaInBytes())
- , m_securityOrigin(securityOrigin)
+ , m_securityOrigin(WTFMove(securityOrigin))
, m_currentSeed(0)
, m_hasPendingClear(false)
, m_hasPendingGetValues(false)
{
- if (m_storageType == LocalStorage)
- WebProcess::shared().parentProcessConnection()->send(Messages::StorageManager::CreateLocalStorageMap(m_storageMapID, storageNamespace->storageNamespaceID(), SecurityOriginData::fromSecurityOrigin(m_securityOrigin.get())), 0);
- else
- WebProcess::shared().parentProcessConnection()->send(Messages::StorageManager::CreateSessionStorageMap(m_storageMapID, storageNamespace->storageNamespaceID(), SecurityOriginData::fromSecurityOrigin(m_securityOrigin.get())), 0);
- WebProcess::shared().addMessageReceiver(Messages::StorageAreaMap::messageReceiverName(), m_storageMapID, *this);
+ switch (m_storageType) {
+ case StorageType::Local:
+ case StorageType::TransientLocal:
+ if (SecurityOrigin* topLevelOrigin = storageNamespace->topLevelOrigin())
+ WebProcess::singleton().parentProcessConnection()->send(Messages::StorageManager::CreateTransientLocalStorageMap(m_storageMapID, storageNamespace->storageNamespaceID(), SecurityOriginData::fromSecurityOrigin(*topLevelOrigin), SecurityOriginData::fromSecurityOrigin(m_securityOrigin)), 0);
+ else
+ WebProcess::singleton().parentProcessConnection()->send(Messages::StorageManager::CreateLocalStorageMap(m_storageMapID, storageNamespace->storageNamespaceID(), SecurityOriginData::fromSecurityOrigin(m_securityOrigin)), 0);
+
+ break;
+
+ case StorageType::Session:
+ WebProcess::singleton().parentProcessConnection()->send(Messages::StorageManager::CreateSessionStorageMap(m_storageMapID, storageNamespace->storageNamespaceID(), SecurityOriginData::fromSecurityOrigin(m_securityOrigin)), 0);
+ break;
+
+ case StorageType::EphemeralLocal:
+ // The UI process is not involved for EphemeralLocal storages.
+ return;
+ }
+
+ WebProcess::singleton().addMessageReceiver(Messages::StorageAreaMap::messageReceiverName(), m_storageMapID, *this);
}
StorageAreaMap::~StorageAreaMap()
{
- WebProcess::shared().parentProcessConnection()->send(Messages::StorageManager::DestroyStorageMap(m_storageMapID), 0);
- WebProcess::shared().removeMessageReceiver(Messages::StorageAreaMap::messageReceiverName(), m_storageMapID);
+ if (m_storageType != StorageType::EphemeralLocal) {
+ WebProcess::singleton().parentProcessConnection()->send(Messages::StorageManager::DestroyStorageMap(m_storageMapID), 0);
+ WebProcess::singleton().removeMessageReceiver(Messages::StorageAreaMap::messageReceiverName(), m_storageMapID);
+ }
+
+ m_storageNamespace->didDestroyStorageAreaMap(*this);
}
unsigned StorageAreaMap::length()
@@ -118,7 +140,7 @@ void StorageAreaMap::setItem(Frame* sourceFrame, StorageAreaImpl* sourceArea, co
m_pendingValueChanges.add(key);
- WebProcess::shared().parentProcessConnection()->send(Messages::StorageManager::SetItem(m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, key, value, sourceFrame->document()->url()), 0);
+ WebProcess::singleton().parentProcessConnection()->send(Messages::StorageManager::SetItem(m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, key, value, sourceFrame->document()->url()), 0);
}
void StorageAreaMap::removeItem(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea, const String& key)
@@ -134,7 +156,7 @@ void StorageAreaMap::removeItem(WebCore::Frame* sourceFrame, StorageAreaImpl* so
m_pendingValueChanges.add(key);
- WebProcess::shared().parentProcessConnection()->send(Messages::StorageManager::RemoveItem(m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, key, sourceFrame->document()->url()), 0);
+ WebProcess::singleton().parentProcessConnection()->send(Messages::StorageManager::RemoveItem(m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, key, sourceFrame->document()->url()), 0);
}
void StorageAreaMap::clear(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea)
@@ -143,7 +165,7 @@ void StorageAreaMap::clear(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceA
m_hasPendingClear = true;
m_storageMap = StorageMap::create(m_quotaInBytes);
- WebProcess::shared().parentProcessConnection()->send(Messages::StorageManager::Clear(m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, sourceFrame->document()->url()), 0);
+ WebProcess::singleton().parentProcessConnection()->send(Messages::StorageManager::Clear(m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, sourceFrame->document()->url()), 0);
}
bool StorageAreaMap::contains(const String& key)
@@ -172,7 +194,7 @@ void StorageAreaMap::loadValuesIfNeeded()
// FIXME: This should use a special sendSync flag to indicate that we don't want to process incoming messages while waiting for a reply.
// (This flag does not yet exist). Since loadValuesIfNeeded() ends up being called from within JavaScript code, processing incoming synchronous messages
// could lead to weird reentrency bugs otherwise.
- WebProcess::shared().parentProcessConnection()->sendSync(Messages::StorageManager::GetValues(m_storageMapID, m_currentSeed), Messages::StorageManager::GetValues::Reply(values), 0);
+ WebProcess::singleton().parentProcessConnection()->sendSync(Messages::StorageManager::GetValues(m_storageMapID, m_currentSeed), Messages::StorageManager::GetValues::Reply(values), 0);
m_storageMap = StorageMap::create(m_quotaInBytes);
m_storageMap->importItems(values);
@@ -248,7 +270,7 @@ void StorageAreaMap::applyChange(const String& key, const String& newValue)
if (!key) {
// A null key means clear.
- RefPtr<StorageMap> newStorageMap = StorageMap::create(m_quotaInBytes);
+ auto newStorageMap = StorageMap::create(m_quotaInBytes);
// Any changes that were made locally after the clear must still be kept around in the new map.
for (auto it = m_pendingValueChanges.begin().keys(), end = m_pendingValueChanges.end().keys(); it != end; ++it) {
@@ -264,7 +286,7 @@ void StorageAreaMap::applyChange(const String& key, const String& newValue)
newStorageMap->setItemIgnoringQuota(key, oldValue);
}
- m_storageMap = newStorageMap.release();
+ m_storageMap = WTFMove(newStorageMap);
return;
}
@@ -288,7 +310,7 @@ void StorageAreaMap::dispatchStorageEvent(uint64_t sourceStorageAreaID, const St
applyChange(key, newValue);
}
- if (storageType() == SessionStorage)
+ if (storageType() == StorageType::Session)
dispatchSessionStorageEvent(sourceStorageAreaID, key, oldValue, newValue, urlString);
else
dispatchLocalStorageEvent(sourceStorageAreaID, key, oldValue, newValue, urlString);
@@ -301,11 +323,11 @@ void StorageAreaMap::clearCache()
void StorageAreaMap::dispatchSessionStorageEvent(uint64_t sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString)
{
- ASSERT(storageType() == SessionStorage);
+ ASSERT(storageType() == StorageType::Session);
// Namespace IDs for session storage namespaces are equivalent to web page IDs
// so we can get the right page here.
- WebPage* webPage = WebProcess::shared().webPage(m_storageNamespaceID);
+ WebPage* webPage = WebProcess::singleton().webPage(m_storageNamespaceID);
if (!webPage)
return;
@@ -314,7 +336,7 @@ void StorageAreaMap::dispatchSessionStorageEvent(uint64_t sourceStorageAreaID, c
Page* page = webPage->corePage();
for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
Document* document = frame->document();
- if (!document->securityOrigin()->equal(m_securityOrigin.get()))
+ if (!document->securityOrigin().equal(m_securityOrigin.ptr()))
continue;
Storage* storage = document->domWindow()->optionalSessionStorage();
@@ -330,21 +352,21 @@ void StorageAreaMap::dispatchSessionStorageEvent(uint64_t sourceStorageAreaID, c
frames.append(frame);
}
- StorageEventDispatcher::dispatchLocalStorageEventsToFrames(page->group(), frames, key, oldValue, newValue, urlString, m_securityOrigin.get());
+ StorageEventDispatcher::dispatchSessionStorageEventsToFrames(*page, frames, key, oldValue, newValue, urlString, SecurityOriginData::fromSecurityOrigin(m_securityOrigin));
}
void StorageAreaMap::dispatchLocalStorageEvent(uint64_t sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString)
{
- ASSERT(storageType() == LocalStorage);
+ ASSERT(isLocalStorage(storageType()));
Vector<RefPtr<Frame>> frames;
- PageGroup& pageGroup = *WebProcess::shared().webPageGroup(m_storageNamespaceID)->corePageGroup();
+ PageGroup& pageGroup = *WebProcess::singleton().webPageGroup(m_storageNamespaceID)->corePageGroup();
const HashSet<Page*>& pages = pageGroup.pages();
for (HashSet<Page*>::const_iterator it = pages.begin(), end = pages.end(); it != end; ++it) {
for (Frame* frame = &(*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
Document* document = frame->document();
- if (!document->securityOrigin()->equal(m_securityOrigin.get()))
+ if (!document->securityOrigin().equal(m_securityOrigin.ptr()))
continue;
Storage* storage = document->domWindow()->optionalLocalStorage();
@@ -361,7 +383,7 @@ void StorageAreaMap::dispatchLocalStorageEvent(uint64_t sourceStorageAreaID, con
}
}
- StorageEventDispatcher::dispatchLocalStorageEventsToFrames(pageGroup, frames, key, oldValue, newValue, urlString, m_securityOrigin.get());
+ StorageEventDispatcher::dispatchLocalStorageEventsToFrames(pageGroup, frames, key, oldValue, newValue, urlString, SecurityOriginData::fromSecurityOrigin(m_securityOrigin));
}
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/Storage/StorageAreaMap.h b/Source/WebKit2/WebProcess/Storage/StorageAreaMap.h
index 0d6c50616..b9e43e807 100644
--- a/Source/WebKit2/WebProcess/Storage/StorageAreaMap.h
+++ b/Source/WebKit2/WebProcess/Storage/StorageAreaMap.h
@@ -31,8 +31,8 @@
#include <WebCore/StorageArea.h>
#include <wtf/Forward.h>
#include <wtf/HashCountedSet.h>
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
namespace WebCore {
class SecurityOrigin;
@@ -46,7 +46,7 @@ class StorageNamespaceImpl;
class StorageAreaMap : public RefCounted<StorageAreaMap>, private IPC::MessageReceiver {
public:
- static PassRefPtr<StorageAreaMap> create(StorageNamespaceImpl*, PassRefPtr<WebCore::SecurityOrigin>);
+ static Ref<StorageAreaMap> create(StorageNamespaceImpl*, Ref<WebCore::SecurityOrigin>&&);
~StorageAreaMap();
WebCore::StorageType storageType() const { return m_storageType; }
@@ -59,11 +59,13 @@ public:
void clear(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea);
bool contains(const String& key);
+ const WebCore::SecurityOrigin& securityOrigin() const { return m_securityOrigin.get(); }
+
private:
- StorageAreaMap(StorageNamespaceImpl*, PassRefPtr<WebCore::SecurityOrigin>);
+ StorageAreaMap(StorageNamespaceImpl*, Ref<WebCore::SecurityOrigin>&&);
// IPC::MessageReceiver
- virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override;
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
void didGetValues(uint64_t storageMapSeed);
void didSetItem(uint64_t storageMapSeed, const String& key, bool quotaError);
@@ -82,12 +84,14 @@ private:
void dispatchSessionStorageEvent(uint64_t sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString);
void dispatchLocalStorageEvent(uint64_t sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString);
+ Ref<StorageNamespaceImpl> m_storageNamespace;
+
uint64_t m_storageMapID;
WebCore::StorageType m_storageType;
uint64_t m_storageNamespaceID;
unsigned m_quotaInBytes;
- RefPtr<WebCore::SecurityOrigin> m_securityOrigin;
+ Ref<WebCore::SecurityOrigin> m_securityOrigin;
RefPtr<WebCore::StorageMap> m_storageMap;
diff --git a/Source/WebKit2/WebProcess/Storage/StorageNamespaceImpl.cpp b/Source/WebKit2/WebProcess/Storage/StorageNamespaceImpl.cpp
index 3845913b2..2abbc5c21 100644
--- a/Source/WebKit2/WebProcess/Storage/StorageNamespaceImpl.cpp
+++ b/Source/WebKit2/WebProcess/Storage/StorageNamespaceImpl.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,103 +31,189 @@
#include "WebPage.h"
#include "WebPageGroupProxy.h"
#include "WebProcess.h"
-#include <WebCore/GroupSettings.h>
+#include <WebCore/Frame.h>
#include <WebCore/PageGroup.h>
#include <WebCore/SecurityOrigin.h>
#include <WebCore/Settings.h>
-#include <wtf/NeverDestroyed.h>
+#include <WebCore/StorageType.h>
using namespace WebCore;
namespace WebKit {
-typedef HashMap<uint64_t, StorageNamespaceImpl*> LocalStorageNamespaceMap;
-
-static LocalStorageNamespaceMap& localStorageNamespaceMap()
+RefPtr<StorageNamespaceImpl> StorageNamespaceImpl::createSessionStorageNamespace(uint64_t identifier, unsigned quotaInBytes)
{
- static NeverDestroyed<LocalStorageNamespaceMap> localStorageNamespaceMap;
- return localStorageNamespaceMap;
+ return adoptRef(new StorageNamespaceImpl(StorageType::Session, identifier, nullptr, quotaInBytes));
}
-PassRefPtr<StorageNamespaceImpl> StorageNamespaceImpl::createLocalStorageNamespace(PageGroup* pageGroup)
+RefPtr<StorageNamespaceImpl> StorageNamespaceImpl::createEphemeralLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes)
{
- uint64_t pageGroupID = WebProcess::shared().webPageGroup(pageGroup)->pageGroupID();
-
- LocalStorageNamespaceMap::AddResult result = localStorageNamespaceMap().add(pageGroupID, nullptr);
- if (!result.isNewEntry)
- return result.iterator->value;
-
- unsigned quota = pageGroup->groupSettings().localStorageQuotaBytes();
- RefPtr<StorageNamespaceImpl> localStorageNamespace = adoptRef(new StorageNamespaceImpl(LocalStorage, pageGroupID, quota));
+ return adoptRef(new StorageNamespaceImpl(StorageType::EphemeralLocal, identifier, nullptr, quotaInBytes));
+}
- result.iterator->value = localStorageNamespace.get();
- return localStorageNamespace.release();
+RefPtr<StorageNamespaceImpl> StorageNamespaceImpl::createLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes)
+{
+ return adoptRef(new StorageNamespaceImpl(StorageType::Local, identifier, nullptr, quotaInBytes));
}
-PassRefPtr<StorageNamespaceImpl> StorageNamespaceImpl::createSessionStorageNamespace(WebPage* webPage)
+RefPtr<StorageNamespaceImpl> StorageNamespaceImpl::createTransientLocalStorageNamespace(uint64_t identifier, WebCore::SecurityOrigin& topLevelOrigin, uint64_t quotaInBytes)
{
- return adoptRef(new StorageNamespaceImpl(SessionStorage, webPage->pageID(), webPage->corePage()->settings().sessionStorageQuota()));
+ return adoptRef(new StorageNamespaceImpl(StorageType::TransientLocal, identifier, &topLevelOrigin, quotaInBytes));
}
-StorageNamespaceImpl::StorageNamespaceImpl(WebCore::StorageType storageType, uint64_t storageNamespaceID, unsigned quotaInBytes)
+StorageNamespaceImpl::StorageNamespaceImpl(WebCore::StorageType storageType, uint64_t storageNamespaceID, WebCore::SecurityOrigin* topLevelOrigin, unsigned quotaInBytes)
: m_storageType(storageType)
, m_storageNamespaceID(storageNamespaceID)
+ , m_topLevelOrigin(topLevelOrigin)
, m_quotaInBytes(quotaInBytes)
{
}
StorageNamespaceImpl::~StorageNamespaceImpl()
{
- if (m_storageType == LocalStorage) {
- ASSERT(localStorageNamespaceMap().contains(m_storageNamespaceID));
- localStorageNamespaceMap().remove(m_storageNamespaceID);
- }
}
-PassRefPtr<StorageArea> StorageNamespaceImpl::storageArea(PassRefPtr<SecurityOrigin> securityOrigin)
+void StorageNamespaceImpl::didDestroyStorageAreaMap(StorageAreaMap& map)
{
- auto result = m_storageAreaMaps.add(securityOrigin.get(), nullptr);
- if (result.isNewEntry)
- result.iterator->value = StorageAreaMap::create(this, securityOrigin);
-
- return StorageAreaImpl::create(result.iterator->value);
+ m_storageAreaMaps.remove(SecurityOriginData::fromSecurityOrigin(map.securityOrigin()));
}
-PassRefPtr<StorageNamespace> StorageNamespaceImpl::copy(Page* newPage)
+RefPtr<StorageArea> StorageNamespaceImpl::storageArea(const SecurityOriginData& securityOrigin)
{
- ASSERT(m_storageNamespaceID);
+ if (m_storageType == StorageType::EphemeralLocal)
+ return ephemeralLocalStorageArea(securityOrigin);
- return createSessionStorageNamespace(WebPage::fromCorePage(newPage));
-}
+ RefPtr<StorageAreaMap> map;
-void StorageNamespaceImpl::close()
-{
- // FIXME: Implement this.
- ASSERT_NOT_REACHED();
-}
+ auto& slot = m_storageAreaMaps.add(securityOrigin, nullptr).iterator->value;
+ if (!slot) {
+ map = StorageAreaMap::create(this, securityOrigin.securityOrigin());
+ slot = map.get();
+ } else
+ map = slot;
-void StorageNamespaceImpl::clearOriginForDeletion(SecurityOrigin*)
-{
- // FIXME: Implement this.
- ASSERT_NOT_REACHED();
+ return StorageAreaImpl::create(map.releaseNonNull());
}
-void StorageNamespaceImpl::clearAllOriginsForDeletion()
-{
- // FIXME: Implement this.
- ASSERT_NOT_REACHED();
-}
+class StorageNamespaceImpl::EphemeralStorageArea final : public StorageArea {
+public:
+ static Ref<EphemeralStorageArea> create(const SecurityOriginData& origin, unsigned quotaInBytes)
+ {
+ return adoptRef(*new EphemeralStorageArea(origin, quotaInBytes));
+ }
+
+ Ref<EphemeralStorageArea> copy()
+ {
+ return adoptRef(*new EphemeralStorageArea(*this));
+ }
+
+private:
+ EphemeralStorageArea(const SecurityOriginData& origin, unsigned quotaInBytes)
+ : m_securityOriginData(origin)
+ , m_storageMap(StorageMap::create(quotaInBytes))
+ {
+ }
+
+ EphemeralStorageArea(EphemeralStorageArea& other)
+ : m_securityOriginData(other.m_securityOriginData)
+ , m_storageMap(other.m_storageMap)
+ {
+ }
+
+ // WebCore::StorageArea.
+ unsigned length()
+ {
+ return m_storageMap->length();
+ }
+
+ String key(unsigned index)
+ {
+ return m_storageMap->key(index);
+ }
+
+ String item(const String& key)
+ {
+ return m_storageMap->getItem(key);
+ }
+
+ void setItem(Frame*, const String& key, const String& value, bool& quotaException)
+ {
+ String oldValue;
+ if (auto newMap = m_storageMap->setItem(key, value, oldValue, quotaException))
+ m_storageMap = WTFMove(newMap);
+ }
+
+ void removeItem(Frame*, const String& key)
+ {
+ String oldValue;
+ if (auto newMap = m_storageMap->removeItem(key, oldValue))
+ m_storageMap = WTFMove(newMap);
+ }
+
+ void clear(Frame*)
+ {
+ if (!m_storageMap->length())
+ return;
+
+ m_storageMap = StorageMap::create(m_storageMap->quota());
+ }
+
+ bool contains(const String& key)
+ {
+ return m_storageMap->contains(key);
+ }
+
+ bool canAccessStorage(Frame* frame)
+ {
+ return frame && frame->page();
+ }
+
+ StorageType storageType() const
+ {
+ return StorageType::EphemeralLocal;
+ }
+
+ size_t memoryBytesUsedByCache()
+ {
+ return 0;
+ }
+
+ void incrementAccessCount() { }
+ void decrementAccessCount() { }
+ void closeDatabaseIfIdle() { }
+
+ SecurityOriginData securityOrigin() const
+ {
+ return m_securityOriginData;
+ }
+
+ SecurityOriginData m_securityOriginData;
+ RefPtr<StorageMap> m_storageMap;
+};
-void StorageNamespaceImpl::sync()
+RefPtr<StorageArea> StorageNamespaceImpl::ephemeralLocalStorageArea(const SecurityOriginData& securityOrigin)
{
- // FIXME: Implement this.
- ASSERT_NOT_REACHED();
+ auto& slot = m_ephemeralLocalStorageAreas.add(securityOrigin, nullptr).iterator->value;
+ if (!slot)
+ slot = StorageNamespaceImpl::EphemeralStorageArea::create(securityOrigin, m_quotaInBytes);
+
+ return slot.get();
}
-void StorageNamespaceImpl::closeIdleLocalStorageDatabases()
+RefPtr<StorageNamespace> StorageNamespaceImpl::copy(Page* newPage)
{
- // FIXME: Implement this.
- ASSERT_NOT_REACHED();
+ ASSERT(m_storageNamespaceID);
+
+ if (m_storageType == StorageType::Session)
+ return createSessionStorageNamespace(WebPage::fromCorePage(newPage)->pageID(), m_quotaInBytes);
+
+ ASSERT(m_storageType == StorageType::EphemeralLocal);
+ RefPtr<StorageNamespaceImpl> newNamespace = adoptRef(new StorageNamespaceImpl(m_storageType, m_storageNamespaceID, m_topLevelOrigin.get(), m_quotaInBytes));
+
+ for (auto& iter : m_ephemeralLocalStorageAreas)
+ newNamespace->m_ephemeralLocalStorageAreas.set(iter.key, iter.value->copy());
+
+ return newNamespace;
}
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/Storage/StorageNamespaceImpl.h b/Source/WebKit2/WebProcess/Storage/StorageNamespaceImpl.h
index 05ed85fee..f13a22dcb 100644
--- a/Source/WebKit2/WebProcess/Storage/StorageNamespaceImpl.h
+++ b/Source/WebKit2/WebProcess/Storage/StorageNamespaceImpl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,11 +23,12 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StorageNamespaceImpl_h
-#define StorageNamespaceImpl_h
+#pragma once
+#include <WebCore/SecurityOriginData.h>
#include <WebCore/SecurityOriginHash.h>
#include <WebCore/StorageArea.h>
+#include <WebCore/StorageMap.h>
#include <WebCore/StorageNamespace.h>
#include <wtf/HashMap.h>
@@ -38,32 +39,40 @@ class WebPage;
class StorageNamespaceImpl : public WebCore::StorageNamespace {
public:
- static PassRefPtr<StorageNamespaceImpl> createLocalStorageNamespace(WebCore::PageGroup*);
- static PassRefPtr<StorageNamespaceImpl> createSessionStorageNamespace(WebPage*);
+ static RefPtr<StorageNamespaceImpl> createSessionStorageNamespace(uint64_t identifier, unsigned quotaInBytes);
+ static RefPtr<StorageNamespaceImpl> createEphemeralLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes);
+ static RefPtr<StorageNamespaceImpl> createLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes);
+ static RefPtr<StorageNamespaceImpl> createTransientLocalStorageNamespace(uint64_t identifier, WebCore::SecurityOrigin& topLevelOrigin, uint64_t quotaInBytes);
+
virtual ~StorageNamespaceImpl();
WebCore::StorageType storageType() const { return m_storageType; }
uint64_t storageNamespaceID() const { return m_storageNamespaceID; }
+ WebCore::SecurityOrigin* topLevelOrigin() const { return m_topLevelOrigin.get(); }
unsigned quotaInBytes() const { return m_quotaInBytes; }
+ void didDestroyStorageAreaMap(StorageAreaMap&);
+
private:
- explicit StorageNamespaceImpl(WebCore::StorageType, uint64_t storageNamespaceID, unsigned quotaInBytes);
+ explicit StorageNamespaceImpl(WebCore::StorageType, uint64_t storageNamespaceID, WebCore::SecurityOrigin* topLevelOrigin, unsigned quotaInBytes);
+
+ RefPtr<WebCore::StorageArea> storageArea(const WebCore::SecurityOriginData&) override;
+ RefPtr<WebCore::StorageNamespace> copy(WebCore::Page*) override;
+
+ RefPtr<WebCore::StorageArea> ephemeralLocalStorageArea(const WebCore::SecurityOriginData&);
- virtual PassRefPtr<WebCore::StorageArea> storageArea(PassRefPtr<WebCore::SecurityOrigin>) override;
- virtual PassRefPtr<WebCore::StorageNamespace> copy(WebCore::Page*) override;
- virtual void close() override;
- virtual void clearOriginForDeletion(WebCore::SecurityOrigin*) override;
- virtual void clearAllOriginsForDeletion() override;
- virtual void sync() override;
- virtual void closeIdleLocalStorageDatabases() override;
+ const WebCore::StorageType m_storageType;
+ const uint64_t m_storageNamespaceID;
- WebCore::StorageType m_storageType;
- uint64_t m_storageNamespaceID;
- unsigned m_quotaInBytes;
+ // Only used for transient local storage namespaces.
+ const RefPtr<WebCore::SecurityOrigin> m_topLevelOrigin;
- HashMap<RefPtr<WebCore::SecurityOrigin>, RefPtr<StorageAreaMap>> m_storageAreaMaps;
+ const unsigned m_quotaInBytes;
+
+ HashMap<WebCore::SecurityOriginData, StorageAreaMap*> m_storageAreaMaps;
+
+ class EphemeralStorageArea;
+ HashMap<WebCore::SecurityOriginData, RefPtr<EphemeralStorageArea>> m_ephemeralLocalStorageAreas;
};
} // namespace WebKit
-
-#endif // StorageNamespaceImpl_h
diff --git a/Source/WebKit2/WebProcess/Storage/WebStorageNamespaceProvider.cpp b/Source/WebKit2/WebProcess/Storage/WebStorageNamespaceProvider.cpp
new file mode 100644
index 000000000..a3758eb87
--- /dev/null
+++ b/Source/WebKit2/WebProcess/Storage/WebStorageNamespaceProvider.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebStorageNamespaceProvider.h"
+
+#include "StorageNamespaceImpl.h"
+#include "WebPage.h"
+#include <wtf/HashMap.h>
+#include <wtf/NeverDestroyed.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static HashMap<uint64_t, WebStorageNamespaceProvider*>& storageNamespaceProviders()
+{
+ static NeverDestroyed<HashMap<uint64_t, WebStorageNamespaceProvider*>> storageNamespaceProviders;
+
+ return storageNamespaceProviders;
+}
+
+RefPtr<WebStorageNamespaceProvider> WebStorageNamespaceProvider::getOrCreate(uint64_t identifier)
+{
+ auto& slot = storageNamespaceProviders().add(identifier, nullptr).iterator->value;
+ if (slot)
+ return slot;
+
+ RefPtr<WebStorageNamespaceProvider> storageNamespaceProvider = adoptRef(new WebStorageNamespaceProvider(identifier));
+ slot = storageNamespaceProvider.get();
+
+ return storageNamespaceProvider;
+}
+
+WebStorageNamespaceProvider::WebStorageNamespaceProvider(uint64_t identifier)
+ : m_identifier(identifier)
+{
+}
+
+WebStorageNamespaceProvider::~WebStorageNamespaceProvider()
+{
+ ASSERT(storageNamespaceProviders().contains(m_identifier));
+
+ storageNamespaceProviders().remove(m_identifier);
+}
+
+RefPtr<WebCore::StorageNamespace> WebStorageNamespaceProvider::createSessionStorageNamespace(Page& page, unsigned quota)
+{
+ return StorageNamespaceImpl::createSessionStorageNamespace(WebPage::fromCorePage(&page)->pageID(), quota);
+}
+
+RefPtr<WebCore::StorageNamespace> WebStorageNamespaceProvider::createEphemeralLocalStorageNamespace(Page& page, unsigned quota)
+{
+ return StorageNamespaceImpl::createEphemeralLocalStorageNamespace(WebPage::fromCorePage(&page)->pageID(), quota);
+}
+
+RefPtr<WebCore::StorageNamespace> WebStorageNamespaceProvider::createLocalStorageNamespace(unsigned quota)
+{
+ return StorageNamespaceImpl::createLocalStorageNamespace(m_identifier, quota);
+}
+
+RefPtr<WebCore::StorageNamespace> WebStorageNamespaceProvider::createTransientLocalStorageNamespace(WebCore::SecurityOrigin& topLevelOrigin, unsigned quota)
+{
+ return StorageNamespaceImpl::createTransientLocalStorageNamespace(m_identifier, topLevelOrigin, quota);
+}
+
+}
diff --git a/Source/WebKit2/WebProcess/Storage/WebStorageNamespaceProvider.h b/Source/WebKit2/WebProcess/Storage/WebStorageNamespaceProvider.h
new file mode 100644
index 000000000..a4c21424b
--- /dev/null
+++ b/Source/WebKit2/WebProcess/Storage/WebStorageNamespaceProvider.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebStorageNamespaceProvider_h
+#define WebStorageNamespaceProvider_h
+
+#include <WebCore/StorageNamespaceProvider.h>
+
+namespace WebKit {
+
+class WebStorageNamespaceProvider final : public WebCore::StorageNamespaceProvider {
+public:
+ static RefPtr<WebStorageNamespaceProvider> getOrCreate(uint64_t identifier);
+ virtual ~WebStorageNamespaceProvider();
+
+private:
+ explicit WebStorageNamespaceProvider(uint64_t identifier);
+
+ RefPtr<WebCore::StorageNamespace> createSessionStorageNamespace(WebCore::Page&, unsigned quota) override;
+ RefPtr<WebCore::StorageNamespace> createEphemeralLocalStorageNamespace(WebCore::Page&, unsigned quota) override;
+ RefPtr<WebCore::StorageNamespace> createLocalStorageNamespace(unsigned quota) override;
+ RefPtr<WebCore::StorageNamespace> createTransientLocalStorageNamespace(WebCore::SecurityOrigin&, unsigned quota) override;
+
+ const uint64_t m_identifier;
+};
+
+}
+
+#endif // WebStorageNamespaceProvider_h