From 24bcf6ac165d290ee90af9415d235c36885caf64 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 21 Sep 2016 16:24:03 -0700 Subject: [PATCH] Add initial cookie changed event support --- atom/browser/api/atom_api_cookies.cc | 38 ++++++++++++++++++- atom/browser/api/atom_api_cookies.h | 10 ++++- atom/browser/api/atom_api_session.cc | 6 ++- atom/browser/atom_browser_context.cc | 7 +++- atom/browser/atom_browser_context.h | 7 ++++ atom/browser/net/atom_cookie_delegate.cc | 41 ++++++++++++++++++++ atom/browser/net/atom_cookie_delegate.h | 48 ++++++++++++++++++++++++ filenames.gypi | 2 + lib/browser/api/session.js | 3 +- 9 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 atom/browser/net/atom_cookie_delegate.cc create mode 100644 atom/browser/net/atom_cookie_delegate.h diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc index 86cc59847b2..a04ace5ccad 100644 --- a/atom/browser/api/atom_api_cookies.cc +++ b/atom/browser/api/atom_api_cookies.cc @@ -20,6 +20,7 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" +using atom::AtomCookieDelegate; using content::BrowserThread; namespace mate { @@ -54,6 +55,29 @@ struct Converter { } }; + +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const AtomCookieDelegate::ChangeCause& val) { + switch (val) { + case AtomCookieDelegate::ChangeCause::CHANGE_COOKIE_EXPLICIT: + return mate::StringToV8(isolate, "explicit"); + case AtomCookieDelegate::ChangeCause::CHANGE_COOKIE_OVERWRITE: + return mate::StringToV8(isolate, "overwrite"); + case AtomCookieDelegate::ChangeCause::CHANGE_COOKIE_EXPIRED: + return mate::StringToV8(isolate, "expired"); + case AtomCookieDelegate::ChangeCause::CHANGE_COOKIE_EVICTED: + return mate::StringToV8(isolate, "evicted"); + case AtomCookieDelegate::ChangeCause::CHANGE_COOKIE_EXPIRED_OVERWRITE: + return mate::StringToV8(isolate, "expired-overwrite"); + default: + return mate::StringToV8(isolate, "unknown"); + } + } +}; + + } // namespace mate namespace atom { @@ -206,11 +230,14 @@ void SetCookieOnIO(scoped_refptr getter, Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context) - : request_context_getter_(browser_context->url_request_context_getter()) { + : request_context_getter_(browser_context->url_request_context_getter()), + cookie_delegate_(browser_context->cookie_delegate()) { Init(isolate); + cookie_delegate_->AddObserver(this); } Cookies::~Cookies() { + cookie_delegate_->RemoveObserver(this); } void Cookies::Get(const base::DictionaryValue& filter, @@ -239,6 +266,15 @@ void Cookies::Set(const base::DictionaryValue& details, base::Bind(SetCookieOnIO, getter, Passed(&copied), callback)); } +void Cookies::OnCookieChanged(const net::CanonicalCookie& cookie, + bool removed, + AtomCookieDelegate::ChangeCause cause) { + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + Emit("changed", cookie, cause, removed); +} + + // static mate::Handle Cookies::Create( v8::Isolate* isolate, diff --git a/atom/browser/api/atom_api_cookies.h b/atom/browser/api/atom_api_cookies.h index 5f60cb7ab49..5c29cebbcae 100644 --- a/atom/browser/api/atom_api_cookies.h +++ b/atom/browser/api/atom_api_cookies.h @@ -8,6 +8,7 @@ #include #include "atom/browser/api/trackable_object.h" +#include "atom/browser/net/atom_cookie_delegate.h" #include "base/callback.h" #include "native_mate/handle.h" #include "net/cookies/canonical_cookie.h" @@ -26,7 +27,8 @@ class AtomBrowserContext; namespace api { -class Cookies : public mate::TrackableObject { +class Cookies : public mate::TrackableObject, + public AtomCookieDelegate::Observer { public: enum Error { SUCCESS, @@ -52,8 +54,14 @@ class Cookies : public mate::TrackableObject { const base::Closure& callback); void Set(const base::DictionaryValue& details, const SetCallback& callback); + // AtomCookieDelegate::Observer: + void OnCookieChanged(const net::CanonicalCookie& cookie, + bool removed, + AtomCookieDelegate::ChangeCause cause) override; + private: net::URLRequestContextGetter* request_context_getter_; + AtomCookieDelegate* cookie_delegate_; DISALLOW_COPY_AND_ASSIGN(Cookies); }; diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 45405099dde..96fcca561d9 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -49,6 +49,7 @@ #include "net/url_request/url_request_context_getter.h" #include "ui/base/l10n/l10n_util.h" +using atom::api::Cookies; using content::BrowserThread; using content::StoragePartition; @@ -335,7 +336,7 @@ void OnClearStorageDataDone(const base::Closure& callback) { Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context) : devtools_network_emulation_client_id_(base::GenerateGUID()), browser_context_(browser_context) { - // Observe DownloadManger to get download notifications. + // Observe DownloadManager to get download notifications. content::BrowserContext::GetDownloadManager(browser_context)-> AddObserver(this); @@ -521,7 +522,7 @@ void Session::GetBlobData( v8::Local Session::Cookies(v8::Isolate* isolate) { if (cookies_.IsEmpty()) { - auto handle = atom::api::Cookies::Create(isolate, browser_context()); + auto handle = Cookies::Create(isolate, browser_context()); cookies_.Reset(isolate, handle.ToV8()); } return v8::Local::New(isolate, cookies_); @@ -631,6 +632,7 @@ void Initialize(v8::Local exports, v8::Local unused, v8::Isolate* isolate = context->GetIsolate(); mate::Dictionary dict(isolate, exports); dict.Set("Session", Session::GetConstructor(isolate)->GetFunction()); + dict.Set("Cookies", Cookies::GetConstructor(isolate)->GetFunction()); dict.SetMethod("fromPartition", &FromPartition); } diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 0b8146995d0..63c8c81fb4d 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -71,7 +71,8 @@ AtomBrowserContext::AtomBrowserContext( const std::string& partition, bool in_memory, const base::DictionaryValue& options) : brightray::BrowserContext(partition, in_memory), - network_delegate_(new AtomNetworkDelegate) { + network_delegate_(new AtomNetworkDelegate), + cookie_delegate_(new AtomCookieDelegate) { // Construct user agent string. Browser* browser = Browser::Get(); std::string name = RemoveWhitespace(browser->GetName()); @@ -107,6 +108,10 @@ net::NetworkDelegate* AtomBrowserContext::CreateNetworkDelegate() { return network_delegate_; } +net::CookieMonsterDelegate* AtomBrowserContext::CreateCookieDelegate() { + return cookie_delegate(); +} + std::string AtomBrowserContext::GetUserAgent() { return user_agent_; } diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index 23d8c64b62c..0ff1cc6321a 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -8,7 +8,9 @@ #include #include +#include "atom/browser/net/atom_cookie_delegate.h" #include "brightray/browser/browser_context.h" +#include "net/cookies/cookie_monster.h" namespace atom { @@ -31,6 +33,7 @@ class AtomBrowserContext : public brightray::BrowserContext { // brightray::URLRequestContextGetter::Delegate: net::NetworkDelegate* CreateNetworkDelegate() override; + net::CookieMonsterDelegate* CreateCookieDelegate() override; std::string GetUserAgent() override; std::unique_ptr CreateURLRequestJobFactory( content::ProtocolHandlerMap* protocol_handlers) override; @@ -50,6 +53,9 @@ class AtomBrowserContext : public brightray::BrowserContext { AtomBlobReader* GetBlobReader(); AtomNetworkDelegate* network_delegate() const { return network_delegate_; } + AtomCookieDelegate* cookie_delegate() const { + return cookie_delegate_.get(); + } protected: AtomBrowserContext(const std::string& partition, bool in_memory, @@ -66,6 +72,7 @@ class AtomBrowserContext : public brightray::BrowserContext { // Managed by brightray::BrowserContext. AtomNetworkDelegate* network_delegate_; + scoped_refptr cookie_delegate_; DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext); }; diff --git a/atom/browser/net/atom_cookie_delegate.cc b/atom/browser/net/atom_cookie_delegate.cc new file mode 100644 index 00000000000..5024a34ada3 --- /dev/null +++ b/atom/browser/net/atom_cookie_delegate.cc @@ -0,0 +1,41 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/net/atom_cookie_delegate.h" + +#include "content/public/browser/browser_thread.h" + +namespace atom { + +AtomCookieDelegate::AtomCookieDelegate() { +} + +AtomCookieDelegate::~AtomCookieDelegate() { +} + +void AtomCookieDelegate::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void AtomCookieDelegate::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void AtomCookieDelegate::NotifyObservers( + const net::CanonicalCookie& cookie, bool removed, ChangeCause cause) { + FOR_EACH_OBSERVER(Observer, + observers_, + OnCookieChanged(cookie, removed, cause)); +} + +void AtomCookieDelegate::OnCookieChanged( + const net::CanonicalCookie& cookie, bool removed, ChangeCause cause) { + content::BrowserThread::PostTask( + content::BrowserThread::UI, + FROM_HERE, + base::Bind(&AtomCookieDelegate::NotifyObservers, + this, cookie, removed, cause)); +} + +} // namespace atom diff --git a/atom/browser/net/atom_cookie_delegate.h b/atom/browser/net/atom_cookie_delegate.h new file mode 100644 index 00000000000..20acbd3b7ca --- /dev/null +++ b/atom/browser/net/atom_cookie_delegate.h @@ -0,0 +1,48 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_NET_ATOM_COOKIE_DELEGATE_H_ +#define ATOM_BROWSER_NET_ATOM_COOKIE_DELEGATE_H_ + +#include "base/observer_list.h" +#include "net/cookies/cookie_monster.h" + +namespace atom { + +class AtomCookieDelegate : public net::CookieMonsterDelegate { + public: + AtomCookieDelegate(); + ~AtomCookieDelegate() override; + + class Observer { + public: + virtual void OnCookieChanged(const net::CanonicalCookie& cookie, + bool removed, + ChangeCause cause) {} + protected: + virtual ~Observer() {} + }; + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + // net::CookieMonsterDelegate: + void OnCookieChanged(const net::CanonicalCookie& cookie, + bool removed, + ChangeCause cause) override; + + + private: + base::ObserverList observers_; + + void NotifyObservers(const net::CanonicalCookie& cookie, + bool removed, + ChangeCause cause); + + DISALLOW_COPY_AND_ASSIGN(AtomCookieDelegate); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_NET_ATOM_COOKIE_DELEGATE_H_ diff --git a/filenames.gypi b/filenames.gypi index d8b3ede3c59..9c4b42f622d 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -227,6 +227,8 @@ 'atom/browser/net/asar/url_request_asar_job.h', 'atom/browser/net/atom_cert_verifier.cc', 'atom/browser/net/atom_cert_verifier.h', + 'atom/browser/net/atom_cookie_delegate.cc', + 'atom/browser/net/atom_cookie_delegate.h', 'atom/browser/net/atom_network_delegate.cc', 'atom/browser/net/atom_network_delegate.h', 'atom/browser/net/atom_ssl_config_service.cc', diff --git a/lib/browser/api/session.js b/lib/browser/api/session.js index af553e442e1..ac47244db32 100644 --- a/lib/browser/api/session.js +++ b/lib/browser/api/session.js @@ -1,6 +1,6 @@ const {EventEmitter} = require('events') const {app} = require('electron') -const {fromPartition, Session} = process.atomBinding('session') +const {fromPartition, Session, Cookies} = process.atomBinding('session') // Public API. Object.defineProperties(exports, { @@ -15,6 +15,7 @@ Object.defineProperties(exports, { }) Object.setPrototypeOf(Session.prototype, EventEmitter.prototype) +Object.setPrototypeOf(Cookies.prototype, EventEmitter.prototype) Session.prototype._init = function () { app.emit('session-created', this)