-
Notifications
You must be signed in to change notification settings - Fork 896
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ephemeral storage support for localStorage and sessionStorage #6560
Conversation
Apart from review, this is still blocked on the addition of a runtime flag for this feature and running it through the CI. |
6af3bf6
to
8c73cfa
Compare
cc @pes10k |
Thanks @mrobinson ! Let me know once the flag is in place, and im happy to start using this as a daily build. Also also, feel free to let me know if you're at the stage where additional tests on https://dev-pages.brave.software/storage/index.html would be helpful |
I believe this change is ready for review. |
fb0592c
to
22697c2
Compare
I have pulled out the addition of a runtime flag for all of ephemeral storage to #6615. This PR now depends on that one. |
22697c2
to
92c6af2
Compare
chromium_src/components/content_settings/core/common/cookie_settings_base.cc
Outdated
Show resolved
Hide resolved
components/ephemeral_storage/browser/ephemeral_storage_tab_helper.cc
Outdated
Show resolved
Hide resolved
chromium_src/components/content_settings/core/common/features.h
Outdated
Show resolved
Hide resolved
chromium_src/third_party/blink/renderer/modules/storage/dom_window_storage.cc
Outdated
Show resolved
Hide resolved
chromium_src/third_party/blink/renderer/modules/storage/dom_window_storage.cc
Outdated
Show resolved
Hide resolved
components/ephemeral_storage/browser/ephemeral_storage_browsertest.cc
Outdated
Show resolved
Hide resolved
patches/third_party-blink-renderer-modules-storage-storage_namespace.h.patch
Outdated
Show resolved
Hide resolved
components/ephemeral_storage/browser/ephemeral_storage_browsertest.cc
Outdated
Show resolved
Hide resolved
chromium_src/third_party/blink/renderer/modules/storage/dom_window_storage.cc
Show resolved
Hide resolved
chromium_src/third_party/blink/renderer/modules/storage/dom_window_storage.cc
Outdated
Show resolved
Hide resolved
chromium_src/third_party/blink/renderer/modules/storage/dom_window_storage.cc
Show resolved
Hide resolved
96df29c
to
6ec701d
Compare
Okay. I've pushed a new commit that addresses review comments and also rebased the entire branch. I think there is really only one question outstanding and it is: #6560 (comment) It's just waiting on @bridiver for feedback on what behavior was expected with that code. Thanks for the review comments and your patience with this change. |
@@ -145,7 +144,10 @@ bool EphemeralStorageTabHelper::IsAnotherTabOpenWithStorageDomain( | |||
} | |||
#else | |||
for (Browser* browser : *BrowserList::GetInstance()) { | |||
if (browser->profile() == web_contents()->GetBrowserContext()) { | |||
// We need to use reinterpret_cast here, because BrowserContext is a subclass of Profile, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmm, it seems to me that it is actually Profile
subclasses BrowserContext
, so we can just write BrowserContext* context = browser->profile()
without a cast
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the issue here was that including the profile.h
header introduces a circular dependency. This code should be gone in the latest revision though.
// localStorage area, we use the sessionStorage infrastructure. | ||
Document* document = window->GetFrame()->GetDocument(); | ||
ephemeral_local_storage_ = | ||
StorageArea::Create(document->GetFrame(), std::move(storage_area), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just window->GetFrame()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
if (!base::FeatureList::IsEnabled(features::kBraveEphemeralStorage)) | ||
return non_ephemeral_storage; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking that maybe we can move these checks to the upper level? Or somehow change the function name, because now it is actually not ephemeralLocalStorage
, but "ephemeral local storage if things are good, otherwise normal local storage"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
String::FromUTF8(webview->Client()->GetSessionStorageNamespaceId()) + | ||
String("/ephemeral-session-storage"); | ||
"/ephemeral-session-storage"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd really like to move this concatenation + /ephemeral-session-storage
into StringToSessionStorageId()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
// hash and then use that make up our own GUID-like string. Because of the way | ||
// we are constructing the string we should never collide with a real GUID and | ||
// we only need to worry about hash collisions, which are unlikely. | ||
std::string StringToSessionStorageId(const std::string& string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function can append "/ephemeral-local-storage"
to the string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One caller needs the string "/ephemeral-local-storage" and the other needs "/ephemeral-session-storage". What do you think about adding an additional parameter which is the suffix to be added to the string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've gone ahead and done this in both dom_window_storage.cc
and ephemeral_storage_tab_helper.cc
.
} else { | ||
std::string local_partition_id = new_domain + "/ephemeral-local-storage"; | ||
auto local_storage_namespace = content::CreateSessionStorageNamespace( | ||
partition, StringToSessionStorageId(local_partition_id)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm probably missing something, but if CreateSessionStorageNamespace
returns same namespace for a given partition (which maps 1-1 to a browser context) and a given id, then we don't need a global map? Since storage partition already maintains one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that CreateSessionStorageNamespace
returns a reference. If all the references disappear then the namespace is deleted. We need the map to maintain at least one reference, keeping the namespace alive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm honestly having hard times understanding this, will definitely need some help :)
How does the map help us to keep a namespace alive if (1) it only holds weak pointers (2) last per_tld_ephemeral_storage_
will erase the corresponding entry in the map?
So anyway, closing (or navigating away) all tabs with a given TLD cleans up the namespace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The maps holds weak pointers, so the map alone won't keep the PerTLDEphemeralStorage (and the namespace) alive on its own. The TabHelper does keep a real reference to the PerTLDEphemeralStorage though. As long as one TabHelper has a reference, the PerTLDEphemeralStorage will stay alive. When the last TabHelper drops the reference (either by being destroyed or by switching domains during navigation), the PerTLDEphemeralStorage will be deleted by the reference counting code and the destructor removes it from the map of weak pointers.
} | ||
|
||
IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest, | ||
ClosingTabClearsEphemeralStorage) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe also check that reload doesn't drop the storage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and also check that storage is different in another profile (should be relatively easy to spinoff an incognito window and do same checks)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(both tests can be a follow-up of course)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. This all makes sense and I'm happy to add these tests in a quick followup, as you suggest.
Thanks for the comments. I've pushed a new commit to this branch with fixes. |
I've pushed a new branch completely removing |
const std::string& suffix) { | ||
std::string hash = base::MD5String(string) + "____"; | ||
DCHECK_EQ(hash.size(), 36u); | ||
return hash + suffix; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm wait, I gather we should rather do md5(hash + suffix)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof. You are right. I will fix this.
#include <utility> | ||
|
||
#include "base/memory/ref_counted.h" | ||
#include "base/memory/weak_ptr.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not used now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
return nullptr; | ||
String session_storage_id = StringToSessionStorageId( | ||
String::FromUTF8(webview->Client()->GetSessionStorageNamespaceId()), | ||
"/ephemeral-session-storage"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bad spacing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean vertical spacing? This particular formatting is the result of running "git cl format."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, everything's fine here
So far found one minor (probably known) trouble:
4a) reload 4b) open the same url in another tab |
Also, would be super helpful to add some top-level comments for key classes (e.g. the TabHelper, |
It seems this is a regression from removing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (only needs fix for #6560 (comment))
nope, actually reproduced with |
f85201c
to
3592765
Compare
Ephemeral storage persists DOM storage in third-party frames in a partitioned storage area that is unique to each top-level frame eTLD. The storage area is persisted until no tabs from the top-level eTLD exist. This change also adds a runtime flag for ephemeral storage, which is only useful if third-party storage is activated. A future change will selectively enable third-party storage when the flag is active.
3592765
to
e17234b
Compare
The issue here was that there was a typo in the code generating the hash. I have fixed this now and all the CI are passing. I think this can be landed now? |
Sure thing, please go ahead! |
Resolves brave/brave-browser#11619
Submitter Checklist:
npm run lint
)git rebase master
(if needed).git rebase -i
to squash commits (if needed).Test Plan:
about:flags
Reviewer Checklist:
After-merge Checklist:
changes has landed on.