--- /dev/null
+/*
+ * Copyright (C) 2013 Samsung Electronics. 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.
+ *
+ */
+
+#include "cookie_manager.h"
+
+#include "utility"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
+#include "base/threading/thread_restrictions.h"
+#include "base/synchronization/waitable_event.h"
+#include "content/public/browser/browser_thread.h"
+#include "eweb_context.h"
+#include "url_request_context_getter_efl.h"
+#include "net/base/net_errors.h"
+#include "net/base/static_cookie_policy.h"
+#include "net/cookies/canonical_cookie.h"
+#include "net/cookies/cookie_util.h"
+#include "net/cookies/parsed_cookie.h"
+#include "net/cookies/cookie_monster.h"
+#include "net/cookies/cookie_options.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "url/gurl.h"
+
+#include <Eina.h>
+
+using content::BrowserThread;
+using net::CookieList;
+using net::CookieMonster;
+using base::AutoLock;
+
+namespace {
+
+void TriggerHostPolicyGetCallbackAsyncOnUIThread(Ewk_Cookie_Accept_Policy policy,
+ CookieManager::AsyncPolicyGetCb callback,
+ void *data) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (callback)
+ (*callback)(policy, NULL, data);
+}
+
+}
+
+class CookieManager::EwkGetHostCallback {
+ public:
+ EwkGetHostCallback(AsyncHostnamesGetCb callback, void* user_data)
+ : callback_(callback),
+ user_data_(user_data) {}
+
+ void TriggerCallback(const net::CookieList& cookies) {
+ Eina_List* hostnames = 0;
+ if (cookies.size()) {
+ net::CookieList::const_iterator it = cookies.begin();
+ while (it != cookies.end()) {
+ hostnames = eina_list_append(hostnames, eina_stringshare_add(it->Name().c_str()));
+ ++it;
+ }
+ }
+ (*callback_)(hostnames, NULL, user_data_);
+ void* item = 0;
+ EINA_LIST_FREE(hostnames, item)
+ eina_stringshare_del(static_cast<Eina_Stringshare*>(item));
+ }
+
+ private:
+ AsyncHostnamesGetCb callback_;
+ void* user_data_;
+};
+
+CookieManager::CookieManager(content::URLRequestContextGetterEfl* request_context_getter)
+ : is_clearing_(false),
+ request_context_getter_(request_context_getter),
+ cookie_policy_(EWK_COOKIE_ACCEPT_POLICY_ALWAYS)
+{
+}
+
+void CookieManager::DeleteCookiesAsync(const std::string& url,
+ const std::string& cookie_name)
+{
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&CookieManager::DeleteCookiesOnIOThread,
+ this,
+ url,
+ cookie_name));
+}
+
+void CookieManager::DeleteCookiesOnIOThread(const std::string& url,
+ const std::string& cookie_name) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ scoped_refptr<net::CookieMonster> cookie_monster =
+ request_context_getter_->GetURLRequestContext()->
+ cookie_store()->GetCookieMonster();
+ if (url.empty()) { // Delete all cookies.
+ cookie_monster->DeleteAllAsync(net::CookieMonster::DeleteCallback());
+ }
+ GURL gurl(url);
+ if (!gurl.is_valid())
+ return;
+ if (cookie_name.empty()) {
+ // Delete all matching host cookies.
+ cookie_monster->DeleteAllForHostAsync(gurl,
+ net::CookieMonster::DeleteCallback());
+ } else {
+ // Delete all matching host and domain cookies.
+ cookie_monster->DeleteCookieAsync(gurl, cookie_name, base::Closure());
+ }
+}
+
+void CookieManager::SetStoragePath(const std::string& path,
+ bool persist_session_cookies,
+ bool file_storage_type) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&CookieManager::SetStoragePathOnIOThread,
+ this,
+ path,
+ persist_session_cookies,
+ file_storage_type));
+}
+
+void CookieManager::GetAcceptPolicyAsync(AsyncPolicyGetCb callback, void *data) {
+ AutoLock lock(lock_);
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&TriggerHostPolicyGetCallbackAsyncOnUIThread,
+ cookie_policy_,
+ callback,
+ data));
+}
+
+void CookieManager::GetHostNamesWithCookiesAsync(AsyncHostnamesGetCb callback, void *data) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ host_callback_queue_.push(new EwkGetHostCallback(callback, data));
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(&CookieManager::FetchCookiesOnIOThread, this));
+}
+
+void CookieManager::FetchCookiesOnIOThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ scoped_refptr<net::CookieMonster> cookie_monster =
+ request_context_getter_->GetURLRequestContext()->
+ cookie_store()->GetCookieMonster();
+ if (cookie_monster.get()) {
+ cookie_monster->GetAllCookiesAsync(base::Bind(&CookieManager::OnFetchComplete, this));
+ } else {
+ OnFetchComplete(net::CookieList());
+ }
+}
+
+void CookieManager::OnFetchComplete(const net::CookieList& cookies) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&CookieManager::OnFetchComplete,
+ this,
+ cookies));
+ return;
+ }
+ if (!host_callback_queue_.empty()) {
+ EwkGetHostCallback* host_callback = host_callback_queue_.front();
+ if (host_callback) {
+ host_callback->TriggerCallback(cookies);
+ delete host_callback;
+ }
+ host_callback_queue_.pop();
+ }
+}
+
+void CookieManager::SetStoragePathOnIOThread(const std::string& path,
+ bool persist_session_cookies,
+ bool file_storage_type) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ base::FilePath storage_path(path);
+ request_context_getter_->SetCookieStoragePath(storage_path, persist_session_cookies);
+}
+
+bool CookieManager::GetGlobalAllowAccess() {
+ AutoLock lock(lock_);
+ return (cookie_policy_ == EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
+}
+
+void CookieManager::SetCookiePolicy(Ewk_Cookie_Accept_Policy policy) {
+ AutoLock lock(lock_);
+ cookie_policy_ = policy;
+}
+
+bool CookieManager::ShouldBlockThirdPartyCookies() {
+ AutoLock lock(lock_);
+ return (cookie_policy_ == EWK_COOKIE_ACCEPT_POLICY_NO_THIRD_PARTY);
+}
+
+bool CookieManager::AllowCookies(const GURL& url,
+ const GURL& first_party_url,
+ bool setting_cookie) {
+ if (GetGlobalAllowAccess())
+ return true;
+
+ if (ShouldBlockThirdPartyCookies()) {
+ net::StaticCookiePolicy policy(net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES);
+ int rv;
+ if (setting_cookie)
+ rv = policy.CanSetCookie(url, first_party_url);
+ else
+ rv = policy.CanGetCookies(url, first_party_url);
+
+ if (net::OK == rv)
+ return true;
+ }
+
+ return false;
+}
+
+bool CookieManager::OnCanGetCookies(const net::URLRequest& request,
+ const net::CookieList& cookie_list) {
+ return AllowCookies(request.url(), request.first_party_for_cookies(), false);
+}
+
+bool CookieManager::OnCanSetCookie(const net::URLRequest& request,
+ const std::string& cookie_line,
+ net::CookieOptions* options) {
+ return AllowCookies(request.url(), request.first_party_for_cookies(), true);
+}
+
+bool CookieManager::AllowGetCookie(const GURL& url,
+ const GURL& first_party,
+ const net::CookieList& cookie_list,
+ content::ResourceContext* context,
+ int render_process_id,
+ int render_frame_id) {
+ return AllowCookies(url, first_party, false);
+}
+
+bool CookieManager::AllowSetCookie(const GURL& url,
+ const GURL& first_party,
+ const std::string& cookie_line,
+ content::ResourceContext* context,
+ int render_process_id,
+ int render_frame_id,
+ net::CookieOptions* options) {
+ return AllowCookies(url, first_party, true);
+}
+
+void CookieManager::GetCookieValueOnIOThread(const GURL& host,
+ std::string* result,
+ base::WaitableEvent* completion) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ net::CookieOptions options;
+ options.set_include_httponly();
+ scoped_refptr<net::CookieMonster> cookie_monster =
+ request_context_getter_->GetURLRequestContext()->
+ cookie_store()->GetCookieMonster();
+ if (cookie_monster.get()) {
+ cookie_monster->GetCookiesWithOptionsAsync(host,
+ options,
+ base::Bind(&CookieManager::GetCookieValueCompleted,
+ this,
+ completion,
+ result));
+ } else {
+ DCHECK(completion);
+ completion->Signal();
+ }
+}
+
+void CookieManager::GetCookieValueCompleted(base::WaitableEvent* completion,
+ std::string* result,
+ const std::string& value) {
+ *result = value;
+ DCHECK(completion);
+ completion->Signal();
+}
+
+std::string CookieManager::GetCookiesForURL(const std::string& url) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ std::string cookie_value;
+ base::WaitableEvent completion(false, false);
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&CookieManager::GetCookieValueOnIOThread,
+ this,
+ GURL(url),
+ &cookie_value,
+ &completion));
+ //allow wait temporarily
+ base::ThreadRestrictions::ScopedAllowWait allow_wait;
+ completion.Wait();
+ return cookie_value;
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 Samsung Electronics. 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.
+ *
+ */
+
+#ifndef cookie_manager_h
+#define cookie_manager_h
+
+#include "base/synchronization/lock.h"
+#include "base/basictypes.h"
+#include "public/ewk_cookie_manager.h"
+#include "url_request_context_getter_efl.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "net/cookies/canonical_cookie.h"
+#include "net/cookies/cookie_options.h"
+#include "net/cookies/cookie_util.h"
+#include "url/gurl.h"
+
+#include <queue>
+#include <Eina.h>
+
+namespace content {
+class ResourceContext;
+}
+
+struct _Ewk_Error;
+
+class CookieManager
+ : public base::RefCountedThreadSafe<CookieManager> {
+public:
+ typedef void (*AsyncPolicyGetCb)(Ewk_Cookie_Accept_Policy, _Ewk_Error*, void *);
+ typedef void (*AsyncHostnamesGetCb)(Eina_List*, _Ewk_Error*, void *);
+
+ explicit CookieManager(content::URLRequestContextGetterEfl* request_context_getter);
+ // Delete all cookies that match the specified parameters. If both |url| and
+ // values |cookie_name| are specified all host and domain cookies matching
+ // both will be deleted. If only |url| is specified all host cookies (but not
+ // domain cookies) irrespective of path will be deleted. If |url| is empty all
+ // cookies for all hosts and domains will be deleted. This method must be
+ // called on the IO thread.
+ void DeleteCookiesAsync(const std::string& url = std::string(),
+ const std::string& cookie_name = std::string());
+ // Sets the directory path that will be used for storing cookie data. If
+ // |path| is empty data will be stored in memory only. Otherwise, data will be
+ // stored at the specified |path|. To persist session cookies (cookies without
+ // an expiry date or validity interval) set |persist_session_cookies| to true.
+ // Session cookies are generally intended to be transient and most Web browsers
+ // do not persist them. Returns false if cookies cannot be accessed.
+ void SetStoragePath(const std::string& path,
+ bool persist_session_cookies,
+ bool file_storage_type=true);
+ //get the accept policy asynchronous
+ void GetAcceptPolicyAsync(AsyncPolicyGetCb callback, void *data);
+ //get host name asynchronous
+ void GetHostNamesWithCookiesAsync(AsyncHostnamesGetCb callback, void *data);
+
+ // These manage the global access state shared across requests regardless of
+ // source (i.e. network or JavaScript).
+ bool GetGlobalAllowAccess();
+ void SetCookiePolicy(Ewk_Cookie_Accept_Policy policy);
+ // These are the functions called when operating over cookies from the
+ // network. See NetworkDelegate for further descriptions.
+ bool OnCanGetCookies(const net::URLRequest& request,
+ const net::CookieList& cookie_list);
+ bool OnCanSetCookie(const net::URLRequest& request,
+ const std::string& cookie_line,
+ net::CookieOptions* options);
+
+ // These are the functions called when operating over cookies from the
+ // renderer. See ContentBrowserClient for further descriptions.
+ bool AllowGetCookie(const GURL& url,
+ const GURL& first_party,
+ const net::CookieList& cookie_list,
+ content::ResourceContext* context,
+ int render_process_id,
+ int render_frame_id);
+ bool AllowSetCookie(const GURL& url,
+ const GURL& first_party,
+ const std::string& cookie_line,
+ content::ResourceContext* context,
+ int render_process_id,
+ int render_frame_id,
+ net::CookieOptions* options);
+ bool ShouldBlockThirdPartyCookies();
+ //This is synchronous call
+ std::string GetCookiesForURL(const std::string& url);
+
+protected:
+ friend class base::RefCountedThreadSafe<CookieManager>;
+
+ ~CookieManager()
+ {}
+
+private:
+ struct EwkGetHostCallback;
+
+ // Deletes cookie having host name. This must be called in IO thread.
+ void DeleteCookiesOnIOThread(const std::string& url,
+ const std::string& cookie_name) ;
+ void SetStoragePathOnIOThread(const std::string& path,
+ bool persist_session_cookies,
+ bool file_storage_type);
+ bool AllowCookies(const GURL& url,
+ const GURL& first_party_url,
+ bool setting_cookie);
+ // Fetch the cookies. This must be called in the IO thread.
+ void FetchCookiesOnIOThread();
+ void OnFetchComplete(const net::CookieList& cookies);
+
+ void GetCookieValueOnIOThread(const GURL& host,
+ std::string* result,
+ base::WaitableEvent* completion);
+ void GetCookieValueCompleted(base::WaitableEvent* completion,
+ std::string* result,
+ const std::string& value);
+ // Indicates whether or not we're currently clearing information:
+ // it's true when ClearCookie() is called in the UI thread, and it's reset
+ // after we notify the callback in the UI thread.
+ // This only mutates on the UI thread.
+ bool is_clearing_;
+ scoped_refptr<content::URLRequestContextGetterEfl> request_context_getter_;
+ //cookie policy information
+ base::Lock lock_;
+ Ewk_Cookie_Accept_Policy cookie_policy_;
+ // This only mutates on the UI thread.
+ std::queue< EwkGetHostCallback* > host_callback_queue_;
+
+ DISALLOW_COPY_AND_ASSIGN(CookieManager);
+};
+
+#endif //cookie_manager_h