diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index 189fc938698e..4463115cfee5 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -28,15 +28,17 @@ namespace atom { namespace { -const base::FilePath::CharType kStoragePartitionDirName[] = "Partitions"; +const base::FilePath::CharType kStoragePartitionDirname[] = "Partitions"; void GetStoragePartitionConfig(const GURL& partition, base::FilePath* partition_path, bool* in_memory, std::string* id) { *in_memory = (partition.path() != "/persist"); - *id = partition.query(); - *partition_path = base::FilePath(kStoragePartitionDirName).AppendASCII(*id); + net::UnescapeRule::Type flags = + net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS; + *id = net::UnescapeURLComponent(partition.query(), flags); + *partition_path = base::FilePath(kStoragePartitionDirname).AppendASCII(*id); } } // namespace @@ -55,7 +57,6 @@ AtomBrowserMainParts::AtomBrowserMainParts() } AtomBrowserMainParts::~AtomBrowserMainParts() { - STLDeleteValues(&browser_context_map_); for (const auto& callback : destruction_callbacks_) callback.Run(); } @@ -72,14 +73,13 @@ content::BrowserContext* AtomBrowserMainParts::GetBrowserContextForPartition( bool in_memory; base::FilePath partition_path; GetStoragePartitionConfig(partition, &partition_path, &in_memory, &id); - auto item = browser_context_map_.find(id); - if (item != browser_context_map_.end()) - return item->second; + if (browser_context_map_.contains(id)) + return browser_context_map_.get(id); - auto browser_context = CreateBrowserContext(); - browser_context->Initialize(partition_path, in_memory); - browser_context_map_[id] = browser_context; - return browser_context; + scoped_ptr browser_context(CreateBrowserContext()); + browser_context->Initialize(partition_path.value(), in_memory); + browser_context_map_.set(id, browser_context.Pass()); + return browser_context_map_.get(id); } void AtomBrowserMainParts::RegisterDestructionCallback( diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index 993340bfb422..d952f432882f 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -10,6 +10,7 @@ #include #include "base/callback.h" +#include "base/containers/scoped_ptr_hash_map.h" #include "base/timer/timer.h" #include "brightray/browser/browser_main_parts.h" #include "content/public/browser/browser_context.h" @@ -78,7 +79,8 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { std::list destruction_callbacks_; // partition_id => browser_context - std::map browser_context_map_; + base::ScopedPtrHashMap> + browser_context_map_; static AtomBrowserMainParts* self_; diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index 8d86e8fae911..2f1c8312155a 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -1,4 +1,3 @@ -crypto = require 'crypto' ipc = require 'ipc' webContents = require 'web-contents' webViewManager = null # Doesn't exist in early initialization. @@ -41,12 +40,16 @@ getNextInstanceId = (webContents) -> # Generate URL encoded partition id. getPartitionId = (partition) -> - persist = partition.startsWith('persist:') # Guest site url will be chrome-guest://fake-host/{persist}?{partitionId} partitionId = "chrome-guest://fake-host/" if partition - partitionId += if persist then 'persist?' else '?' - partitionId += crypto.createHash('sha256').update(partition).digest('hex') + persist = partition.startsWith('persist:') + if persist + partition = partition.substring('persist:'.length) + partitionId += 'persist?' + else + partitionId += '?' + partitionId += encodeURIComponent(partition) return partitionId # Create a new guest instance. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index cafcc5762e7a..c1b1f705e95b 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -142,7 +142,8 @@ Sets the storage partition used by the `webview`. If the storage partition ID st the `webview` will use a persistent storage partition available to all `webview` in the app with the same storage partition ID. if there is no `persist:` prefix, the `webview` will use an in-memory storage partition. By assigning the same partition ID, multiple `webview` -can share the same storage partition. +can share the same storage partition. If the storage partition ID is unset then default storage +of the app will be used. This value can only be modified before the first navigation, since the storage partition of an active renderer process cannot change. Subsequent attempts to modify the value will fail with a diff --git a/spec/fixtures/pages/partition/one.html b/spec/fixtures/pages/partition/one.html index 765f721883f3..ad22c341df95 100644 --- a/spec/fixtures/pages/partition/one.html +++ b/spec/fixtures/pages/partition/one.html @@ -1,5 +1,4 @@ diff --git a/spec/fixtures/pages/partition/two.html b/spec/fixtures/pages/partition/two.html deleted file mode 100644 index ad22c341df95..000000000000 --- a/spec/fixtures/pages/partition/two.html +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index ae8cd5d45579..486efaa6ffb4 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -155,30 +155,25 @@ describe ' tag', -> document.body.appendChild webview describe 'partition attribute', -> - isolatedWebview = null - beforeEach -> - isolatedWebview = new WebView - - afterEach -> - document.body.removeChild isolatedWebview - it 'isolates storage for different id', (done) -> listener = (e) -> - document.body.appendChild isolatedWebview - webview.removeEventListener 'did-finish-load', listener - listener2 = (e) -> - assert.equal e.message, "one 1" - webview.removeEventListener 'console-message', listener2 - listener3 = (e) -> assert.equal e.message, " 0" - isolatedWebview.removeEventListener 'console-message', listener3 + webview.removeEventListener 'console-message', listener done() - webview.addEventListener 'did-finish-load', listener - webview.addEventListener 'console-message', listener2 + window.localStorage.setItem 'test', 'one' + webview.addEventListener 'console-message', listener + webview.src = "file://#{fixtures}/pages/partition/one.html" + webview.partition = "test" + document.body.appendChild webview + + it 'uses current session storage when no id is provided', (done) -> + listener = (e) -> + assert.equal e.message, "one 1" + webview.removeEventListener 'console-message', listener + done() + window.localStorage.setItem 'test', 'one' + webview.addEventListener 'console-message', listener webview.src = "file://#{fixtures}/pages/partition/one.html" - isolatedWebview.addEventListener 'console-message', listener3 - isolatedWebview.setAttribute 'partition', 'test' - isolatedWebview.src = "file://#{fixtures}/pages/partition/two.html" document.body.appendChild webview describe 'new-window event', ->