summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/glue
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/sync/glue')
-rw-r--r--chrome/browser/sync/glue/http_bridge.cc57
-rw-r--r--chrome/browser/sync/glue/http_bridge.h46
-rw-r--r--chrome/browser/sync/glue/http_bridge_unittest.cc54
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.cc9
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.h5
5 files changed, 118 insertions, 53 deletions
diff --git a/chrome/browser/sync/glue/http_bridge.cc b/chrome/browser/sync/glue/http_bridge.cc
index dfda3b5..3448755 100644
--- a/chrome/browser/sync/glue/http_bridge.cc
+++ b/chrome/browser/sync/glue/http_bridge.cc
@@ -21,24 +21,46 @@
namespace browser_sync {
+HttpBridge::RequestContextGetter::RequestContextGetter(
+ URLRequestContextGetter* baseline_context_getter)
+ : baseline_context_getter_(baseline_context_getter) {
+}
+
+URLRequestContext* HttpBridge::RequestContextGetter::GetURLRequestContext() {
+ // Lazily create the context.
+ if (!context_) {
+ URLRequestContext* baseline_context =
+ baseline_context_getter_->GetURLRequestContext();
+ context_ = new RequestContext(baseline_context);
+ baseline_context_getter_ = NULL;
+ }
+
+ // Apply the user agent which was set earlier.
+ if (is_user_agent_set())
+ context_->set_user_agent(user_agent_);
+
+ return context_;
+}
+
HttpBridgeFactory::HttpBridgeFactory(
- URLRequestContext* baseline_context) {
- DCHECK(baseline_context != NULL);
- request_context_ = new HttpBridge::RequestContext(baseline_context);
- request_context_->AddRef();
+ URLRequestContextGetter* baseline_context_getter) {
+ DCHECK(baseline_context_getter != NULL);
+ request_context_getter_ =
+ new HttpBridge::RequestContextGetter(baseline_context_getter);
+ request_context_getter_->AddRef();
}
HttpBridgeFactory::~HttpBridgeFactory() {
- if (request_context_) {
- // Clean up request context on IO thread.
+ if (request_context_getter_) {
+ // Clean up request context getter on IO thread.
ChromeThread::GetMessageLoop(ChromeThread::IO)->ReleaseSoon(FROM_HERE,
- request_context_);
- request_context_ = NULL;
+ request_context_getter_);
+ request_context_getter_ = NULL;
}
}
sync_api::HttpPostProviderInterface* HttpBridgeFactory::Create() {
- HttpBridge* http = new HttpBridge(request_context_,
+ HttpBridge* http = new HttpBridge(request_context_getter_,
ChromeThread::GetMessageLoop(ChromeThread::IO));
http->AddRef();
return http;
@@ -87,9 +109,9 @@ HttpBridge::RequestContext::~RequestContext() {
delete http_transaction_factory_;
}
-HttpBridge::HttpBridge(HttpBridge::RequestContext* context,
+HttpBridge::HttpBridge(HttpBridge::RequestContextGetter* context_getter,
MessageLoop* io_loop)
- : context_for_request_(context),
+ : context_getter_for_request_(context_getter),
url_poster_(NULL),
created_on_loop_(MessageLoop::current()),
io_loop_(io_loop),
@@ -98,17 +120,17 @@ HttpBridge::HttpBridge(HttpBridge::RequestContext* context,
http_response_code_(-1),
http_post_completed_(false, false),
use_io_loop_for_testing_(false) {
- context_for_request_->AddRef();
+ context_getter_for_request_->AddRef();
}
HttpBridge::~HttpBridge() {
- io_loop_->ReleaseSoon(FROM_HERE, context_for_request_);
+ io_loop_->ReleaseSoon(FROM_HERE, context_getter_for_request_);
}
void HttpBridge::SetUserAgent(const char* user_agent) {
DCHECK_EQ(MessageLoop::current(), created_on_loop_);
DCHECK(!request_completed_);
- context_for_request_->set_user_agent(user_agent);
+ context_getter_for_request_->set_user_agent(user_agent);
}
void HttpBridge::SetExtraRequestHeaders(const char * headers) {
@@ -153,7 +175,6 @@ bool HttpBridge::MakeSynchronousPost(int* os_error_code, int* response_code) {
DCHECK(!request_completed_);
DCHECK(url_for_request_.is_valid()) << "Invalid URL for request";
DCHECK(!content_type_.empty()) << "Payload not set";
- DCHECK(context_for_request_->is_user_agent_set()) << "User agent not set";
io_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
&HttpBridge::CallMakeAsynchronousPost));
@@ -172,7 +193,7 @@ void HttpBridge::MakeAsynchronousPost() {
DCHECK(!request_completed_);
url_poster_ = new URLFetcher(url_for_request_, URLFetcher::POST, this);
- url_poster_->set_request_context(context_for_request_);
+ url_poster_->set_request_context(context_getter_for_request_);
url_poster_->set_upload_data(content_type_, request_content_);
url_poster_->set_extra_request_headers(extra_headers_);
@@ -194,10 +215,6 @@ const char* HttpBridge::GetResponseContent() const {
return response_content_.data();
}
-URLRequestContext* HttpBridge::GetRequestContext() const {
- return context_for_request_;
-}
-
void HttpBridge::OnURLFetchComplete(const URLFetcher *source, const GURL &url,
const URLRequestStatus &status,
int response_code,
diff --git a/chrome/browser/sync/glue/http_bridge.h b/chrome/browser/sync/glue/http_bridge.h
index ab491a0..7e1d967 100644
--- a/chrome/browser/sync/glue/http_bridge.h
+++ b/chrome/browser/sync/glue/http_bridge.h
@@ -12,6 +12,7 @@
#include "base/ref_counted.h"
#include "base/waitable_event.h"
#include "chrome/browser/net/url_fetcher.h"
+#include "chrome/browser/net/url_request_context_getter.h"
#include "chrome/browser/sync/engine/syncapi.h"
#include "googleurl/src/gurl.h"
#include "net/url_request/url_request_context.h"
@@ -53,7 +54,6 @@ class HttpBridge : public base::RefCountedThreadSafe<HttpBridge>,
// Set the user agent for requests using this context. The default is
// the browser's UA string.
void set_user_agent(const std::string& ua) { user_agent_ = ua; }
- bool is_user_agent_set() const { return !user_agent_.empty(); }
virtual const std::string& GetUserAgent(const GURL& url) const {
// If the user agent is set explicitly return that, otherwise call the
@@ -73,7 +73,31 @@ class HttpBridge : public base::RefCountedThreadSafe<HttpBridge>,
DISALLOW_COPY_AND_ASSIGN(RequestContext);
};
- HttpBridge(RequestContext* context, MessageLoop* io_loop);
+ // Lazy-getter for RequestContext objects.
+ class RequestContextGetter : public URLRequestContextGetter {
+ public:
+ explicit RequestContextGetter(
+ URLRequestContextGetter* baseline_context_getter);
+
+ void set_user_agent(const std::string& ua) { user_agent_ = ua; }
+ bool is_user_agent_set() const { return !user_agent_.empty(); }
+
+ // URLRequestContextGetter implementation.
+ virtual URLRequestContext* GetURLRequestContext();
+
+ private:
+ // User agent to apply to the URLRequestContext.
+ std::string user_agent_;
+
+ scoped_refptr<URLRequestContextGetter> baseline_context_getter_;
+
+ // Lazily initialized by GetURLRequestContext().
+ scoped_refptr<RequestContext> context_;
+
+ DISALLOW_COPY_AND_ASSIGN(RequestContextGetter);
+ };
+
+ HttpBridge(RequestContextGetter* context, MessageLoop* io_loop);
virtual ~HttpBridge();
// sync_api::HttpPostProvider implementation.
@@ -98,7 +122,11 @@ class HttpBridge : public base::RefCountedThreadSafe<HttpBridge>,
const ResponseCookies& cookies,
const std::string& data);
- URLRequestContext* GetRequestContext() const;
+#if defined(UNIT_TEST)
+ URLRequestContextGetter* GetRequestContextGetter() const {
+ return context_getter_for_request_;
+ }
+#endif
protected:
// Protected virtual so the unit test can override to shunt network requests.
@@ -112,9 +140,9 @@ class HttpBridge : public base::RefCountedThreadSafe<HttpBridge>,
// still have a function to statically pass to PostTask.
void CallMakeAsynchronousPost() { MakeAsynchronousPost(); }
- // A customized URLRequestContext for bridged requests. See RequestContext
- // definition for details.
- RequestContext* context_for_request_;
+ // Gets a customized URLRequestContext for bridged requests. See
+ // RequestContext definition for details.
+ RequestContextGetter* context_getter_for_request_;
// Our hook into the network layer is a URLFetcher. USED ONLY ON THE IO LOOP,
// so we can block created_on_loop_ while the fetch is in progress.
@@ -165,16 +193,16 @@ class HttpBridge : public base::RefCountedThreadSafe<HttpBridge>,
class HttpBridgeFactory
: public sync_api::HttpPostProviderFactory {
public:
- explicit HttpBridgeFactory(URLRequestContext* baseline_context);
+ explicit HttpBridgeFactory(URLRequestContextGetter* baseline_context_getter);
virtual ~HttpBridgeFactory();
virtual sync_api::HttpPostProviderInterface* Create();
virtual void Destroy(sync_api::HttpPostProviderInterface* http);
private:
// This request context is built on top of the baseline context and shares
// common components.
- HttpBridge::RequestContext* GetRequestContext();
+ HttpBridge::RequestContextGetter* GetRequestContextGetter();
// We must Release() this from the IO thread.
- HttpBridge::RequestContext* request_context_;
+ HttpBridge::RequestContextGetter* request_context_getter_;
DISALLOW_COPY_AND_ASSIGN(HttpBridgeFactory);
};
diff --git a/chrome/browser/sync/glue/http_bridge_unittest.cc b/chrome/browser/sync/glue/http_bridge_unittest.cc
index 32e0bc8..da3eb67 100644
--- a/chrome/browser/sync/glue/http_bridge_unittest.cc
+++ b/chrome/browser/sync/glue/http_bridge_unittest.cc
@@ -16,10 +16,22 @@ namespace {
const wchar_t kDocRoot[] = L"chrome/test/data";
}
+// Lazy getter for TestURLRequestContext instances.
+class TestURLRequestContextGetter : public URLRequestContextGetter {
+ public:
+ virtual URLRequestContext* GetURLRequestContext() {
+ if (!context_)
+ context_ = new TestURLRequestContext;
+ return context_;
+ }
+ private:
+ scoped_refptr<URLRequestContext> context_;
+};
+
class HttpBridgeTest : public testing::Test {
public:
HttpBridgeTest()
- : fake_default_request_context_(NULL),
+ : fake_default_request_context_getter_(NULL),
io_thread_("HttpBridgeTest IO thread") {
}
@@ -30,19 +42,21 @@ class HttpBridgeTest : public testing::Test {
}
virtual void TearDown() {
- io_thread_loop()->ReleaseSoon(FROM_HERE, fake_default_request_context_);
+ io_thread_loop()->ReleaseSoon(FROM_HERE,
+ fake_default_request_context_getter_);
io_thread_.Stop();
- fake_default_request_context_ = NULL;
+ fake_default_request_context_getter_ = NULL;
}
HttpBridge* BuildBridge() {
- if (!fake_default_request_context_) {
- fake_default_request_context_ = new TestURLRequestContext();
- fake_default_request_context_->AddRef();
+ if (!fake_default_request_context_getter_) {
+ fake_default_request_context_getter_ = new TestURLRequestContextGetter();
+ fake_default_request_context_getter_->AddRef();
}
HttpBridge* bridge = new HttpBridge(
- new HttpBridge::RequestContext(fake_default_request_context_),
- io_thread_.message_loop());
+ new HttpBridge::RequestContextGetter(
+ fake_default_request_context_getter_),
+ io_thread_loop());
bridge->use_io_loop_for_testing_ = true;
return bridge;
}
@@ -50,14 +64,14 @@ class HttpBridgeTest : public testing::Test {
MessageLoop* io_thread_loop() { return io_thread_.message_loop(); }
// Note this is lazy created, so don't call this before your bridge.
- TestURLRequestContext* GetTestRequestContext() {
- return fake_default_request_context_;
+ TestURLRequestContextGetter* GetTestRequestContextGetter() {
+ return fake_default_request_context_getter_;
}
private:
// A make-believe "default" request context, as would be returned by
// Profile::GetDefaultRequestContext(). Created lazily by BuildBridge.
- TestURLRequestContext* fake_default_request_context_;
+ TestURLRequestContextGetter* fake_default_request_context_getter_;
// Separate thread for IO used by the HttpBridge.
base::Thread io_thread_;
@@ -67,9 +81,10 @@ class HttpBridgeTest : public testing::Test {
// back with dummy response info.
class ShuntedHttpBridge : public HttpBridge {
public:
- ShuntedHttpBridge(URLRequestContext* baseline_context,
+ ShuntedHttpBridge(URLRequestContextGetter* baseline_context_getter,
MessageLoop* io_loop, HttpBridgeTest* test)
- : HttpBridge(new HttpBridge::RequestContext(baseline_context),
+ : HttpBridge(new HttpBridge::RequestContextGetter(
+ baseline_context_getter),
io_loop), test_(test) { }
protected:
virtual void MakeAsynchronousPost() {
@@ -94,19 +109,22 @@ class ShuntedHttpBridge : public HttpBridge {
TEST_F(HttpBridgeTest, TestUsesSameHttpNetworkSession) {
scoped_refptr<HttpBridge> http_bridge(this->BuildBridge());
- EXPECT_TRUE(GetTestRequestContext());
+ EXPECT_TRUE(GetTestRequestContextGetter());
net::HttpNetworkSession* test_session =
- GetTestRequestContext()->http_transaction_factory()->GetSession();
+ GetTestRequestContextGetter()->GetURLRequestContext()->
+ http_transaction_factory()->GetSession();
EXPECT_EQ(test_session,
- http_bridge->GetRequestContext()->
+ http_bridge->GetRequestContextGetter()->
+ GetURLRequestContext()->
http_transaction_factory()->GetSession());
}
// Test the HttpBridge without actually making any network requests.
TEST_F(HttpBridgeTest, TestMakeSynchronousPostShunted) {
- scoped_refptr<TestURLRequestContext> ctx(new TestURLRequestContext());
+ scoped_refptr<URLRequestContextGetter> ctx_getter(
+ new TestURLRequestContextGetter());
scoped_refptr<HttpBridge> http_bridge(new ShuntedHttpBridge(
- ctx, io_thread_loop(), this));
+ ctx_getter, io_thread_loop(), this));
http_bridge->SetUserAgent("bob");
http_bridge->SetURL("http://www.google.com", 9999);
http_bridge->SetPostPayload("text/plain", 2, " ");
diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc
index 8432381..4c38711 100644
--- a/chrome/browser/sync/glue/sync_backend_host.cc
+++ b/chrome/browser/sync/glue/sync_backend_host.cc
@@ -40,8 +40,9 @@ SyncBackendHost::~SyncBackendHost() {
DCHECK(!core_ && !frontend_) << "Must call Shutdown before destructor.";
}
-void SyncBackendHost::Initialize(const GURL& sync_service_url,
- URLRequestContext* baseline_context) {
+void SyncBackendHost::Initialize(
+ const GURL& sync_service_url,
+ URLRequestContextGetter* baseline_context_getter) {
if (!core_thread_.Start())
return;
bookmark_model_worker_ = new BookmarkModelWorker(frontend_loop_);
@@ -49,8 +50,8 @@ void SyncBackendHost::Initialize(const GURL& sync_service_url,
core_thread_.message_loop()->PostTask(FROM_HERE,
NewRunnableMethod(core_.get(), &SyncBackendHost::Core::DoInitialize,
sync_service_url, bookmark_model_worker_, true,
- new HttpBridgeFactory(baseline_context),
- new HttpBridgeFactory(baseline_context)));
+ new HttpBridgeFactory(baseline_context_getter),
+ new HttpBridgeFactory(baseline_context_getter)));
}
void SyncBackendHost::Authenticate(const std::string& username,
diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h
index 3fad2c7..f0a1cd4 100644
--- a/chrome/browser/sync/glue/sync_backend_host.h
+++ b/chrome/browser/sync/glue/sync_backend_host.h
@@ -15,11 +15,11 @@
#include "base/ref_counted.h"
#include "base/thread.h"
#include "base/timer.h"
+#include "chrome/browser/net/url_request_context_getter.h"
#include "chrome/browser/sync/auth_error_state.h"
#include "chrome/browser/sync/engine/syncapi.h"
#include "chrome/browser/sync/glue/bookmark_model_worker.h"
#include "googleurl/src/gurl.h"
-#include "net/url_request/url_request_context.h"
namespace browser_sync {
@@ -85,7 +85,8 @@ class SyncBackendHost {
~SyncBackendHost();
// Called on |frontend_loop_| to kick off asynchronous initialization.
- void Initialize(const GURL& service_url, URLRequestContext* baseline_context);
+ void Initialize(const GURL& service_url,
+ URLRequestContextGetter* baseline_context_getter);
// Called on |frontend_loop_| to kick off asynchronous authentication.
void Authenticate(const std::string& username, const std::string& password);