2012-04-03 03:34:16 +02:00
|
|
|
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
|
|
|
|
// reserved. Use of this source code is governed by a BSD-style license that can
|
|
|
|
// be found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "libcef/browser/cookie_manager_impl.h"
|
|
|
|
|
2012-08-04 02:59:58 +02:00
|
|
|
#include <set>
|
2012-04-03 03:34:16 +02:00
|
|
|
#include <string>
|
2012-08-04 02:59:58 +02:00
|
|
|
#include <vector>
|
2012-04-03 03:34:16 +02:00
|
|
|
|
2013-09-03 18:43:31 +02:00
|
|
|
#include "libcef/browser/content_browser_client.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
#include "libcef/browser/context.h"
|
|
|
|
#include "libcef/browser/thread_util.h"
|
|
|
|
#include "libcef/common/time_util.h"
|
|
|
|
|
|
|
|
#include "base/bind.h"
|
2014-11-12 20:25:15 +01:00
|
|
|
#include "base/files/file_util.h"
|
2012-06-19 18:29:49 +02:00
|
|
|
#include "base/format_macros.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
#include "base/logging.h"
|
2012-05-18 17:04:56 +02:00
|
|
|
#include "base/threading/thread_restrictions.h"
|
2013-04-16 00:16:01 +02:00
|
|
|
#include "content/browser/net/sqlite_persistent_cookie_store.h"
|
2013-12-17 23:04:35 +01:00
|
|
|
#include "content/public/browser/cookie_crypto_delegate.h"
|
2012-06-19 18:29:49 +02:00
|
|
|
#include "net/cookies/cookie_util.h"
|
2012-08-04 02:59:58 +02:00
|
|
|
#include "net/cookies/parsed_cookie.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
#include "net/url_request/url_request_context.h"
|
2013-07-24 22:15:18 +02:00
|
|
|
#include "url/gurl.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
|
2013-03-12 21:23:24 +01:00
|
|
|
using content::BrowserThread;
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
// Callback class for visiting cookies.
|
|
|
|
class VisitCookiesCallback : public base::RefCounted<VisitCookiesCallback> {
|
|
|
|
public:
|
2015-03-02 21:25:14 +01:00
|
|
|
explicit VisitCookiesCallback(
|
|
|
|
scoped_refptr<net::CookieMonster> cookie_monster,
|
|
|
|
CefRefPtr<CefCookieVisitor> visitor)
|
2012-04-03 03:34:16 +02:00
|
|
|
: cookie_monster_(cookie_monster),
|
|
|
|
visitor_(visitor) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void Run(const net::CookieList& list) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
|
|
|
|
int total = list.size(), count = 0;
|
|
|
|
|
|
|
|
net::CookieList::const_iterator it = list.begin();
|
|
|
|
for (; it != list.end(); ++it, ++count) {
|
|
|
|
CefCookie cookie;
|
2012-08-04 02:59:58 +02:00
|
|
|
const net::CanonicalCookie& cc = *(it);
|
2012-06-19 18:29:49 +02:00
|
|
|
CefCookieManagerImpl::GetCefCookie(cc, cookie);
|
2012-04-03 03:34:16 +02:00
|
|
|
|
|
|
|
bool deleteCookie = false;
|
|
|
|
bool keepLooping = visitor_->Visit(cookie, count, total, deleteCookie);
|
|
|
|
if (deleteCookie) {
|
|
|
|
cookie_monster_->DeleteCanonicalCookieAsync(cc,
|
|
|
|
net::CookieMonster::DeleteCookieCallback());
|
|
|
|
}
|
|
|
|
if (!keepLooping)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2014-11-12 20:25:15 +01:00
|
|
|
friend class base::RefCounted<VisitCookiesCallback>;
|
|
|
|
|
|
|
|
~VisitCookiesCallback() {}
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
scoped_refptr<net::CookieMonster> cookie_monster_;
|
|
|
|
CefRefPtr<CefCookieVisitor> visitor_;
|
|
|
|
};
|
|
|
|
|
2012-06-19 18:29:49 +02:00
|
|
|
|
|
|
|
// Methods extracted from net/cookies/cookie_monster.cc
|
|
|
|
|
|
|
|
// Determine the cookie domain to use for setting the specified cookie.
|
|
|
|
bool GetCookieDomain(const GURL& url,
|
2012-08-04 02:59:58 +02:00
|
|
|
const net::ParsedCookie& pc,
|
2012-06-19 18:29:49 +02:00
|
|
|
std::string* result) {
|
|
|
|
std::string domain_string;
|
|
|
|
if (pc.HasDomain())
|
|
|
|
domain_string = pc.Domain();
|
|
|
|
return net::cookie_util::GetCookieDomainWithString(url, domain_string,
|
|
|
|
result);
|
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
// Always execute the callback asynchronously.
|
|
|
|
void RunAsyncCompletionOnIOThread(CefRefPtr<CefCompletionCallback> callback) {
|
|
|
|
if (!callback.get())
|
|
|
|
return;
|
2013-02-13 20:53:41 +01:00
|
|
|
CEF_POST_TASK(CEF_IOT,
|
2014-02-05 21:35:45 +01:00
|
|
|
base::Bind(&CefCompletionCallback::OnComplete, callback.get()));
|
2013-02-13 20:53:41 +01:00
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
// Always execute the callback asynchronously.
|
|
|
|
void DeleteCookiesCallbackImpl(CefRefPtr<CefDeleteCookiesCallback> callback,
|
|
|
|
int num_deleted) {
|
|
|
|
if (!callback.get())
|
|
|
|
return;
|
|
|
|
CEF_POST_TASK(CEF_IOT,
|
|
|
|
base::Bind(&CefDeleteCookiesCallback::OnComplete, callback.get(),
|
|
|
|
num_deleted));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Always execute the callback asynchronously.
|
|
|
|
void SetCookieCallbackImpl(CefRefPtr<CefSetCookieCallback> callback,
|
|
|
|
bool success) {
|
|
|
|
if (!callback.get())
|
|
|
|
return;
|
|
|
|
CEF_POST_TASK(CEF_IOT,
|
|
|
|
base::Bind(&CefSetCookieCallback::OnComplete, callback.get(), success));
|
|
|
|
}
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
CefCookieManagerImpl::CefCookieManagerImpl() {
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
CefCookieManagerImpl::~CefCookieManagerImpl() {
|
|
|
|
}
|
|
|
|
|
2013-02-13 20:53:41 +01:00
|
|
|
void CefCookieManagerImpl::Initialize(
|
2015-03-02 21:25:14 +01:00
|
|
|
CefRefPtr<CefRequestContextImpl> request_context,
|
2013-02-13 20:53:41 +01:00
|
|
|
const CefString& path,
|
2015-03-02 21:25:14 +01:00
|
|
|
bool persist_session_cookies,
|
|
|
|
CefRefPtr<CefCompletionCallback> callback) {
|
|
|
|
if (request_context.get()) {
|
|
|
|
request_context_ = request_context;
|
|
|
|
request_context_->GetRequestContextImpl(
|
|
|
|
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
|
|
|
|
base::Bind(&CefCookieManagerImpl::InitWithContext, this, callback));
|
|
|
|
} else {
|
|
|
|
SetStoragePath(path, persist_session_cookies, callback);
|
|
|
|
}
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
void CefCookieManagerImpl::GetCookieMonster(
|
|
|
|
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
|
|
|
const CookieMonsterCallback& callback) {
|
|
|
|
if (!task_runner.get())
|
|
|
|
task_runner = base::MessageLoop::current()->task_runner();
|
2012-06-19 18:29:49 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
if (!CEF_CURRENTLY_ON_IOT()) {
|
|
|
|
CEF_POST_TASK(CEF_IOT,
|
|
|
|
base::Bind(&CefCookieManagerImpl::GetCookieMonster, this, task_runner,
|
|
|
|
callback));
|
|
|
|
return;
|
|
|
|
}
|
2012-06-19 18:29:49 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
if (HasContext()) {
|
|
|
|
RunMethodWithContext(
|
|
|
|
base::Bind(&CefCookieManagerImpl::GetCookieMonsterWithContext, this,
|
|
|
|
task_runner, callback));
|
|
|
|
return;
|
|
|
|
}
|
2012-04-04 00:14:28 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
DCHECK(cookie_monster_.get());
|
|
|
|
if (cookie_monster_.get()) {
|
|
|
|
if (task_runner->BelongsToCurrentThread()) {
|
|
|
|
// Execute the callback immediately.
|
|
|
|
callback.Run(cookie_monster_);
|
|
|
|
} else {
|
|
|
|
// Execute the callback on the target thread.
|
|
|
|
task_runner->PostTask(FROM_HERE, base::Bind(callback, cookie_monster_));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2012-04-04 00:14:28 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
scoped_refptr<net::CookieMonster>
|
|
|
|
CefCookieManagerImpl::GetExistingCookieMonster() {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
if (cookie_monster_.get()) {
|
|
|
|
return cookie_monster_;
|
|
|
|
} else if (request_context_impl_.get()) {
|
|
|
|
scoped_refptr<net::CookieMonster> cookie_monster =
|
|
|
|
request_context_impl_->GetURLRequestContext()->cookie_store()->
|
|
|
|
GetCookieMonster();
|
|
|
|
DCHECK(cookie_monster.get());
|
|
|
|
return cookie_monster;
|
|
|
|
}
|
2012-04-04 00:14:28 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
LOG(ERROR) << "Cookie manager backing store does not exist yet";
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-04-04 00:14:28 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
void CefCookieManagerImpl::SetSupportedSchemes(
|
|
|
|
const std::vector<CefString>& schemes,
|
|
|
|
CefRefPtr<CefCompletionCallback> callback) {
|
|
|
|
if (!CEF_CURRENTLY_ON_IOT()) {
|
2012-04-04 00:14:28 +02:00
|
|
|
CEF_POST_TASK(CEF_IOT,
|
2015-03-02 21:25:14 +01:00
|
|
|
base::Bind(&CefCookieManagerImpl::SetSupportedSchemes, this, schemes,
|
|
|
|
callback));
|
|
|
|
return;
|
2012-04-04 00:14:28 +02:00
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
if (HasContext()) {
|
|
|
|
RunMethodWithContext(
|
|
|
|
base::Bind(&CefCookieManagerImpl::SetSupportedSchemesWithContext, this,
|
|
|
|
schemes, callback));
|
|
|
|
return;
|
|
|
|
}
|
2012-06-19 18:29:49 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
DCHECK(cookie_monster_.get());
|
|
|
|
if (!cookie_monster_.get())
|
|
|
|
return;
|
2012-04-03 03:34:16 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
supported_schemes_ = schemes;
|
|
|
|
|
|
|
|
if (supported_schemes_.empty()) {
|
|
|
|
supported_schemes_.push_back("http");
|
|
|
|
supported_schemes_.push_back("https");
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
std::set<std::string> scheme_set;
|
|
|
|
std::vector<CefString>::const_iterator it = supported_schemes_.begin();
|
|
|
|
for (; it != supported_schemes_.end(); ++it)
|
|
|
|
scheme_set.insert(*it);
|
2012-04-03 03:34:16 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
const char** arr = new const char*[scheme_set.size()];
|
|
|
|
std::set<std::string>::const_iterator it2 = scheme_set.begin();
|
|
|
|
for (int i = 0; it2 != scheme_set.end(); ++it2, ++i)
|
|
|
|
arr[i] = it2->c_str();
|
2012-06-19 18:29:49 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
cookie_monster_->SetCookieableSchemes(arr, scheme_set.size());
|
2012-04-03 03:34:16 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
delete [] arr;
|
2012-04-03 03:34:16 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
RunAsyncCompletionOnIOThread(callback);
|
|
|
|
}
|
2012-04-03 03:34:16 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
bool CefCookieManagerImpl::VisitAllCookies(
|
|
|
|
CefRefPtr<CefCookieVisitor> visitor) {
|
|
|
|
GetCookieMonster(
|
|
|
|
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
|
|
|
|
base::Bind(&CefCookieManagerImpl::VisitAllCookiesInternal, this,
|
|
|
|
visitor));
|
2012-04-03 03:34:16 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
bool CefCookieManagerImpl::VisitUrlCookies(
|
|
|
|
const CefString& url,
|
|
|
|
bool includeHttpOnly,
|
|
|
|
CefRefPtr<CefCookieVisitor> visitor) {
|
|
|
|
GetCookieMonster(
|
|
|
|
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
|
|
|
|
base::Bind(&CefCookieManagerImpl::VisitUrlCookiesInternal, this, url,
|
|
|
|
includeHttpOnly, visitor));
|
|
|
|
return true;
|
|
|
|
}
|
2012-06-19 18:29:49 +02:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
bool CefCookieManagerImpl::SetCookie(
|
|
|
|
const CefString& url,
|
|
|
|
const CefCookie& cookie,
|
|
|
|
CefRefPtr<CefSetCookieCallback> callback) {
|
2012-04-03 03:34:16 +02:00
|
|
|
GURL gurl = GURL(url.ToString());
|
|
|
|
if (!gurl.is_valid())
|
|
|
|
return false;
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
GetCookieMonster(
|
|
|
|
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
|
|
|
|
base::Bind(&CefCookieManagerImpl::SetCookieInternal, this, gurl, cookie,
|
|
|
|
callback));
|
2012-04-03 03:34:16 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
bool CefCookieManagerImpl::DeleteCookies(
|
|
|
|
const CefString& url,
|
|
|
|
const CefString& cookie_name,
|
|
|
|
CefRefPtr<CefDeleteCookiesCallback> callback) {
|
|
|
|
// Empty URLs are allowed but not invalid URLs.
|
2012-04-03 03:34:16 +02:00
|
|
|
GURL gurl = GURL(url.ToString());
|
2015-03-02 21:25:14 +01:00
|
|
|
if (!gurl.is_empty() && !gurl.is_valid())
|
2012-04-03 03:34:16 +02:00
|
|
|
return false;
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
GetCookieMonster(
|
|
|
|
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
|
|
|
|
base::Bind(&CefCookieManagerImpl::DeleteCookiesInternal, this, gurl,
|
|
|
|
cookie_name, callback));
|
2012-04-03 03:34:16 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-02-13 20:53:41 +01:00
|
|
|
bool CefCookieManagerImpl::SetStoragePath(
|
|
|
|
const CefString& path,
|
2015-03-02 21:25:14 +01:00
|
|
|
bool persist_session_cookies,
|
|
|
|
CefRefPtr<CefCompletionCallback> callback) {
|
|
|
|
if (!CEF_CURRENTLY_ON_IOT()) {
|
2012-04-03 03:34:16 +02:00
|
|
|
CEF_POST_TASK(CEF_IOT,
|
|
|
|
base::Bind(base::IgnoreResult(&CefCookieManagerImpl::SetStoragePath),
|
2015-03-02 21:25:14 +01:00
|
|
|
this, path, persist_session_cookies, callback));
|
|
|
|
return true;
|
2013-02-13 20:53:41 +01:00
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
if (HasContext()) {
|
|
|
|
RunMethodWithContext(
|
|
|
|
base::Bind(&CefCookieManagerImpl::SetStoragePathWithContext, this, path,
|
|
|
|
persist_session_cookies, callback));
|
|
|
|
return true;
|
|
|
|
}
|
2013-02-13 20:53:41 +01:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
base::FilePath new_path;
|
|
|
|
if (!path.empty())
|
|
|
|
new_path = base::FilePath(path);
|
2013-02-13 20:53:41 +01:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
if (cookie_monster_.get() && ((storage_path_.empty() && path.empty()) ||
|
|
|
|
storage_path_ == new_path)) {
|
|
|
|
// The path has not changed so don't do anything.
|
|
|
|
RunAsyncCompletionOnIOThread(callback);
|
|
|
|
return true;
|
|
|
|
}
|
2013-02-13 20:53:41 +01:00
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
scoped_refptr<content::SQLitePersistentCookieStore> persistent_store;
|
|
|
|
if (!new_path.empty()) {
|
|
|
|
// TODO(cef): Move directory creation to the blocking pool instead of
|
|
|
|
// allowing file IO on this thread.
|
|
|
|
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
|
|
|
if (base::DirectoryExists(new_path) ||
|
|
|
|
base::CreateDirectory(new_path)) {
|
|
|
|
const base::FilePath& cookie_path = new_path.AppendASCII("Cookies");
|
|
|
|
persistent_store =
|
|
|
|
new content::SQLitePersistentCookieStore(
|
|
|
|
cookie_path,
|
|
|
|
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
|
|
|
|
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
|
|
|
|
persist_session_cookies,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
} else {
|
|
|
|
NOTREACHED() << "The cookie storage directory could not be created";
|
|
|
|
storage_path_.clear();
|
|
|
|
}
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
// Set the new cookie store that will be used for all new requests. The old
|
|
|
|
// cookie store, if any, will be automatically flushed and closed when no
|
|
|
|
// longer referenced.
|
|
|
|
cookie_monster_ = new net::CookieMonster(persistent_store.get(), NULL);
|
|
|
|
if (persistent_store.get() && persist_session_cookies)
|
|
|
|
cookie_monster_->SetPersistSessionCookies(true);
|
|
|
|
storage_path_ = new_path;
|
|
|
|
|
|
|
|
// Restore the previously supported schemes.
|
|
|
|
SetSupportedSchemes(supported_schemes_, callback);
|
|
|
|
|
2012-04-03 03:34:16 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
bool CefCookieManagerImpl::FlushStore(
|
|
|
|
CefRefPtr<CefCompletionCallback> callback) {
|
|
|
|
GetCookieMonster(
|
|
|
|
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
|
|
|
|
base::Bind(&CefCookieManagerImpl::FlushStoreInternal, this, callback));
|
|
|
|
return true;
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
2012-06-19 18:29:49 +02:00
|
|
|
// static
|
2012-08-04 02:59:58 +02:00
|
|
|
bool CefCookieManagerImpl::GetCefCookie(const net::CanonicalCookie& cc,
|
|
|
|
CefCookie& cookie) {
|
2012-06-19 18:29:49 +02:00
|
|
|
CefString(&cookie.name).FromString(cc.Name());
|
|
|
|
CefString(&cookie.value).FromString(cc.Value());
|
|
|
|
CefString(&cookie.domain).FromString(cc.Domain());
|
|
|
|
CefString(&cookie.path).FromString(cc.Path());
|
|
|
|
cookie.secure = cc.IsSecure();
|
|
|
|
cookie.httponly = cc.IsHttpOnly();
|
|
|
|
cef_time_from_basetime(cc.CreationDate(), cookie.creation);
|
|
|
|
cef_time_from_basetime(cc.LastAccessDate(), cookie.last_access);
|
2012-08-04 02:59:58 +02:00
|
|
|
cookie.has_expires = cc.IsPersistent();
|
2012-06-19 18:29:49 +02:00
|
|
|
if (cookie.has_expires)
|
|
|
|
cef_time_from_basetime(cc.ExpiryDate(), cookie.expires);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
bool CefCookieManagerImpl::GetCefCookie(const GURL& url,
|
|
|
|
const std::string& cookie_line,
|
|
|
|
CefCookie& cookie) {
|
|
|
|
// Parse the cookie.
|
2012-08-04 02:59:58 +02:00
|
|
|
net::ParsedCookie pc(cookie_line);
|
2012-06-19 18:29:49 +02:00
|
|
|
if (!pc.IsValid())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
std::string cookie_domain;
|
|
|
|
if (!GetCookieDomain(url, pc, &cookie_domain))
|
|
|
|
return false;
|
|
|
|
|
2012-08-04 02:59:58 +02:00
|
|
|
std::string cookie_path = net::CanonicalCookie::CanonPath(url, pc);
|
2012-06-19 18:29:49 +02:00
|
|
|
base::Time creation_time = base::Time::Now();
|
2012-08-04 02:59:58 +02:00
|
|
|
base::Time cookie_expires =
|
2012-11-05 21:18:20 +01:00
|
|
|
net::CanonicalCookie::CanonExpiration(pc, creation_time, creation_time);
|
2012-06-19 18:29:49 +02:00
|
|
|
|
|
|
|
CefString(&cookie.name).FromString(pc.Name());
|
|
|
|
CefString(&cookie.value).FromString(pc.Value());
|
|
|
|
CefString(&cookie.domain).FromString(cookie_domain);
|
|
|
|
CefString(&cookie.path).FromString(cookie_path);
|
|
|
|
cookie.secure = pc.IsSecure();
|
|
|
|
cookie.httponly = pc.IsHttpOnly();
|
|
|
|
cef_time_from_basetime(creation_time, cookie.creation);
|
|
|
|
cef_time_from_basetime(creation_time, cookie.last_access);
|
|
|
|
cookie.has_expires = !cookie_expires.is_null();
|
|
|
|
if (cookie.has_expires)
|
|
|
|
cef_time_from_basetime(cookie_expires, cookie.expires);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
bool CefCookieManagerImpl::HasContext() {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
return (request_context_impl_.get() || request_context_.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefCookieManagerImpl::RunMethodWithContext(
|
|
|
|
const CefRequestContextImpl::RequestContextCallback& method) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
if (request_context_impl_.get()) {
|
|
|
|
method.Run(request_context_impl_);
|
|
|
|
} else if (request_context_.get()) {
|
|
|
|
// Try again after the request context is initialized.
|
|
|
|
request_context_->GetRequestContextImpl(
|
|
|
|
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
|
|
|
|
method);
|
|
|
|
} else {
|
|
|
|
NOTREACHED();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefCookieManagerImpl::InitWithContext(
|
|
|
|
CefRefPtr<CefCompletionCallback> callback,
|
|
|
|
scoped_refptr<CefURLRequestContextGetterImpl> request_context) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
|
|
|
|
DCHECK(!request_context_impl_.get());
|
|
|
|
request_context_impl_ = request_context;
|
|
|
|
|
|
|
|
// Clear the CefRequestContextImpl reference here to avoid a potential
|
|
|
|
// reference loop between CefRequestContextImpl (which has a reference to
|
|
|
|
// CefRequestContextHandler), CefRequestContextHandler (which may keep a
|
|
|
|
// reference to this object) and this object.
|
|
|
|
request_context_ = NULL;
|
|
|
|
|
|
|
|
RunAsyncCompletionOnIOThread(callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefCookieManagerImpl::SetStoragePathWithContext(
|
|
|
|
const CefString& path,
|
|
|
|
bool persist_session_cookies,
|
|
|
|
CefRefPtr<CefCompletionCallback> callback,
|
|
|
|
scoped_refptr<CefURLRequestContextGetterImpl> request_context) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
|
|
|
|
base::FilePath new_path;
|
|
|
|
if (!path.empty())
|
|
|
|
new_path = base::FilePath(path);
|
|
|
|
|
|
|
|
request_context->SetCookieStoragePath(new_path, persist_session_cookies);
|
|
|
|
|
|
|
|
RunAsyncCompletionOnIOThread(callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefCookieManagerImpl::SetSupportedSchemesWithContext(
|
|
|
|
const std::vector<CefString>& schemes,
|
|
|
|
CefRefPtr<CefCompletionCallback> callback,
|
|
|
|
scoped_refptr<CefURLRequestContextGetterImpl> request_context) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
|
|
|
|
std::vector<std::string> scheme_vec;
|
|
|
|
std::vector<CefString>::const_iterator it = schemes.begin();
|
|
|
|
for (; it != schemes.end(); ++it)
|
|
|
|
scheme_vec.push_back(it->ToString());
|
|
|
|
|
|
|
|
request_context->SetCookieSupportedSchemes(scheme_vec);
|
|
|
|
|
|
|
|
RunAsyncCompletionOnIOThread(callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefCookieManagerImpl::GetCookieMonsterWithContext(
|
|
|
|
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
|
|
|
|
const CookieMonsterCallback& callback,
|
|
|
|
scoped_refptr<CefURLRequestContextGetterImpl> request_context) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
|
|
|
|
scoped_refptr<net::CookieMonster> cookie_monster =
|
|
|
|
request_context->GetURLRequestContext()->cookie_store()->
|
|
|
|
GetCookieMonster();
|
|
|
|
|
|
|
|
if (task_runner->BelongsToCurrentThread()) {
|
|
|
|
// Execute the callback immediately.
|
|
|
|
callback.Run(cookie_monster);
|
|
|
|
} else {
|
|
|
|
// Execute the callback on the target thread.
|
|
|
|
task_runner->PostTask(FROM_HERE, base::Bind(callback, cookie_monster));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefCookieManagerImpl::VisitAllCookiesInternal(
|
|
|
|
CefRefPtr<CefCookieVisitor> visitor,
|
|
|
|
scoped_refptr<net::CookieMonster> cookie_monster) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
|
|
|
|
scoped_refptr<VisitCookiesCallback> callback(
|
|
|
|
new VisitCookiesCallback(cookie_monster, visitor));
|
|
|
|
|
|
|
|
cookie_monster->GetAllCookiesAsync(
|
|
|
|
base::Bind(&VisitCookiesCallback::Run, callback.get()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefCookieManagerImpl::VisitUrlCookiesInternal(
|
|
|
|
const CefString& url,
|
|
|
|
bool includeHttpOnly,
|
|
|
|
CefRefPtr<CefCookieVisitor> visitor,
|
|
|
|
scoped_refptr<net::CookieMonster> cookie_monster) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
|
|
|
|
net::CookieOptions options;
|
|
|
|
if (includeHttpOnly)
|
|
|
|
options.set_include_httponly();
|
|
|
|
|
|
|
|
scoped_refptr<VisitCookiesCallback> callback(
|
|
|
|
new VisitCookiesCallback(cookie_monster, visitor));
|
|
|
|
|
|
|
|
GURL gurl = GURL(url.ToString());
|
|
|
|
cookie_monster->GetAllCookiesForURLWithOptionsAsync(gurl, options,
|
|
|
|
base::Bind(&VisitCookiesCallback::Run, callback.get()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefCookieManagerImpl::SetCookieInternal(
|
|
|
|
const GURL& url,
|
|
|
|
const CefCookie& cookie,
|
|
|
|
CefRefPtr<CefSetCookieCallback> callback,
|
|
|
|
scoped_refptr<net::CookieMonster> cookie_monster) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
|
|
|
|
std::string name = CefString(&cookie.name).ToString();
|
|
|
|
std::string value = CefString(&cookie.value).ToString();
|
|
|
|
std::string domain = CefString(&cookie.domain).ToString();
|
|
|
|
std::string path = CefString(&cookie.path).ToString();
|
|
|
|
|
|
|
|
base::Time expiration_time;
|
|
|
|
if (cookie.has_expires)
|
|
|
|
cef_time_to_basetime(cookie.expires, expiration_time);
|
|
|
|
|
|
|
|
cookie_monster->SetCookieWithDetailsAsync(
|
|
|
|
url, name, value, domain, path,
|
|
|
|
expiration_time,
|
|
|
|
cookie.secure ? true : false,
|
|
|
|
cookie.httponly ? true : false,
|
|
|
|
net::COOKIE_PRIORITY_DEFAULT,
|
|
|
|
base::Bind(SetCookieCallbackImpl, callback));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefCookieManagerImpl::DeleteCookiesInternal(
|
|
|
|
const GURL& url,
|
|
|
|
const CefString& cookie_name,
|
|
|
|
CefRefPtr<CefDeleteCookiesCallback> callback,
|
|
|
|
scoped_refptr<net::CookieMonster> cookie_monster) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
|
|
|
|
if (url.is_empty()) {
|
|
|
|
// Delete all cookies.
|
|
|
|
cookie_monster->DeleteAllAsync(
|
|
|
|
base::Bind(DeleteCookiesCallbackImpl, callback));
|
|
|
|
} else if (cookie_name.empty()) {
|
|
|
|
// Delete all matching host cookies.
|
|
|
|
cookie_monster->DeleteAllForHostAsync(url,
|
|
|
|
base::Bind(DeleteCookiesCallbackImpl, callback));
|
|
|
|
} else {
|
|
|
|
// Delete all matching host and domain cookies.
|
|
|
|
cookie_monster->DeleteCookieAsync(url, cookie_name,
|
|
|
|
base::Bind(DeleteCookiesCallbackImpl, callback, -1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CefCookieManagerImpl::FlushStoreInternal(
|
|
|
|
CefRefPtr<CefCompletionCallback> callback,
|
|
|
|
scoped_refptr<net::CookieMonster> cookie_monster) {
|
|
|
|
CEF_REQUIRE_IOT();
|
|
|
|
|
|
|
|
cookie_monster->FlushStore(
|
|
|
|
base::Bind(RunAsyncCompletionOnIOThread, callback));
|
|
|
|
}
|
2012-04-03 03:34:16 +02:00
|
|
|
|
|
|
|
// CefCookieManager methods ----------------------------------------------------
|
|
|
|
|
|
|
|
// static
|
2015-03-02 21:25:14 +01:00
|
|
|
CefRefPtr<CefCookieManager> CefCookieManager::GetGlobalManager(
|
|
|
|
CefRefPtr<CefCompletionCallback> callback) {
|
2012-04-03 03:34:16 +02:00
|
|
|
// Verify that the context is in a valid state.
|
|
|
|
if (!CONTEXT_STATE_VALID()) {
|
|
|
|
NOTREACHED() << "context not valid";
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
return CefRequestContext::GetGlobalContext()->GetDefaultCookieManager(
|
|
|
|
callback);
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
CefRefPtr<CefCookieManager> CefCookieManager::CreateManager(
|
2013-02-13 20:53:41 +01:00
|
|
|
const CefString& path,
|
2015-03-02 21:25:14 +01:00
|
|
|
bool persist_session_cookies,
|
|
|
|
CefRefPtr<CefCompletionCallback> callback) {
|
2012-04-03 03:34:16 +02:00
|
|
|
// Verify that the context is in a valid state.
|
|
|
|
if (!CONTEXT_STATE_VALID()) {
|
|
|
|
NOTREACHED() << "context not valid";
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-03-02 21:25:14 +01:00
|
|
|
CefRefPtr<CefCookieManagerImpl> cookie_manager = new CefCookieManagerImpl();
|
|
|
|
cookie_manager->Initialize(NULL, path, persist_session_cookies, callback);
|
|
|
|
return cookie_manager.get();
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|