diff options
author | jyasskin@chromium.org <jyasskin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-07 21:55:52 +0000 |
---|---|---|
committer | jyasskin@chromium.org <jyasskin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-07 21:55:52 +0000 |
commit | 6439498598a343b186d9a1ccd1ed338d5f79894a (patch) | |
tree | 00464bc66120cd58ef63f5075568c0166516cd10 /content | |
parent | cbb192a49372e491a906dc7c9809869b1ac0c20a (diff) | |
download | chromium_src-6439498598a343b186d9a1ccd1ed338d5f79894a.zip chromium_src-6439498598a343b186d9a1ccd1ed338d5f79894a.tar.gz chromium_src-6439498598a343b186d9a1ccd1ed338d5f79894a.tar.bz2 |
Revert 216264 "Adds a SqlLite backend to WebRTCIdentityStore."
to fix a memory leak:
http://build.chromium.org/p/chromium.memory.fyi/builders/Linux%20Heapcheck/builds/28768/steps/heapcheck%20test%3A%20content/logs/stdio
Leak of 160 bytes in 1 objects allocated from:
@ 7f1611ba10e0 content::WebRTCIdentityStore::RequestIdentity
@ a51510 content::WebRTCIdentityStoreTest_CancelRequest_Test::TestBody
Leak of 71 bytes in 1 objects allocated from:
@ 7f160f01ca89 std::basic_string::_Rep::_S_create
@ 7f161c6a5cac GURL::GURL
@ a514de content::WebRTCIdentityStoreTest_CancelRequest_Test::TestBody
> Adds a SqlLite backend to WebRTCIdentityStore.
> WebRTCIdentityStore maintains a list of inflight requests. If a new request is identical (i.e. same origin, identity_name, common_name) to a inflight request, the new one is joined into the existing one, so that it will not make duplicated requests to the backend or generate dupicated identities.
>
> If the backend does not find an existing identity, WebRTCIdentityStore generates a new one and adds it to the backend.
>
> The backend borrows most of the design from SQLiteServerBoundCertStore::Backend. It loads the database into memory on the first find request. Add or delete database operations are batched to commit every 30 seconds or every 512 operations.
>
>
> BUG=
>
> Review URL: https://chromiumcodereview.appspot.com/21453002
R=jiayl@chromium.org
Review URL: https://codereview.chromium.org/22264011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216282 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/media/webrtc_identity_store.cc | 184 | ||||
-rw-r--r-- | content/browser/media/webrtc_identity_store.h | 53 | ||||
-rw-r--r-- | content/browser/media/webrtc_identity_store_backend.cc | 543 | ||||
-rw-r--r-- | content/browser/media/webrtc_identity_store_backend.h | 111 | ||||
-rw-r--r-- | content/browser/media/webrtc_identity_store_unittest.cc | 260 | ||||
-rw-r--r-- | content/browser/renderer_host/media/webrtc_identity_service_host.cc | 14 | ||||
-rw-r--r-- | content/browser/renderer_host/media/webrtc_identity_service_host.h | 4 | ||||
-rw-r--r-- | content/browser/renderer_host/media/webrtc_identity_service_host_unittest.cc | 34 | ||||
-rw-r--r-- | content/browser/renderer_host/render_process_host_impl.cc | 2 | ||||
-rw-r--r-- | content/browser/storage_partition_impl.cc | 27 | ||||
-rw-r--r-- | content/browser/storage_partition_impl.h | 4 | ||||
-rw-r--r-- | content/browser/storage_partition_impl_unittest.cc | 10 | ||||
-rw-r--r-- | content/content_browser.gypi | 2 | ||||
-rw-r--r-- | content/public/browser/storage_partition.h | 2 |
14 files changed, 102 insertions, 1148 deletions
diff --git a/content/browser/media/webrtc_identity_store.cc b/content/browser/media/webrtc_identity_store.cc index 29a7ef9..ee19f1e 100644 --- a/content/browser/media/webrtc_identity_store.cc +++ b/content/browser/media/webrtc_identity_store.cc @@ -4,14 +4,11 @@ #include "content/browser/media/webrtc_identity_store.h" -#include <map> - #include "base/bind.h" #include "base/callback_helpers.h" #include "base/logging.h" #include "base/rand_util.h" #include "base/threading/worker_pool.h" -#include "content/browser/media/webrtc_identity_store_backend.h" #include "content/public/browser/browser_thread.h" #include "crypto/rsa_private_key.h" #include "net/base/net_errors.h" @@ -21,18 +18,11 @@ namespace content { struct WebRTCIdentityRequestResult { - WebRTCIdentityRequestResult(int error, - const std::string& certificate, - const std::string& private_key) - : error(error), certificate(certificate), private_key(private_key) {} - int error; std::string certificate; std::string private_key; }; -// Generates a new identity using |common_name| and returns the result in -// |result|. static void GenerateIdentityWorker(const std::string& common_name, WebRTCIdentityRequestResult* result) { result->error = net::OK; @@ -70,59 +60,33 @@ static void GenerateIdentityWorker(const std::string& common_name, std::string(private_key_info.begin(), private_key_info.end()); } -class WebRTCIdentityRequestHandle; - // The class represents an identity request internal to WebRTCIdentityStore. -// It has a one-to-many mapping to the external version of the request, -// WebRTCIdentityRequestHandle, i.e. multiple identical external requests are -// combined into one internal request. +// It has a one-to-one mapping to the external version of the request +// WebRTCIdentityRequestHandle, which is the target of the +// WebRTCIdentityRequest's completion callback. // It's deleted automatically when the request is completed. class WebRTCIdentityRequest { public: - WebRTCIdentityRequest(const GURL& origin, - const std::string& identity_name, - const std::string& common_name) - : origin_(origin), - identity_name_(identity_name), - common_name_(common_name) {} + WebRTCIdentityRequest(const WebRTCIdentityStore::CompletionCallback& callback) + : callback_(callback) {} - void Cancel(WebRTCIdentityRequestHandle* handle) { + void Cancel() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (callbacks_.find(handle) == callbacks_.end()) - return; - callbacks_.erase(handle); + callback_.Reset(); } private: friend class WebRTCIdentityStore; - void AddCallback(WebRTCIdentityRequestHandle* handle, - const WebRTCIdentityStore::CompletionCallback& callback) { - DCHECK(callbacks_.find(handle) == callbacks_.end()); - callbacks_[handle] = callback; - } - - // This method deletes "this" and no one should access it after the request - // completes. - // We do not use base::Owned to tie its lifetime to the callback for - // WebRTCIdentityStoreBackend::FindIdentity, because it needs to live longer - // than that if the identity does not exist in DB. - void Post(const WebRTCIdentityRequestResult& result) { + void Post(WebRTCIdentityRequestResult* result) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (callbacks_.empty()) + if (callback_.is_null()) return; - for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end(); - ++it) - it->second.Run(result.error, result.certificate, result.private_key); - delete this; + callback_.Run(result->error, result->certificate, result->private_key); + // "this" will be deleted after this point. } - GURL origin_; - std::string identity_name_; - std::string common_name_; - typedef std::map<WebRTCIdentityRequestHandle*, - WebRTCIdentityStore::CompletionCallback> CallbackMap; - CallbackMap callbacks_; + WebRTCIdentityStore::CompletionCallback callback_; }; // The class represents an identity request which calls back to the external @@ -151,7 +115,7 @@ class WebRTCIdentityRequestHandle { request_ = NULL; // "this" will be deleted after the following call, because "this" is // owned by the Callback held by |request|. - request->Cancel(this); + request->Cancel(); } void OnRequestStarted(WebRTCIdentityRequest* request) { @@ -176,12 +140,10 @@ class WebRTCIdentityRequestHandle { DISALLOW_COPY_AND_ASSIGN(WebRTCIdentityRequestHandle); }; -WebRTCIdentityStore::WebRTCIdentityStore(const base::FilePath& path, - quota::SpecialStoragePolicy* policy) - : task_runner_(base::WorkerPool::GetTaskRunner(true)), - backend_(new WebRTCIdentityStoreBackend(path, policy)) {} +WebRTCIdentityStore::WebRTCIdentityStore() + : task_runner_(base::WorkerPool::GetTaskRunner(true)) {} -WebRTCIdentityStore::~WebRTCIdentityStore() { backend_->Close(); } +WebRTCIdentityStore::~WebRTCIdentityStore() {} base::Closure WebRTCIdentityStore::RequestIdentity( const GURL& origin, @@ -193,118 +155,26 @@ base::Closure WebRTCIdentityStore::RequestIdentity( WebRTCIdentityRequestHandle* handle = new WebRTCIdentityRequestHandle(this, callback); - WebRTCIdentityRequest* request = - FindRequest(origin, identity_name, common_name); - - // If there is no identical request in flight, create a new one, queue it, - // and make the backend request. - if (!request) { - request = new WebRTCIdentityRequest(origin, identity_name, common_name); + WebRTCIdentityRequest* request = new WebRTCIdentityRequest(base::Bind( + &WebRTCIdentityRequestHandle::OnRequestComplete, base::Owned(handle))); + handle->OnRequestStarted(request); - if (!backend_->FindIdentity( - origin, - identity_name, - common_name, - base::Bind( - &WebRTCIdentityStore::BackendFindCallback, this, request))) { - delete request; - return base::Closure(); - } - in_flight_requests_.push_back(request); - } + WebRTCIdentityRequestResult* result = new WebRTCIdentityRequestResult(); + if (!task_runner_->PostTaskAndReply( + FROM_HERE, + base::Bind(&GenerateIdentityWorker, common_name, result), + base::Bind(&WebRTCIdentityRequest::Post, + base::Owned(request), + base::Owned(result)))) + return base::Closure(); - request->AddCallback( - handle, - base::Bind(&WebRTCIdentityRequestHandle::OnRequestComplete, - base::Owned(handle))); - handle->OnRequestStarted(request); return base::Bind(&WebRTCIdentityRequestHandle::Cancel, base::Unretained(handle)); } -void WebRTCIdentityStore::DeleteBetween(base::Time delete_begin, - base::Time delete_end, - const base::Closure& callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - backend_->DeleteBetween(delete_begin, delete_end, callback); -} - void WebRTCIdentityStore::SetTaskRunnerForTesting( const scoped_refptr<base::TaskRunner>& task_runner) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); task_runner_ = task_runner; } -void WebRTCIdentityStore::BackendFindCallback(WebRTCIdentityRequest* request, - int error, - const std::string& certificate, - const std::string& private_key) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (error == net::OK) { - DVLOG(2) << "Identity found in DB."; - WebRTCIdentityRequestResult result(error, certificate, private_key); - PostRequestResult(request, result); - return; - } - // Generate a new identity if not found in the DB. - WebRTCIdentityRequestResult* result = - new WebRTCIdentityRequestResult(0, "", ""); - if (!task_runner_->PostTaskAndReply( - FROM_HERE, - base::Bind(&GenerateIdentityWorker, request->common_name_, result), - base::Bind(&WebRTCIdentityStore::GenerateIdentityCallback, - this, - request, - base::Owned(result)))) { - // Completes the request with error if failed to post the task. - WebRTCIdentityRequestResult result(net::ERR_UNEXPECTED, "", ""); - PostRequestResult(request, result); - } -} - -void WebRTCIdentityStore::GenerateIdentityCallback( - WebRTCIdentityRequest* request, - WebRTCIdentityRequestResult* result) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (result->error == net::OK) { - DVLOG(2) << "New identity generated and added to the backend."; - backend_->AddIdentity(request->origin_, - request->identity_name_, - request->common_name_, - result->certificate, - result->private_key); - } - PostRequestResult(request, *result); -} - -void WebRTCIdentityStore::PostRequestResult( - WebRTCIdentityRequest* request, - const WebRTCIdentityRequestResult& result) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - // Removes the in flight request from the queue. - for (size_t i = 0; i < in_flight_requests_.size(); ++i) { - if (in_flight_requests_[i] == request) { - in_flight_requests_.erase(in_flight_requests_.begin() + i); - break; - } - } - // |request| will be deleted after this call. - request->Post(result); -} - -// Find an identical request from the in flight requests. -WebRTCIdentityRequest* WebRTCIdentityStore::FindRequest( - const GURL& origin, - const std::string& identity_name, - const std::string& common_name) { - for (size_t i = 0; i < in_flight_requests_.size(); ++i) { - if (in_flight_requests_[i]->origin_ == origin && - in_flight_requests_[i]->identity_name_ == identity_name && - in_flight_requests_[i]->common_name_ == common_name) { - return in_flight_requests_[i]; - } - } - return NULL; -} - } // namespace content diff --git a/content/browser/media/webrtc_identity_store.h b/content/browser/media/webrtc_identity_store.h index c2b523e..1649384 100644 --- a/content/browser/media/webrtc_identity_store.h +++ b/content/browser/media/webrtc_identity_store.h @@ -6,44 +6,32 @@ #define CONTENT_BROWSER_MEDIA_WEBRTC_IDENTITY_STORE_H_ #include <string> -#include <vector> #include "base/callback.h" -#include "base/time/time.h" #include "content/common/content_export.h" class GURL; namespace base { -class FilePath; class TaskRunner; } // namespace base -namespace quota { -class SpecialStoragePolicy; -} // namespace quota - namespace content { -class WebRTCIdentityRequest; -struct WebRTCIdentityRequestResult; -class WebRTCIdentityStoreBackend; + class WebRTCIdentityStoreTest; // A class for creating and fetching DTLS identities, i.e. the private key and // the self-signed certificate. -// It can be created/destroyed on any thread, but the public methods must be -// called on the IO thread. -class CONTENT_EXPORT WebRTCIdentityStore - : public base::RefCountedThreadSafe<WebRTCIdentityStore> { +class CONTENT_EXPORT WebRTCIdentityStore { public: typedef base::Callback<void(int error, const std::string& certificate, const std::string& private_key)> CompletionCallback; - // If |path| is empty, nothing will be saved to disk. - WebRTCIdentityStore(const base::FilePath& path, - quota::SpecialStoragePolicy* policy); + WebRTCIdentityStore(); + // Only virtual to allow subclassing for test mock. + virtual ~WebRTCIdentityStore(); // Retrieve the cached DTLS private key and certificate, i.e. identity, for // the |origin| and |identity_name| pair, or generate a new identity using @@ -51,6 +39,7 @@ class CONTENT_EXPORT WebRTCIdentityStore // If the given |common_name| is different from the common name in the cached // identity that has the same origin and identity_name, a new private key and // a new certificate will be generated, overwriting the old one. + // TODO(jiayl): implement identity caching through a persistent storage. // // |origin| is the origin of the DTLS connection; // |identity_name| is used to identify an identity within an origin; it is @@ -60,7 +49,7 @@ class CONTENT_EXPORT WebRTCIdentityStore // be shared with the peer of the DTLS connection. Identities created for // different origins or different identity names may have the same common // name. - // |callback| is the callback to return the result as DER strings. + // |callback| is the callback to return the result. // // Returns the Closure used to cancel the request if the request is accepted. // The Closure can only be called before the request completes. @@ -69,42 +58,14 @@ class CONTENT_EXPORT WebRTCIdentityStore const std::string& common_name, const CompletionCallback& callback); - // Delete the identities created between |delete_begin| and |delete_end|. - // |callback| will be called when the operation is done. - void DeleteBetween(base::Time delete_begin, - base::Time delete_end, - const base::Closure& callback); - - protected: - // Only virtual to allow subclassing for test mock. - virtual ~WebRTCIdentityStore(); - private: - friend class base::RefCountedThreadSafe<WebRTCIdentityStore>; friend class WebRTCIdentityStoreTest; void SetTaskRunnerForTesting( const scoped_refptr<base::TaskRunner>& task_runner); - void BackendFindCallback(WebRTCIdentityRequest* request, - int error, - const std::string& certificate, - const std::string& private_key); - void GenerateIdentityCallback(WebRTCIdentityRequest* request, - WebRTCIdentityRequestResult* result); - WebRTCIdentityRequest* FindRequest(const GURL& origin, - const std::string& identity_name, - const std::string& common_name); - void PostRequestResult(WebRTCIdentityRequest* request, - const WebRTCIdentityRequestResult& result); - // The TaskRunner for doing work on a worker thread. scoped_refptr<base::TaskRunner> task_runner_; - // Weak references of the in flight requests. Used to join identical external - // requests. - std::vector<WebRTCIdentityRequest*> in_flight_requests_; - - scoped_refptr<WebRTCIdentityStoreBackend> backend_; DISALLOW_COPY_AND_ASSIGN(WebRTCIdentityStore); }; diff --git a/content/browser/media/webrtc_identity_store_backend.cc b/content/browser/media/webrtc_identity_store_backend.cc deleted file mode 100644 index a86cc20..0000000 --- a/content/browser/media/webrtc_identity_store_backend.cc +++ /dev/null @@ -1,543 +0,0 @@ -// Copyright 2013 The Chromium 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 "content/browser/media/webrtc_identity_store_backend.h" - -#include "base/file_util.h" -#include "base/files/file_path.h" -#include "content/public/browser/browser_thread.h" -#include "net/base/net_errors.h" -#include "sql/error_delegate_util.h" -#include "sql/statement.h" -#include "sql/transaction.h" -#include "url/gurl.h" -#include "webkit/browser/quota/special_storage_policy.h" - -namespace content { - -static const char* kWebRTCIdentityStoreDBName = "webrtc_identity_store"; - -static const base::FilePath::CharType kWebRTCIdentityStoreDirectory[] = - FILE_PATH_LITERAL("WebRTCIdentityStore"); - -// Initializes the identity table, returning true on success. -static bool InitDB(sql::Connection* db) { - if (db->DoesTableExist(kWebRTCIdentityStoreDBName)) { - if (db->DoesColumnExist(kWebRTCIdentityStoreDBName, "origin") && - db->DoesColumnExist(kWebRTCIdentityStoreDBName, "identity_name") && - db->DoesColumnExist(kWebRTCIdentityStoreDBName, "common_name") && - db->DoesColumnExist(kWebRTCIdentityStoreDBName, "certificate") && - db->DoesColumnExist(kWebRTCIdentityStoreDBName, "private_key") && - db->DoesColumnExist(kWebRTCIdentityStoreDBName, "creation_time")) - return true; - if (!db->Execute("DROP TABLE webrtc_identity_store")) - return false; - } - - return db->Execute( - "CREATE TABLE webrtc_identity_store" - " (" - "origin TEXT NOT NULL," - "identity_name TEXT NOT NULL," - "common_name TEXT NOT NULL," - "certificate BLOB NOT NULL," - "private_key BLOB NOT NULL," - "creation_time INTEGER)"); -} - -struct WebRTCIdentityStoreBackend::IdentityKey { - IdentityKey(const GURL& origin, const std::string& identity_name) - : origin(origin), identity_name(identity_name) {} - - bool operator<(const IdentityKey& other) const { - return origin < other.origin || - (origin == other.origin && identity_name < other.identity_name); - } - - GURL origin; - std::string identity_name; -}; - -struct WebRTCIdentityStoreBackend::Identity { - Identity(const std::string& common_name, - const std::string& certificate, - const std::string& private_key) - : common_name(common_name), - certificate(certificate), - private_key(private_key), - creation_time(base::Time::Now().ToInternalValue()) {} - - Identity(const std::string& common_name, - const std::string& certificate, - const std::string& private_key, - int64 creation_time) - : common_name(common_name), - certificate(certificate), - private_key(private_key), - creation_time(creation_time) {} - - std::string common_name; - std::string certificate; - std::string private_key; - int64 creation_time; -}; - -struct WebRTCIdentityStoreBackend::PendingFindRequest { - PendingFindRequest(const GURL& origin, - const std::string& identity_name, - const std::string& common_name, - const FindIdentityCallback& callback) - : origin(origin), - identity_name(identity_name), - common_name(common_name), - callback(callback) {} - - ~PendingFindRequest() {} - - GURL origin; - std::string identity_name; - std::string common_name; - FindIdentityCallback callback; -}; - -// The class encapsulates the database operations. All members except ctor and -// dtor should be accessed on the DB thread. -// It can be created/destroyed on any thread. -class WebRTCIdentityStoreBackend::SqlLiteStorage - : public base::RefCountedThreadSafe<SqlLiteStorage> { - public: - SqlLiteStorage(const base::FilePath& path, - quota::SpecialStoragePolicy* policy) - : special_storage_policy_(policy) { - if (!path.empty()) - path_ = path.Append(kWebRTCIdentityStoreDirectory); - } - - void Load(IdentityMap* out_map); - void Close(); - void AddIdentity(const GURL& origin, - const std::string& identity_name, - const Identity& identity); - void DeleteIdentity(const GURL& origin, - const std::string& identity_name, - const Identity& identity); - void DeleteBetween(base::Time delete_begin, - base::Time delete_end, - const base::Closure& callback); - - private: - friend class base::RefCountedThreadSafe<SqlLiteStorage>; - - enum OperationType { - ADD_IDENTITY, - DELETE_IDENTITY - }; - struct PendingOperation { - PendingOperation(OperationType type, - const GURL& origin, - const std::string& identity_name, - const Identity& identity) - : type(type), - origin(origin), - identity_name(identity_name), - identity(identity) {} - - OperationType type; - GURL origin; - std::string identity_name; - Identity identity; - }; - typedef std::vector<PendingOperation*> PendingOperationList; - - virtual ~SqlLiteStorage() {} - void OnDatabaseError(int error, sql::Statement* stmt); - void BatchOperation(OperationType type, - const GURL& origin, - const std::string& identity_name, - const Identity& identity); - void Commit(); - - // The file path of the DB. Empty if temporary. - base::FilePath path_; - scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_; - scoped_ptr<sql::Connection> db_; - // Batched DB operations pending to commit. - PendingOperationList pending_operations_; - - DISALLOW_COPY_AND_ASSIGN(SqlLiteStorage); -}; - -WebRTCIdentityStoreBackend::WebRTCIdentityStoreBackend( - const base::FilePath& path, - quota::SpecialStoragePolicy* policy) - : state_(NOT_STARTED), - sql_lite_storage_(new SqlLiteStorage(path, policy)) {} - -bool WebRTCIdentityStoreBackend::FindIdentity( - const GURL& origin, - const std::string& identity_name, - const std::string& common_name, - const FindIdentityCallback& callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (state_ == CLOSED) - return false; - - if (state_ != LOADED) { - // Queues the request to wait for the DB to load. - pending_find_requests_.push_back( - new PendingFindRequest(origin, identity_name, common_name, callback)); - if (state_ == LOADING) - return true; - - DCHECK_EQ(state_, NOT_STARTED); - - // Kick off loading the DB. - scoped_ptr<IdentityMap> out_map(new IdentityMap()); - if (BrowserThread::PostTaskAndReply( - BrowserThread::DB, - FROM_HERE, - base::Bind(&SqlLiteStorage::Load, sql_lite_storage_, out_map.get()), - base::Bind(&WebRTCIdentityStoreBackend::OnLoaded, - this, - base::Passed(&out_map)))) { - state_ = LOADING; - return true; - } - // If it fails to post task, falls back to ERR_FILE_NOT_FOUND. - } - - IdentityKey key(origin, identity_name); - IdentityMap::iterator iter = identities_.find(key); - if (iter != identities_.end() && iter->second.common_name == common_name) { - // Identity found. - return BrowserThread::PostTask(BrowserThread::IO, - FROM_HERE, - base::Bind(callback, - net::OK, - iter->second.certificate, - iter->second.private_key)); - } - - return BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(callback, net::ERR_FILE_NOT_FOUND, "", "")); -} - -void WebRTCIdentityStoreBackend::AddIdentity(const GURL& origin, - const std::string& identity_name, - const std::string& common_name, - const std::string& certificate, - const std::string& private_key) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (state_ == CLOSED) - return; - - // If there is an existing identity for the same origin and identity_name, - // delete it. - IdentityKey key(origin, identity_name); - Identity identity(common_name, certificate, private_key); - - if (identities_.find(key) != identities_.end()) { - if (!BrowserThread::PostTask(BrowserThread::DB, - FROM_HERE, - base::Bind(&SqlLiteStorage::DeleteIdentity, - sql_lite_storage_, - origin, - identity_name, - identities_.find(key)->second))) - return; - } - identities_.insert(std::pair<IdentityKey, Identity>(key, identity)); - - BrowserThread::PostTask(BrowserThread::DB, - FROM_HERE, - base::Bind(&SqlLiteStorage::AddIdentity, - sql_lite_storage_, - origin, - identity_name, - identity)); -} - -void WebRTCIdentityStoreBackend::Close() { - if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { - BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(&WebRTCIdentityStoreBackend::Close, this)); - return; - } - - if (state_ == CLOSED) - return; - - state_ = CLOSED; - BrowserThread::PostTask( - BrowserThread::DB, - FROM_HERE, - base::Bind(&SqlLiteStorage::Close, sql_lite_storage_)); -} - -void WebRTCIdentityStoreBackend::DeleteBetween(base::Time delete_begin, - base::Time delete_end, - const base::Closure& callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - // Delete the in-memory cache. - IdentityMap::iterator it = identities_.begin(); - while (it != identities_.end()) { - if (it->second.creation_time >= delete_begin.ToInternalValue() && - it->second.creation_time <= delete_end.ToInternalValue()) - identities_.erase(it++); - else - it++; - } - - BrowserThread::PostTaskAndReply(BrowserThread::DB, - FROM_HERE, - base::Bind(&SqlLiteStorage::DeleteBetween, - sql_lite_storage_, - delete_begin, - delete_end, - callback), - callback); -} - -WebRTCIdentityStoreBackend::~WebRTCIdentityStoreBackend() {} - -void WebRTCIdentityStoreBackend::OnLoaded(scoped_ptr<IdentityMap> out_map) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - state_ = LOADED; - identities_.swap(*out_map); - - for (size_t i = 0; i < pending_find_requests_.size(); ++i) { - FindIdentity(pending_find_requests_[i]->origin, - pending_find_requests_[i]->identity_name, - pending_find_requests_[i]->common_name, - pending_find_requests_[i]->callback); - delete pending_find_requests_[i]; - } - pending_find_requests_.clear(); -} - -// -// Implementation of SqlLiteStorage. -// - -void WebRTCIdentityStoreBackend::SqlLiteStorage::Load(IdentityMap* out_map) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - DCHECK(!db_.get()); - - // Ensure the parent directory for storing certs is created before reading - // from it. - const base::FilePath dir = path_.DirName(); - if (!base::PathExists(dir) && !file_util::CreateDirectory(dir)) { - DLOG(ERROR) << "Unable to open DB file path."; - return; - } - - db_.reset(new sql::Connection()); - - db_->set_error_callback(base::Bind(&SqlLiteStorage::OnDatabaseError, this)); - - if (!db_->Open(path_)) { - DLOG(ERROR) << "Unable to open DB."; - db_.reset(); - return; - } - - if (!InitDB(db_.get())) { - DLOG(ERROR) << "Unable to init DB."; - db_.reset(); - return; - } - - db_->Preload(); - - // Slurp all the identities into the out_map. - sql::Statement stmt(db_->GetUniqueStatement( - "SELECT origin, identity_name, common_name, " - "certificate, private_key, creation_time " - "FROM webrtc_identity_store")); - CHECK(stmt.is_valid()); - - while (stmt.Step()) { - IdentityKey key(GURL(stmt.ColumnString(0)), stmt.ColumnString(1)); - std::string common_name(stmt.ColumnString(2)); - std::string cert, private_key; - stmt.ColumnBlobAsString(3, &cert); - stmt.ColumnBlobAsString(4, &private_key); - int64 creation_time = stmt.ColumnInt64(5); - std::pair<IdentityMap::iterator, bool> result = - out_map->insert(std::pair<IdentityKey, Identity>( - key, Identity(common_name, cert, private_key, creation_time))); - DCHECK(result.second); - } -} - -void WebRTCIdentityStoreBackend::SqlLiteStorage::Close() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - Commit(); - db_.reset(); -} - -void WebRTCIdentityStoreBackend::SqlLiteStorage::AddIdentity( - const GURL& origin, - const std::string& identity_name, - const Identity& identity) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - if (!db_.get()) - return; - - // Do not add for session only origins. - if (special_storage_policy_.get() && - !special_storage_policy_->IsStorageProtected(origin) && - special_storage_policy_->IsStorageSessionOnly(origin)) { - return; - } - BatchOperation(ADD_IDENTITY, origin, identity_name, identity); -} - -void WebRTCIdentityStoreBackend::SqlLiteStorage::DeleteIdentity( - const GURL& origin, - const std::string& identity_name, - const Identity& identity) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - if (!db_.get()) - return; - BatchOperation(DELETE_IDENTITY, origin, identity_name, identity); -} - -void WebRTCIdentityStoreBackend::SqlLiteStorage::OnDatabaseError( - int error, - sql::Statement* stmt) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - if (!sql::IsErrorCatastrophic(error)) - return; - db_->RazeAndClose(); -} - -void WebRTCIdentityStoreBackend::SqlLiteStorage::BatchOperation( - OperationType type, - const GURL& origin, - const std::string& identity_name, - const Identity& identity) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - // Commit every 30 seconds. - static const base::TimeDelta kCommitInterval( - base::TimeDelta::FromSeconds(30)); - // Commit right away if we have more than 512 outstanding operations. - static const size_t kCommitAfterBatchSize = 512; - - // We do a full copy of the cert here, and hopefully just here. - scoped_ptr<PendingOperation> operation( - new PendingOperation(type, origin, identity_name, identity)); - - pending_operations_.push_back(operation.release()); - - if (pending_operations_.size() == 1) { - // We've gotten our first entry for this batch, fire off the timer. - BrowserThread::PostDelayedTask(BrowserThread::DB, - FROM_HERE, - base::Bind(&SqlLiteStorage::Commit, this), - kCommitInterval); - } else if (pending_operations_.size() >= kCommitAfterBatchSize) { - // We've reached a big enough batch, fire off a commit now. - BrowserThread::PostTask(BrowserThread::DB, - FROM_HERE, - base::Bind(&SqlLiteStorage::Commit, this)); - } -} - -void WebRTCIdentityStoreBackend::SqlLiteStorage::Commit() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - // Maybe an old timer fired or we are already Close()'ed. - if (!db_.get() || pending_operations_.empty()) - return; - - sql::Statement add_stmt(db_->GetCachedStatement( - SQL_FROM_HERE, - "INSERT INTO webrtc_identity_store " - "(origin, identity_name, common_name, certificate," - " private_key, creation_time) VALUES" - " (?,?,?,?,?,?)")); - - CHECK(add_stmt.is_valid()); - - sql::Statement del_stmt(db_->GetCachedStatement( - SQL_FROM_HERE, - "DELETE FROM webrtc_identity_store WHERE origin=? AND identity_name=?")); - - CHECK(del_stmt.is_valid()); - - sql::Transaction transaction(db_.get()); - if (!transaction.Begin()) { - DLOG(ERROR) << "Failed to begin the transaction."; - return; - } - - for (PendingOperationList::iterator it = pending_operations_.begin(); - it != pending_operations_.end(); - ++it) { - scoped_ptr<PendingOperation> po(*it); - switch (po->type) { - case ADD_IDENTITY: { - add_stmt.Reset(true); - add_stmt.BindString(0, po->origin.spec()); - add_stmt.BindString(1, po->identity_name); - add_stmt.BindString(2, po->identity.common_name); - const std::string& cert = po->identity.certificate; - add_stmt.BindBlob(3, cert.data(), cert.size()); - const std::string& private_key = po->identity.private_key; - add_stmt.BindBlob(4, private_key.data(), private_key.size()); - add_stmt.BindInt64(5, po->identity.creation_time); - CHECK(add_stmt.Run()); - break; - } - case DELETE_IDENTITY: - del_stmt.Reset(true); - del_stmt.BindString(0, po->origin.spec()); - add_stmt.BindString(1, po->identity_name); - CHECK(del_stmt.Run()); - break; - - default: - NOTREACHED(); - break; - } - } - transaction.Commit(); - pending_operations_.clear(); -} - -void WebRTCIdentityStoreBackend::SqlLiteStorage::DeleteBetween( - base::Time delete_begin, - base::Time delete_end, - const base::Closure& callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); - if (!db_.get()) - return; - - // Commit pending operations first. - Commit(); - - sql::Statement del_stmt(db_->GetCachedStatement( - SQL_FROM_HERE, - "DELETE FROM webrtc_identity_store" - " WHERE creation_time >= ? AND creation_time <= ?")); - CHECK(del_stmt.is_valid()); - - del_stmt.BindInt64(0, delete_begin.ToInternalValue()); - del_stmt.BindInt64(1, delete_end.ToInternalValue()); - - sql::Transaction transaction(db_.get()); - if (!transaction.Begin()) { - DLOG(ERROR) << "Failed to begin the transaction."; - return; - } - - CHECK(del_stmt.Run()); - transaction.Commit(); -} - -} // namespace content diff --git a/content/browser/media/webrtc_identity_store_backend.h b/content/browser/media/webrtc_identity_store_backend.h deleted file mode 100644 index ab4e1ed..0000000 --- a/content/browser/media/webrtc_identity_store_backend.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_MEDIA_WEBRTC_IDENTITY_STORE_BACKEND_H_ -#define CONTENT_BROWSER_MEDIA_WEBRTC_IDENTITY_STORE_BACKEND_H_ - -#include <map> -#include <string> - -#include "base/time/time.h" -#include "sql/connection.h" -#include "sql/meta_table.h" - -class GURL; - -namespace base { -class FilePath; -} // namespace base - -namespace quota { -class SpecialStoragePolicy; -} // namespace quota - -namespace content { - -// This class represents a persistent cache of WebRTC identities. -// It can be created/destroyed/Close() on any thread. All other members should -// be accessed on the IO thread. -class WebRTCIdentityStoreBackend - : public base::RefCountedThreadSafe<WebRTCIdentityStoreBackend> { - public: - typedef base::Callback<void(int error, - const std::string& certificate, - const std::string& private_key)> - FindIdentityCallback; - - // No data is saved on disk if |path| is empty. - WebRTCIdentityStoreBackend(const base::FilePath& path, - quota::SpecialStoragePolicy* policy); - - // Finds the identity with |origin|, |identity_name|, and |common_name| from - // the DB. - // |origin| is the origin of the identity; - // |identity_name| is used to identify an identity within an origin; - // |common_name| is the common name used to generate the certificate; - // |callback| is the callback to return the find result. - // Returns true if |callback| will be called. - // Should be called on the IO thread. - bool FindIdentity(const GURL& origin, - const std::string& identity_name, - const std::string& common_name, - const FindIdentityCallback& callback); - - // Adds the identity to the DB and overwrites any existing identity having the - // same origin and identity_name. - // |origin| is the origin of the identity; - // |identity_name| is used to identify an identity within an origin; - // |common_name| is the common name used to generate the certificate; - // |certificate| is the DER string of the certificate; - // |private_key| is the DER string of the private key. - // Should be called on the IO thread. - void AddIdentity(const GURL& origin, - const std::string& identity_name, - const std::string& common_name, - const std::string& certificate, - const std::string& private_key); - - // Commits all pending DB operations and closes the DB connection. Any API - // call after this will fail. - // Can be called on any thread. - void Close(); - - // Delete the data created between |delete_begin| and |delete_end|. - // Should be called on the IO thread. - void DeleteBetween(base::Time delete_begin, - base::Time delete_end, - const base::Closure& callback); - - private: - friend class base::RefCountedThreadSafe<WebRTCIdentityStoreBackend>; - class SqlLiteStorage; - enum LoadingState { - NOT_STARTED, - LOADING, - LOADED, - CLOSED, - }; - struct PendingFindRequest; - struct IdentityKey; - struct Identity; - typedef std::map<IdentityKey, Identity> IdentityMap; - - ~WebRTCIdentityStoreBackend(); - - void OnLoaded(scoped_ptr<IdentityMap> out_map); - - // In-memory copy of the identities. - IdentityMap identities_; - // "Find identity" requests waiting for the DB to load. - std::vector<PendingFindRequest*> pending_find_requests_; - // The persistent storage loading state. - LoadingState state_; - // The persistent storage of identities. - scoped_refptr<SqlLiteStorage> sql_lite_storage_; - - DISALLOW_COPY_AND_ASSIGN(WebRTCIdentityStoreBackend); -}; -} - -#endif // CONTENT_BROWSER_MEDIA_WEBRTC_IDENTITY_STORE_BACKEND_H_ diff --git a/content/browser/media/webrtc_identity_store_unittest.cc b/content/browser/media/webrtc_identity_store_unittest.cc index 81c25d7..a975dd4 100644 --- a/content/browser/media/webrtc_identity_store_unittest.cc +++ b/content/browser/media/webrtc_identity_store_unittest.cc @@ -17,37 +17,15 @@ namespace content { // TODO(jiayl): the tests fail on Android since the openssl version of // CreateSelfSignedCert is not implemented. We should mock out this dependency // and remove the if-defined. -#if !defined(OS_ANDROID) - -static const char* kFakeOrigin = "http://foo.com"; -static const char* kFakeIdentityName1 = "name1"; -static const char* kFakeIdentityName2 = "name2"; -static const char* kFakeCommonName1 = "cname1"; -static const char* kFakeCommonName2 = "cname2"; - -static void OnRequestCompleted(bool* completed, - std::string* out_cert, - std::string* out_key, - int error, - const std::string& certificate, - const std::string& private_key) { - ASSERT_EQ(net::OK, error); - ASSERT_NE("", certificate); - ASSERT_NE("", private_key); - *completed = true; - *out_cert = certificate; - *out_key = private_key; -} +#if !defined(OS_ANDROID) class WebRTCIdentityStoreTest : public testing::Test { public: WebRTCIdentityStoreTest() - : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP | - TestBrowserThreadBundle::REAL_DB_THREAD), + : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), pool_owner_( new base::SequencedWorkerPoolOwner(3, "WebRTCIdentityStoreTest")), - webrtc_identity_store_( - new WebRTCIdentityStore(base::FilePath(), NULL)) { + webrtc_identity_store_(new WebRTCIdentityStore()) { webrtc_identity_store_->SetTaskRunnerForTesting(pool_owner_->pool()); } @@ -55,224 +33,74 @@ class WebRTCIdentityStoreTest : public testing::Test { pool_owner_->pool()->Shutdown(); } - void RunUntilIdle() { - RunAllPendingInMessageLoop(BrowserThread::DB); - RunAllPendingInMessageLoop(BrowserThread::IO); - pool_owner_->pool()->FlushForTesting(); - base::RunLoop().RunUntilIdle(); - } - - base::Closure RequestIdentityAndRunUtilIdle(const std::string& origin, - const std::string& identity_name, - const std::string& common_name, - bool* completed, - std::string* certificate, - std::string* private_key) { - base::Closure cancel_callback = webrtc_identity_store_->RequestIdentity( - GURL(origin), - identity_name, - common_name, - base::Bind(&OnRequestCompleted, completed, certificate, private_key)); - EXPECT_FALSE(cancel_callback.is_null()); - RunUntilIdle(); - return cancel_callback; - } - protected: TestBrowserThreadBundle browser_thread_bundle_; scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_; - scoped_refptr<WebRTCIdentityStore> webrtc_identity_store_; + scoped_ptr<WebRTCIdentityStore> webrtc_identity_store_; }; +static void OnRequestCompleted(bool* completed, + int error, + const std::string& certificate, + const std::string& private_key) { + ASSERT_EQ(net::OK, error); + ASSERT_NE("", certificate); + ASSERT_NE("", private_key); + *completed = true; +} + TEST_F(WebRTCIdentityStoreTest, RequestIdentity) { bool completed = false; - std::string dummy; base::Closure cancel_callback = - RequestIdentityAndRunUtilIdle(kFakeOrigin, - kFakeIdentityName1, - kFakeCommonName1, - &completed, - &dummy, - &dummy); + webrtc_identity_store_->RequestIdentity( + GURL("http://google.com"), + "a", + "b", + base::Bind(&OnRequestCompleted, &completed)); + ASSERT_FALSE(cancel_callback.is_null()); + pool_owner_->pool()->FlushForTesting(); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(completed); } TEST_F(WebRTCIdentityStoreTest, CancelRequest) { bool completed = false; - std::string dummy; - base::Closure cancel_callback = webrtc_identity_store_->RequestIdentity( - GURL(kFakeOrigin), - kFakeIdentityName1, - kFakeCommonName1, - base::Bind(&OnRequestCompleted, &completed, &dummy, &dummy)); + base::Closure cancel_callback = + webrtc_identity_store_->RequestIdentity( + GURL("http://google.com"), + "a", + "b", + base::Bind(&OnRequestCompleted, &completed)); ASSERT_FALSE(cancel_callback.is_null()); cancel_callback.Run(); - - RunUntilIdle(); + pool_owner_->pool()->FlushForTesting(); + base::RunLoop().RunUntilIdle(); EXPECT_FALSE(completed); } -TEST_F(WebRTCIdentityStoreTest, ConcurrentUniqueRequests) { - bool completed_1 = false; - bool completed_2 = false; - std::string dummy; - base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity( - GURL(kFakeOrigin), - kFakeIdentityName1, - kFakeCommonName1, - base::Bind(&OnRequestCompleted, &completed_1, &dummy, &dummy)); - ASSERT_FALSE(cancel_callback_1.is_null()); - - base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity( - GURL(kFakeOrigin), - kFakeIdentityName2, - kFakeCommonName1, - base::Bind(&OnRequestCompleted, &completed_2, &dummy, &dummy)); - ASSERT_FALSE(cancel_callback_2.is_null()); - - RunUntilIdle(); - EXPECT_TRUE(completed_1); - EXPECT_TRUE(completed_2); -} - -TEST_F(WebRTCIdentityStoreTest, DifferentCommonNameReturnNewIdentity) { +TEST_F(WebRTCIdentityStoreTest, MultipleRequests) { bool completed_1 = false; bool completed_2 = false; - std::string cert_1, cert_2, key_1, key_2; - base::Closure cancel_callback_1 = - RequestIdentityAndRunUtilIdle(kFakeOrigin, - kFakeIdentityName1, - kFakeCommonName1, - &completed_1, - &cert_1, - &key_1); - - base::Closure cancel_callback_2 = - RequestIdentityAndRunUtilIdle(kFakeOrigin, - kFakeIdentityName1, - kFakeCommonName2, - &completed_2, - &cert_2, - &key_2); - - EXPECT_TRUE(completed_1); - EXPECT_TRUE(completed_2); - EXPECT_NE(cert_1, cert_2); - EXPECT_NE(key_1, key_2); -} - -TEST_F(WebRTCIdentityStoreTest, SerialIdenticalRequests) { - bool completed_1 = false; - bool completed_2 = false; - std::string cert_1, cert_2, key_1, key_2; - - base::Closure cancel_callback_1 = - RequestIdentityAndRunUtilIdle(kFakeOrigin, - kFakeIdentityName1, - kFakeCommonName1, - &completed_1, - &cert_1, - &key_1); - - base::Closure cancel_callback_2 = - RequestIdentityAndRunUtilIdle(kFakeOrigin, - kFakeIdentityName1, - kFakeCommonName1, - &completed_2, - &cert_2, - &key_2); - - EXPECT_TRUE(completed_1); - EXPECT_TRUE(completed_2); - EXPECT_EQ(cert_1, cert_2); - EXPECT_EQ(key_1, key_2); -} - -TEST_F(WebRTCIdentityStoreTest, ConcurrentIdenticalRequestsJoined) { - bool completed_1 = false; - bool completed_2 = false; - std::string cert_1, cert_2, key_1, key_2; - - base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity( - GURL(kFakeOrigin), - kFakeIdentityName1, - kFakeCommonName1, - base::Bind(&OnRequestCompleted, &completed_1, &cert_1, &key_1)); - ASSERT_FALSE(cancel_callback_1.is_null()); - - base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity( - GURL(kFakeOrigin), - kFakeIdentityName1, - kFakeCommonName1, - base::Bind(&OnRequestCompleted, &completed_2, &cert_2, &key_2)); - ASSERT_FALSE(cancel_callback_2.is_null()); - - RunUntilIdle(); - EXPECT_TRUE(completed_1); - EXPECT_TRUE(completed_2); - EXPECT_EQ(cert_1, cert_2); - EXPECT_EQ(key_1, key_2); -} - -TEST_F(WebRTCIdentityStoreTest, CancelOneOfIdenticalRequests) { - bool completed_1 = false; - bool completed_2 = false; - std::string cert_1, cert_2, key_1, key_2; - - base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity( - GURL(kFakeOrigin), - kFakeIdentityName1, - kFakeCommonName1, - base::Bind(&OnRequestCompleted, &completed_1, &cert_1, &key_1)); + webrtc_identity_store_->RequestIdentity( + GURL("http://foo.com"), + "a", + "b", + base::Bind(&OnRequestCompleted, &completed_1)); ASSERT_FALSE(cancel_callback_1.is_null()); - base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity( - GURL(kFakeOrigin), - kFakeIdentityName1, - kFakeCommonName1, - base::Bind(&OnRequestCompleted, &completed_2, &cert_2, &key_2)); - ASSERT_FALSE(cancel_callback_2.is_null()); - - cancel_callback_1.Run(); - - RunUntilIdle(); - EXPECT_FALSE(completed_1); - EXPECT_TRUE(completed_2); -} - -TEST_F(WebRTCIdentityStoreTest, DeleteDataAndGenerateNewIdentity) { - bool completed_1 = false; - bool completed_2 = false; - std::string cert_1, cert_2, key_1, key_2; - - // Generate the first identity. - base::Closure cancel_callback_1 = - RequestIdentityAndRunUtilIdle(kFakeOrigin, - kFakeIdentityName1, - kFakeCommonName1, - &completed_1, - &cert_1, - &key_1); - - // Clear the data and the second request should return a new identity. - webrtc_identity_store_->DeleteBetween( - base::Time(), base::Time::Now(), base::Bind(&base::DoNothing)); - RunUntilIdle(); - base::Closure cancel_callback_2 = - RequestIdentityAndRunUtilIdle(kFakeOrigin, - kFakeIdentityName1, - kFakeCommonName1, - &completed_2, - &cert_2, - &key_2); + webrtc_identity_store_->RequestIdentity( + GURL("http://bar.com"), + "a", + "b", + base::Bind(&OnRequestCompleted, &completed_2)); + ASSERT_FALSE(cancel_callback_2.is_null()); + pool_owner_->pool()->FlushForTesting(); + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(completed_1); EXPECT_TRUE(completed_2); - EXPECT_NE(cert_1, cert_2); - EXPECT_NE(key_1, key_2); } - #endif } // namespace content diff --git a/content/browser/renderer_host/media/webrtc_identity_service_host.cc b/content/browser/renderer_host/media/webrtc_identity_service_host.cc index 0230b26..cce3c74 100644 --- a/content/browser/renderer_host/media/webrtc_identity_service_host.cc +++ b/content/browser/renderer_host/media/webrtc_identity_service_host.cc @@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" -#include "content/browser/child_process_security_policy_impl.h" #include "content/browser/media/webrtc_identity_store.h" #include "content/common/media/webrtc_identity_messages.h" #include "net/base/net_errors.h" @@ -14,10 +13,8 @@ namespace content { WebRTCIdentityServiceHost::WebRTCIdentityServiceHost( - int renderer_process_id, WebRTCIdentityStore* identity_store) - : renderer_process_id_(renderer_process_id), - identity_store_(identity_store) {} + : identity_store_(identity_store) {} WebRTCIdentityServiceHost::~WebRTCIdentityServiceHost() { if (!cancel_callback_.is_null()) @@ -45,15 +42,6 @@ void WebRTCIdentityServiceHost::OnRequestIdentity( SendErrorMessage(net::ERR_INSUFFICIENT_RESOURCES); return; } - - ChildProcessSecurityPolicyImpl* policy = - ChildProcessSecurityPolicyImpl::GetInstance(); - if (!policy->CanAccessCookiesForOrigin(renderer_process_id_, origin)) { - DLOG(WARNING) << "Request rejected because origin access is denied."; - SendErrorMessage(net::ERR_ACCESS_DENIED); - return; - } - cancel_callback_ = identity_store_->RequestIdentity( origin, identity_name, diff --git a/content/browser/renderer_host/media/webrtc_identity_service_host.h b/content/browser/renderer_host/media/webrtc_identity_service_host.h index 3676223..4c53056 100644 --- a/content/browser/renderer_host/media/webrtc_identity_service_host.h +++ b/content/browser/renderer_host/media/webrtc_identity_service_host.h @@ -26,8 +26,7 @@ class WebRTCIdentityStore; // ERR_INSUFFICIENT_RESOURCES will be sent back to the renderer. class CONTENT_EXPORT WebRTCIdentityServiceHost : public BrowserMessageFilter { public: - explicit WebRTCIdentityServiceHost(int renderer_process_id, - WebRTCIdentityStore* identity_store); + explicit WebRTCIdentityServiceHost(WebRTCIdentityStore* identity_store); protected: virtual ~WebRTCIdentityServiceHost(); @@ -51,7 +50,6 @@ class CONTENT_EXPORT WebRTCIdentityServiceHost : public BrowserMessageFilter { void SendErrorMessage(int error); - int renderer_process_id_; base::Closure cancel_callback_; WebRTCIdentityStore* identity_store_; diff --git a/content/browser/renderer_host/media/webrtc_identity_service_host_unittest.cc b/content/browser/renderer_host/media/webrtc_identity_service_host_unittest.cc index 341378d..058e15be 100644 --- a/content/browser/renderer_host/media/webrtc_identity_service_host_unittest.cc +++ b/content/browser/renderer_host/media/webrtc_identity_service_host_unittest.cc @@ -4,11 +4,9 @@ #include <deque> -#include "content/browser/child_process_security_policy_impl.h" #include "content/browser/media/webrtc_identity_store.h" #include "content/browser/renderer_host/media/webrtc_identity_service_host.h" #include "content/common/media/webrtc_identity_messages.h" -#include "content/public/test/test_browser_thread_bundle.h" #include "ipc/ipc_message.h" #include "net/base/net_errors.h" #include "testing/gtest/include/gtest/gtest.h" @@ -23,12 +21,9 @@ static const char FAKE_COMMON_NAME[] = "fake common name"; static const char FAKE_CERTIFICATE[] = "fake cert"; static const char FAKE_PRIVATE_KEY[] = "fake private key"; static const int FAKE_ERROR = 100; -static const int FAKE_RENDERER_ID = 10; class MockWebRTCIdentityStore : public WebRTCIdentityStore { public: - MockWebRTCIdentityStore() : WebRTCIdentityStore(base::FilePath(), NULL) {} - virtual base::Closure RequestIdentity( const GURL& origin, const std::string& identity_name, @@ -51,8 +46,6 @@ class MockWebRTCIdentityStore : public WebRTCIdentityStore { } private: - virtual ~MockWebRTCIdentityStore() {} - void OnCancel() { callback_.Reset(); } CompletionCallback callback_; @@ -61,11 +54,7 @@ class MockWebRTCIdentityStore : public WebRTCIdentityStore { class WebRTCIdentityServiceHostForTest : public WebRTCIdentityServiceHost { public: explicit WebRTCIdentityServiceHostForTest(WebRTCIdentityStore* identity_store) - : WebRTCIdentityServiceHost(FAKE_RENDERER_ID, identity_store) { - ChildProcessSecurityPolicyImpl* policy = - ChildProcessSecurityPolicyImpl::GetInstance(); - policy->Add(FAKE_RENDERER_ID); - } + : WebRTCIdentityServiceHost(identity_store) {} virtual bool Send(IPC::Message* message) OVERRIDE { messages_.push_back(*message); @@ -86,11 +75,7 @@ class WebRTCIdentityServiceHostForTest : public WebRTCIdentityServiceHost { void ClearMessages() { messages_.clear(); } private: - virtual ~WebRTCIdentityServiceHostForTest() { - ChildProcessSecurityPolicyImpl* policy = - ChildProcessSecurityPolicyImpl::GetInstance(); - policy->Remove(FAKE_RENDERER_ID); - } + virtual ~WebRTCIdentityServiceHostForTest() {} std::deque<IPC::Message> messages_; }; @@ -98,8 +83,7 @@ class WebRTCIdentityServiceHostForTest : public WebRTCIdentityServiceHost { class WebRTCIdentityServiceHostTest : public ::testing::Test { public: WebRTCIdentityServiceHostTest() - : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), - store_(new MockWebRTCIdentityStore()), + : store_(new MockWebRTCIdentityStore()), host_(new WebRTCIdentityServiceHostForTest(store_.get())) {} void SendRequestToHost() { @@ -140,8 +124,7 @@ class WebRTCIdentityServiceHostTest : public ::testing::Test { } protected: - TestBrowserThreadBundle browser_thread_bundle_; - scoped_refptr<MockWebRTCIdentityStore> store_; + scoped_ptr<MockWebRTCIdentityStore> store_; scoped_refptr<WebRTCIdentityServiceHostForTest> host_; }; @@ -175,13 +158,4 @@ TEST_F(WebRTCIdentityServiceHostTest, TestOnRequestFailed) { VerifyRequestFailedMessage(net::ERR_KEY_GENERATION_FAILED); } -TEST_F(WebRTCIdentityServiceHostTest, TestOriginAccessDenied) { - ChildProcessSecurityPolicyImpl* policy = - ChildProcessSecurityPolicyImpl::GetInstance(); - policy->Remove(FAKE_RENDERER_ID); - - SendRequestToHost(); - VerifyRequestFailedMessage(net::ERR_ACCESS_DENIED); -} - } // namespace content diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 3ed4860..d3ba06e 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -652,7 +652,7 @@ void RenderProcessHostImpl::CreateMessageFilters() { channel_->AddFilter(gpu_message_filter_); #if defined(ENABLE_WEBRTC) channel_->AddFilter(new WebRTCIdentityServiceHost( - GetID(), storage_partition_impl_->GetWebRTCIdentityStore())); + storage_partition_impl_->GetWebRTCIdentityStore())); peer_connection_tracker_host_ = new PeerConnectionTrackerHost(GetID()); channel_->AddFilter(peer_connection_tracker_host_.get()); channel_->AddFilter(new MediaStreamDispatcherHost( diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 361b4d1..1775b5f 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc @@ -252,7 +252,6 @@ struct StoragePartitionImpl::DataDeletionHelper { net::URLRequestContextGetter* rq_context, DOMStorageContextWrapper* dom_storage_context, quota::QuotaManager* quota_manager, - WebRTCIdentityStore* webrtc_identity_store, const base::Time begin, const base::Time end); @@ -285,7 +284,7 @@ StoragePartitionImpl::StoragePartitionImpl( webkit_database::DatabaseTracker* database_tracker, DOMStorageContextWrapper* dom_storage_context, IndexedDBContextImpl* indexed_db_context, - WebRTCIdentityStore* webrtc_identity_store) + scoped_ptr<WebRTCIdentityStore> webrtc_identity_store) : partition_path_(partition_path), quota_manager_(quota_manager), appcache_service_(appcache_service), @@ -293,7 +292,7 @@ StoragePartitionImpl::StoragePartitionImpl( database_tracker_(database_tracker), dom_storage_context_(dom_storage_context), indexed_db_context_(indexed_db_context), - webrtc_identity_store_(webrtc_identity_store) {} + webrtc_identity_store_(webrtc_identity_store.Pass()) {} StoragePartitionImpl::~StoragePartitionImpl() { // These message loop checks are just to avoid leaks in unittests. @@ -368,8 +367,8 @@ StoragePartitionImpl* StoragePartitionImpl::Create( scoped_refptr<ChromeAppCacheService> appcache_service = new ChromeAppCacheService(quota_manager->proxy()); - scoped_refptr<WebRTCIdentityStore> webrtc_identity_store( - new WebRTCIdentityStore(path, context->GetSpecialStoragePolicy())); + scoped_ptr<WebRTCIdentityStore> webrtc_identity_store( + new WebRTCIdentityStore()); return new StoragePartitionImpl(partition_path, quota_manager.get(), @@ -378,7 +377,7 @@ StoragePartitionImpl* StoragePartitionImpl::Create( database_tracker.get(), dom_storage_context.get(), indexed_db_context.get(), - webrtc_identity_store.get()); + webrtc_identity_store.Pass()); } base::FilePath StoragePartitionImpl::GetPath() { @@ -432,8 +431,7 @@ void StoragePartitionImpl::ClearDataImpl( // DataDeletionHelper::DecrementTaskCountOnUI(). helper->ClearDataOnUIThread( remove_mask, quota_storage_remove_mask, remove_origin, - GetPath(), rq_context, dom_storage_context_, quota_manager_, - webrtc_identity_store_, begin, end); + GetPath(), rq_context, dom_storage_context_, quota_manager_, begin, end); } void StoragePartitionImpl:: @@ -548,7 +546,6 @@ void StoragePartitionImpl::DataDeletionHelper::ClearDataOnUIThread( net::URLRequestContextGetter* rq_context, DOMStorageContextWrapper* dom_storage_context, quota::QuotaManager* quota_manager, - WebRTCIdentityStore* webrtc_identity_store, const base::Time begin, const base::Time end) { DCHECK_NE(remove_mask, 0u); @@ -605,18 +602,6 @@ void StoragePartitionImpl::DataDeletionHelper::ClearDataOnUIThread( path, begin, end, decrement_callback)); } - if (remove_mask & REMOVE_DATA_MASK_WEBRTC_IDENTITY) { - IncrementTaskCountOnUI(); - BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(&WebRTCIdentityStore::DeleteBetween, - webrtc_identity_store, - begin, - end, - decrement_callback)); - } - DecrementTaskCountOnUI(); } diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index e59347c..8665a74 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h @@ -77,7 +77,7 @@ class StoragePartitionImpl : public StoragePartition { webkit_database::DatabaseTracker* database_tracker, DOMStorageContextWrapper* dom_storage_context, IndexedDBContextImpl* indexed_db_context, - WebRTCIdentityStore* webrtc_identity_store); + scoped_ptr<WebRTCIdentityStore> webrtc_identity_store); void ClearDataImpl(uint32 remove_mask, uint32 quota_storage_remove_mask, @@ -112,7 +112,7 @@ class StoragePartitionImpl : public StoragePartition { scoped_refptr<webkit_database::DatabaseTracker> database_tracker_; scoped_refptr<DOMStorageContextWrapper> dom_storage_context_; scoped_refptr<IndexedDBContextImpl> indexed_db_context_; - scoped_refptr<WebRTCIdentityStore> webrtc_identity_store_; + scoped_ptr<WebRTCIdentityStore> webrtc_identity_store_; DISALLOW_COPY_AND_ASSIGN(StoragePartitionImpl); }; diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc index a8b47bc..2207837 100644 --- a/content/browser/storage_partition_impl_unittest.cc +++ b/content/browser/storage_partition_impl_unittest.cc @@ -109,8 +109,14 @@ TEST_F(StoragePartitionShaderClearTest, ClearShaderCache) { EXPECT_EQ(1u, Size()); TestClosureCallback clear_cb; - StoragePartitionImpl sp( - cache_path(), NULL, NULL, NULL, NULL, NULL, NULL, NULL); + StoragePartitionImpl sp(cache_path(), + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + scoped_ptr<WebRTCIdentityStore>()); base::MessageLoop::current()->PostTask( FROM_HERE, base::Bind(&ClearData, &sp, clear_cb.callback())); clear_cb.WaitForResult(); diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 3f12bd7..af89574 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -705,8 +705,6 @@ 'browser/media/media_internals_ui.h', 'browser/media/webrtc_identity_store.cc', 'browser/media/webrtc_identity_store.h', - 'browser/media/webrtc_identity_store_backend.cc', - 'browser/media/webrtc_identity_store_backend.h', 'browser/media/webrtc_internals.cc', 'browser/media/webrtc_internals.h', 'browser/media/webrtc_internals_message_handler.cc', diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h index b30ca42..f69feaa 100644 --- a/content/public/browser/storage_partition.h +++ b/content/public/browser/storage_partition.h @@ -64,7 +64,7 @@ class StoragePartition { REMOVE_DATA_MASK_LOCAL_STORAGE = 1 << 4, REMOVE_DATA_MASK_SHADER_CACHE = 1 << 5, REMOVE_DATA_MASK_WEBSQL = 1 << 6, - REMOVE_DATA_MASK_WEBRTC_IDENTITY = 1 << 7, + REMOVE_DATA_MASK_ALL = -1 }; |