Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: sync/internal_api/http_bridge.cc

Issue 10645004: [Sync] Move HttpBridge to sync/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync to head Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sync/internal_api/DEPS ('k') | sync/internal_api/http_bridge_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/glue/http_bridge.h" 5 #include "sync/internal_api/public/http_bridge.h"
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/message_loop_proxy.h" 8 #include "base/message_loop_proxy.h"
9 #include "base/string_number_conversions.h" 9 #include "base/string_number_conversions.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/common/content_client.h"
12 #include "net/base/host_resolver.h" 10 #include "net/base/host_resolver.h"
13 #include "net/base/load_flags.h" 11 #include "net/base/load_flags.h"
14 #include "net/base/net_errors.h" 12 #include "net/base/net_errors.h"
15 #include "net/cookies/cookie_monster.h" 13 #include "net/cookies/cookie_monster.h"
16 #include "net/http/http_cache.h" 14 #include "net/http/http_cache.h"
17 #include "net/http/http_network_layer.h" 15 #include "net/http/http_network_layer.h"
18 #include "net/http/http_response_headers.h" 16 #include "net/http/http_response_headers.h"
19 #include "net/proxy/proxy_service.h" 17 #include "net/proxy/proxy_service.h"
20 #include "net/url_request/url_fetcher.h" 18 #include "net/url_request/url_fetcher.h"
21 #include "net/url_request/url_request_context.h" 19 #include "net/url_request/url_request_context.h"
22 #include "net/url_request/url_request_status.h" 20 #include "net/url_request/url_request_status.h"
23 21
24 using content::BrowserThread;
25
26 namespace browser_sync { 22 namespace browser_sync {
27 23
28 HttpBridge::RequestContextGetter::RequestContextGetter( 24 HttpBridge::RequestContextGetter::RequestContextGetter(
29 net::URLRequestContextGetter* baseline_context_getter) 25 net::URLRequestContextGetter* baseline_context_getter,
30 : baseline_context_getter_(baseline_context_getter) { 26 const std::string& user_agent)
27 : baseline_context_getter_(baseline_context_getter),
28 network_task_runner_(
29 baseline_context_getter_->GetNetworkTaskRunner()),
30 user_agent_(user_agent) {
31 DCHECK(baseline_context_getter_);
32 DCHECK(network_task_runner_);
33 DCHECK(!user_agent_.empty());
31 } 34 }
32 35
33 HttpBridge::RequestContextGetter::~RequestContextGetter() {} 36 HttpBridge::RequestContextGetter::~RequestContextGetter() {}
34 37
35 net::URLRequestContext* 38 net::URLRequestContext*
36 HttpBridge::RequestContextGetter::GetURLRequestContext() { 39 HttpBridge::RequestContextGetter::GetURLRequestContext() {
37 // Lazily create the context. 40 // Lazily create the context.
38 if (!context_.get()) { 41 if (!context_.get()) {
39 net::URLRequestContext* baseline_context = 42 net::URLRequestContext* baseline_context =
40 baseline_context_getter_->GetURLRequestContext(); 43 baseline_context_getter_->GetURLRequestContext();
41 context_.reset(new RequestContext(baseline_context)); 44 context_.reset(
45 new RequestContext(baseline_context, GetNetworkTaskRunner(),
46 user_agent_));
42 baseline_context_getter_ = NULL; 47 baseline_context_getter_ = NULL;
43 } 48 }
44 49
45 // Apply the user agent which was set earlier.
46 if (is_user_agent_set())
47 context_->set_user_agent(user_agent_);
48
49 return context_.get(); 50 return context_.get();
50 } 51 }
51 52
52 scoped_refptr<base::SingleThreadTaskRunner> 53 scoped_refptr<base::SingleThreadTaskRunner>
53 HttpBridge::RequestContextGetter::GetNetworkTaskRunner() const { 54 HttpBridge::RequestContextGetter::GetNetworkTaskRunner() const {
54 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 55 return network_task_runner_;
55 } 56 }
56 57
57 HttpBridgeFactory::HttpBridgeFactory( 58 HttpBridgeFactory::HttpBridgeFactory(
58 net::URLRequestContextGetter* baseline_context_getter) { 59 net::URLRequestContextGetter* baseline_context_getter,
59 DCHECK(baseline_context_getter != NULL); 60 const std::string& user_agent)
60 request_context_getter_ = 61 : request_context_getter_(
61 new HttpBridge::RequestContextGetter(baseline_context_getter); 62 new HttpBridge::RequestContextGetter(
62 } 63 baseline_context_getter, user_agent)) {}
63 64
64 HttpBridgeFactory::~HttpBridgeFactory() { 65 HttpBridgeFactory::~HttpBridgeFactory() {
65 } 66 }
66 67
67 csync::HttpPostProviderInterface* HttpBridgeFactory::Create() { 68 csync::HttpPostProviderInterface* HttpBridgeFactory::Create() {
68 HttpBridge* http = new HttpBridge(request_context_getter_); 69 HttpBridge* http = new HttpBridge(request_context_getter_);
69 http->AddRef(); 70 http->AddRef();
70 return http; 71 return http;
71 } 72 }
72 73
73 void HttpBridgeFactory::Destroy(csync::HttpPostProviderInterface* http) { 74 void HttpBridgeFactory::Destroy(csync::HttpPostProviderInterface* http) {
74 static_cast<HttpBridge*>(http)->Release(); 75 static_cast<HttpBridge*>(http)->Release();
75 } 76 }
76 77
77 HttpBridge::RequestContext::RequestContext( 78 HttpBridge::RequestContext::RequestContext(
78 net::URLRequestContext* baseline_context) 79 net::URLRequestContext* baseline_context,
79 : baseline_context_(baseline_context) { 80 const scoped_refptr<base::SingleThreadTaskRunner>&
81 network_task_runner,
82 const std::string& user_agent)
83 : baseline_context_(baseline_context),
84 network_task_runner_(network_task_runner),
85 user_agent_(user_agent) {
86 DCHECK(!user_agent_.empty());
80 87
81 // Create empty, in-memory cookie store. 88 // Create empty, in-memory cookie store.
82 set_cookie_store(new net::CookieMonster(NULL, NULL)); 89 set_cookie_store(new net::CookieMonster(NULL, NULL));
83 90
84 // We don't use a cache for bridged loads, but we do want to share proxy info. 91 // We don't use a cache for bridged loads, but we do want to share proxy info.
85 set_host_resolver(baseline_context->host_resolver()); 92 set_host_resolver(baseline_context->host_resolver());
86 set_proxy_service(baseline_context->proxy_service()); 93 set_proxy_service(baseline_context->proxy_service());
87 set_ssl_config_service(baseline_context->ssl_config_service()); 94 set_ssl_config_service(baseline_context->ssl_config_service());
88 95
89 // We want to share the HTTP session data with the network layer factory, 96 // We want to share the HTTP session data with the network layer factory,
90 // which includes auth_cache for proxies. 97 // which includes auth_cache for proxies.
91 // Session is not refcounted so we need to be careful to not lose the parent 98 // Session is not refcounted so we need to be careful to not lose the parent
92 // context. 99 // context.
93 net::HttpNetworkSession* session = 100 net::HttpNetworkSession* session =
94 baseline_context->http_transaction_factory()->GetSession(); 101 baseline_context->http_transaction_factory()->GetSession();
95 DCHECK(session); 102 DCHECK(session);
96 set_http_transaction_factory(new net::HttpNetworkLayer(session)); 103 set_http_transaction_factory(new net::HttpNetworkLayer(session));
97 104
98 // TODO(timsteele): We don't currently listen for pref changes of these 105 // TODO(timsteele): We don't currently listen for pref changes of these
99 // fields or CookiePolicy; I'm not sure we want to strictly follow the 106 // fields or CookiePolicy; I'm not sure we want to strictly follow the
100 // default settings, since for example if the user chooses to block all 107 // default settings, since for example if the user chooses to block all
101 // cookies, sync will start failing. Also it seems like accept_lang/charset 108 // cookies, sync will start failing. Also it seems like accept_lang/charset
102 // should be tied to whatever the sync servers expect (if anything). These 109 // should be tied to whatever the sync servers expect (if anything). These
103 // fields should probably just be settable by sync backend; though we should 110 // fields should probably just be settable by sync backend; though we should
104 // figure out if we need to give the user explicit control over policies etc. 111 // figure out if we need to give the user explicit control over policies etc.
105 set_accept_language(baseline_context->accept_language()); 112 set_accept_language(baseline_context->accept_language());
106 set_accept_charset(baseline_context->accept_charset()); 113 set_accept_charset(baseline_context->accept_charset());
107 114
108 // We default to the browser's user agent. This can (and should) be overridden
109 // with set_user_agent.
110 set_user_agent(content::GetUserAgent(GURL()));
111
112 set_net_log(baseline_context->net_log()); 115 set_net_log(baseline_context->net_log());
113 } 116 }
114 117
115 HttpBridge::RequestContext::~RequestContext() { 118 HttpBridge::RequestContext::~RequestContext() {
116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 119 DCHECK(network_task_runner_->BelongsToCurrentThread());
117 delete http_transaction_factory(); 120 delete http_transaction_factory();
118 } 121 }
119 122
123 const std::string& HttpBridge::RequestContext::GetUserAgent(
124 const GURL& url) const {
125 return user_agent_;
126 }
127
120 HttpBridge::URLFetchState::URLFetchState() : url_poster(NULL), 128 HttpBridge::URLFetchState::URLFetchState() : url_poster(NULL),
121 aborted(false), 129 aborted(false),
122 request_completed(false), 130 request_completed(false),
123 request_succeeded(false), 131 request_succeeded(false),
124 http_response_code(-1), 132 http_response_code(-1),
125 error_code(-1) {} 133 error_code(-1) {}
126 HttpBridge::URLFetchState::~URLFetchState() {} 134 HttpBridge::URLFetchState::~URLFetchState() {}
127 135
128 HttpBridge::HttpBridge(HttpBridge::RequestContextGetter* context_getter) 136 HttpBridge::HttpBridge(HttpBridge::RequestContextGetter* context_getter)
129 : context_getter_for_request_(context_getter), 137 : context_getter_for_request_(context_getter),
138 network_task_runner_(
139 context_getter_for_request_->GetNetworkTaskRunner()),
130 created_on_loop_(MessageLoop::current()), 140 created_on_loop_(MessageLoop::current()),
131 http_post_completed_(false, false) { 141 http_post_completed_(false, false) {
132 } 142 }
133 143
134 HttpBridge::~HttpBridge() { 144 HttpBridge::~HttpBridge() {
135 } 145 }
136 146
137 void HttpBridge::SetUserAgent(const char* user_agent) {
138 DCHECK_EQ(MessageLoop::current(), created_on_loop_);
139 if (DCHECK_IS_ON()) {
140 base::AutoLock lock(fetch_state_lock_);
141 DCHECK(!fetch_state_.request_completed);
142 }
143 context_getter_for_request_->set_user_agent(user_agent);
144 }
145
146 void HttpBridge::SetExtraRequestHeaders(const char * headers) { 147 void HttpBridge::SetExtraRequestHeaders(const char * headers) {
147 DCHECK(extra_headers_.empty()) 148 DCHECK(extra_headers_.empty())
148 << "HttpBridge::SetExtraRequestHeaders called twice."; 149 << "HttpBridge::SetExtraRequestHeaders called twice.";
149 extra_headers_.assign(headers); 150 extra_headers_.assign(headers);
150 } 151 }
151 152
152 void HttpBridge::SetURL(const char* url, int port) { 153 void HttpBridge::SetURL(const char* url, int port) {
153 DCHECK_EQ(MessageLoop::current(), created_on_loop_); 154 DCHECK_EQ(MessageLoop::current(), created_on_loop_);
154 if (DCHECK_IS_ON()) { 155 if (DCHECK_IS_ON()) {
155 base::AutoLock lock(fetch_state_lock_); 156 base::AutoLock lock(fetch_state_lock_);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 189
189 bool HttpBridge::MakeSynchronousPost(int* error_code, int* response_code) { 190 bool HttpBridge::MakeSynchronousPost(int* error_code, int* response_code) {
190 DCHECK_EQ(MessageLoop::current(), created_on_loop_); 191 DCHECK_EQ(MessageLoop::current(), created_on_loop_);
191 if (DCHECK_IS_ON()) { 192 if (DCHECK_IS_ON()) {
192 base::AutoLock lock(fetch_state_lock_); 193 base::AutoLock lock(fetch_state_lock_);
193 DCHECK(!fetch_state_.request_completed); 194 DCHECK(!fetch_state_.request_completed);
194 } 195 }
195 DCHECK(url_for_request_.is_valid()) << "Invalid URL for request"; 196 DCHECK(url_for_request_.is_valid()) << "Invalid URL for request";
196 DCHECK(!content_type_.empty()) << "Payload not set"; 197 DCHECK(!content_type_.empty()) << "Payload not set";
197 198
198 if (!BrowserThread::PostTask( 199 if (!network_task_runner_->PostTask(
199 BrowserThread::IO, FROM_HERE, 200 FROM_HERE,
200 base::Bind(&HttpBridge::CallMakeAsynchronousPost, this))) { 201 base::Bind(&HttpBridge::CallMakeAsynchronousPost, this))) {
201 // This usually happens when we're in a unit test. 202 // This usually happens when we're in a unit test.
202 LOG(WARNING) << "Could not post CallMakeAsynchronousPost task"; 203 LOG(WARNING) << "Could not post CallMakeAsynchronousPost task";
203 return false; 204 return false;
204 } 205 }
205 206
206 // Block until network request completes or is aborted. See 207 // Block until network request completes or is aborted. See
207 // OnURLFetchComplete and Abort. 208 // OnURLFetchComplete and Abort.
208 http_post_completed_.Wait(); 209 http_post_completed_.Wait();
209 210
210 base::AutoLock lock(fetch_state_lock_); 211 base::AutoLock lock(fetch_state_lock_);
211 DCHECK(fetch_state_.request_completed || fetch_state_.aborted); 212 DCHECK(fetch_state_.request_completed || fetch_state_.aborted);
212 *error_code = fetch_state_.error_code; 213 *error_code = fetch_state_.error_code;
213 *response_code = fetch_state_.http_response_code; 214 *response_code = fetch_state_.http_response_code;
214 return fetch_state_.request_succeeded; 215 return fetch_state_.request_succeeded;
215 } 216 }
216 217
217 void HttpBridge::MakeAsynchronousPost() { 218 void HttpBridge::MakeAsynchronousPost() {
218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 219 DCHECK(network_task_runner_->BelongsToCurrentThread());
219 base::AutoLock lock(fetch_state_lock_); 220 base::AutoLock lock(fetch_state_lock_);
220 DCHECK(!fetch_state_.request_completed); 221 DCHECK(!fetch_state_.request_completed);
221 if (fetch_state_.aborted) 222 if (fetch_state_.aborted)
222 return; 223 return;
223 224
224 fetch_state_.url_poster = net::URLFetcher::Create( 225 fetch_state_.url_poster = net::URLFetcher::Create(
225 url_for_request_, net::URLFetcher::POST, this); 226 url_for_request_, net::URLFetcher::POST, this);
226 fetch_state_.url_poster->SetRequestContext(context_getter_for_request_); 227 fetch_state_.url_poster->SetRequestContext(context_getter_for_request_);
227 fetch_state_.url_poster->SetUploadData(content_type_, request_content_); 228 fetch_state_.url_poster->SetUploadData(content_type_, request_content_);
228 fetch_state_.url_poster->SetExtraRequestHeaders(extra_headers_); 229 fetch_state_.url_poster->SetExtraRequestHeaders(extra_headers_);
(...skipping 27 matching lines...) Expand all
256 return value; 257 return value;
257 } 258 }
258 259
259 void HttpBridge::Abort() { 260 void HttpBridge::Abort() {
260 base::AutoLock lock(fetch_state_lock_); 261 base::AutoLock lock(fetch_state_lock_);
261 DCHECK(!fetch_state_.aborted); 262 DCHECK(!fetch_state_.aborted);
262 if (fetch_state_.aborted || fetch_state_.request_completed) 263 if (fetch_state_.aborted || fetch_state_.request_completed)
263 return; 264 return;
264 265
265 fetch_state_.aborted = true; 266 fetch_state_.aborted = true;
266 if (!BrowserThread::PostTask( 267 if (!network_task_runner_->PostTask(
267 BrowserThread::IO, FROM_HERE, 268 FROM_HERE,
268 base::Bind(&HttpBridge::DestroyURLFetcherOnIOThread, this, 269 base::Bind(&HttpBridge::DestroyURLFetcherOnIOThread, this,
269 fetch_state_.url_poster))) { 270 fetch_state_.url_poster))) {
270 // Madness ensues. 271 // Madness ensues.
271 NOTREACHED() << "Could not post task to delete URLFetcher"; 272 NOTREACHED() << "Could not post task to delete URLFetcher";
272 } 273 }
273 274
274 fetch_state_.url_poster = NULL; 275 fetch_state_.url_poster = NULL;
275 fetch_state_.error_code = net::ERR_ABORTED; 276 fetch_state_.error_code = net::ERR_ABORTED;
276 http_post_completed_.Signal(); 277 http_post_completed_.Signal();
277 } 278 }
278 279
279 void HttpBridge::DestroyURLFetcherOnIOThread(net::URLFetcher* fetcher) { 280 void HttpBridge::DestroyURLFetcherOnIOThread(net::URLFetcher* fetcher) {
280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 281 DCHECK(network_task_runner_->BelongsToCurrentThread());
281 delete fetcher; 282 delete fetcher;
282 } 283 }
283 284
284 void HttpBridge::OnURLFetchComplete(const net::URLFetcher* source) { 285 void HttpBridge::OnURLFetchComplete(const net::URLFetcher* source) {
285 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 286 DCHECK(network_task_runner_->BelongsToCurrentThread());
286 base::AutoLock lock(fetch_state_lock_); 287 base::AutoLock lock(fetch_state_lock_);
287 if (fetch_state_.aborted) 288 if (fetch_state_.aborted)
288 return; 289 return;
289 290
290 fetch_state_.request_completed = true; 291 fetch_state_.request_completed = true;
291 fetch_state_.request_succeeded = 292 fetch_state_.request_succeeded =
292 (net::URLRequestStatus::SUCCESS == source->GetStatus().status()); 293 (net::URLRequestStatus::SUCCESS == source->GetStatus().status());
293 fetch_state_.http_response_code = source->GetResponseCode(); 294 fetch_state_.http_response_code = source->GetResponseCode();
294 fetch_state_.error_code = source->GetStatus().error(); 295 fetch_state_.error_code = source->GetStatus().error();
295 296
(...skipping 11 matching lines...) Expand all
307 // URLFetcher, so it seems most natural / "polite" to let the stack unwind. 308 // URLFetcher, so it seems most natural / "polite" to let the stack unwind.
308 MessageLoop::current()->DeleteSoon(FROM_HERE, fetch_state_.url_poster); 309 MessageLoop::current()->DeleteSoon(FROM_HERE, fetch_state_.url_poster);
309 fetch_state_.url_poster = NULL; 310 fetch_state_.url_poster = NULL;
310 311
311 // Wake the blocked syncer thread in MakeSynchronousPost. 312 // Wake the blocked syncer thread in MakeSynchronousPost.
312 // WARNING: DONT DO ANYTHING AFTER THIS CALL! |this| may be deleted! 313 // WARNING: DONT DO ANYTHING AFTER THIS CALL! |this| may be deleted!
313 http_post_completed_.Signal(); 314 http_post_completed_.Signal();
314 } 315 }
315 316
316 } // namespace browser_sync 317 } // namespace browser_sync
OLDNEW
« no previous file with comments | « sync/internal_api/DEPS ('k') | sync/internal_api/http_bridge_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698