OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #if defined(BROWSER_SYNC) | 5 #if defined(BROWSER_SYNC) |
6 | 6 |
7 #include "chrome/browser/sync/glue/http_bridge.h" | 7 #include "chrome/browser/sync/glue/http_bridge.h" |
8 | 8 |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "chrome/browser/chrome_thread.h" | 11 #include "chrome/browser/chrome_thread.h" |
12 #include "chrome/browser/profile.h" | 12 #include "chrome/browser/profile.h" |
| 13 #include "chrome/browser/chrome_thread.h" |
13 #include "net/base/cookie_monster.h" | 14 #include "net/base/cookie_monster.h" |
14 #include "net/base/load_flags.h" | 15 #include "net/base/load_flags.h" |
15 #include "net/http/http_cache.h" | 16 #include "net/http/http_cache.h" |
16 #include "net/http/http_network_layer.h" | 17 #include "net/http/http_network_layer.h" |
17 #include "net/proxy/proxy_service.h" | 18 #include "net/proxy/proxy_service.h" |
18 #include "net/url_request/url_request_context.h" | 19 #include "net/url_request/url_request_context.h" |
19 #include "net/url_request/url_request_status.h" | 20 #include "net/url_request/url_request_status.h" |
20 #include "webkit/glue/webkit_glue.h" | 21 #include "webkit/glue/webkit_glue.h" |
21 | 22 |
22 namespace browser_sync { | 23 namespace browser_sync { |
(...skipping 23 matching lines...) Expand all Loading... |
46 URLRequestContextGetter* baseline_context_getter) { | 47 URLRequestContextGetter* baseline_context_getter) { |
47 DCHECK(baseline_context_getter != NULL); | 48 DCHECK(baseline_context_getter != NULL); |
48 request_context_getter_ = | 49 request_context_getter_ = |
49 new HttpBridge::RequestContextGetter(baseline_context_getter); | 50 new HttpBridge::RequestContextGetter(baseline_context_getter); |
50 request_context_getter_->AddRef(); | 51 request_context_getter_->AddRef(); |
51 } | 52 } |
52 | 53 |
53 HttpBridgeFactory::~HttpBridgeFactory() { | 54 HttpBridgeFactory::~HttpBridgeFactory() { |
54 if (request_context_getter_) { | 55 if (request_context_getter_) { |
55 // Clean up request context getter on IO thread. | 56 // Clean up request context getter on IO thread. |
56 ChromeThread::GetMessageLoop(ChromeThread::IO)->ReleaseSoon(FROM_HERE, | 57 bool posted = ChromeThread::ReleaseSoon( |
57 request_context_getter_); | 58 ChromeThread::IO, FROM_HERE, request_context_getter_); |
| 59 DCHECK(posted); |
58 request_context_getter_ = NULL; | 60 request_context_getter_ = NULL; |
59 } | 61 } |
60 } | 62 } |
61 | 63 |
62 sync_api::HttpPostProviderInterface* HttpBridgeFactory::Create() { | 64 sync_api::HttpPostProviderInterface* HttpBridgeFactory::Create() { |
63 HttpBridge* http = new HttpBridge(request_context_getter_, | 65 HttpBridge* http = new HttpBridge(request_context_getter_); |
64 ChromeThread::GetMessageLoop(ChromeThread::IO)); | |
65 http->AddRef(); | 66 http->AddRef(); |
66 return http; | 67 return http; |
67 } | 68 } |
68 | 69 |
69 void HttpBridgeFactory::Destroy(sync_api::HttpPostProviderInterface* http) { | 70 void HttpBridgeFactory::Destroy(sync_api::HttpPostProviderInterface* http) { |
70 static_cast<HttpBridge*>(http)->Release(); | 71 static_cast<HttpBridge*>(http)->Release(); |
71 } | 72 } |
72 | 73 |
73 HttpBridge::RequestContext::RequestContext(URLRequestContext* baseline_context) | 74 HttpBridge::RequestContext::RequestContext(URLRequestContext* baseline_context) |
74 : baseline_context_(baseline_context) { | 75 : baseline_context_(baseline_context) { |
(...skipping 27 matching lines...) Expand all Loading... |
102 | 103 |
103 // We default to the browser's user agent. This can (and should) be overridden | 104 // We default to the browser's user agent. This can (and should) be overridden |
104 // with set_user_agent. | 105 // with set_user_agent. |
105 user_agent_ = webkit_glue::GetUserAgent(GURL()); | 106 user_agent_ = webkit_glue::GetUserAgent(GURL()); |
106 } | 107 } |
107 | 108 |
108 HttpBridge::RequestContext::~RequestContext() { | 109 HttpBridge::RequestContext::~RequestContext() { |
109 delete http_transaction_factory_; | 110 delete http_transaction_factory_; |
110 } | 111 } |
111 | 112 |
112 HttpBridge::HttpBridge(HttpBridge::RequestContextGetter* context_getter, | 113 HttpBridge::HttpBridge(HttpBridge::RequestContextGetter* context_getter) |
113 MessageLoop* io_loop) | |
114 : context_getter_for_request_(context_getter), | 114 : context_getter_for_request_(context_getter), |
115 url_poster_(NULL), | 115 url_poster_(NULL), |
116 created_on_loop_(MessageLoop::current()), | 116 created_on_loop_(MessageLoop::current()), |
117 io_loop_(io_loop), | |
118 request_completed_(false), | 117 request_completed_(false), |
119 request_succeeded_(false), | 118 request_succeeded_(false), |
120 http_response_code_(-1), | 119 http_response_code_(-1), |
121 http_post_completed_(false, false), | 120 http_post_completed_(false, false) { |
122 use_io_loop_for_testing_(false) { | |
123 context_getter_for_request_->AddRef(); | 121 context_getter_for_request_->AddRef(); |
124 } | 122 } |
125 | 123 |
126 HttpBridge::~HttpBridge() { | 124 HttpBridge::~HttpBridge() { |
127 io_loop_->ReleaseSoon(FROM_HERE, context_getter_for_request_); | 125 bool posted = ChromeThread::ReleaseSoon( |
| 126 ChromeThread::IO, FROM_HERE, context_getter_for_request_); |
| 127 DCHECK(posted); |
128 } | 128 } |
129 | 129 |
130 void HttpBridge::SetUserAgent(const char* user_agent) { | 130 void HttpBridge::SetUserAgent(const char* user_agent) { |
131 DCHECK_EQ(MessageLoop::current(), created_on_loop_); | 131 DCHECK_EQ(MessageLoop::current(), created_on_loop_); |
132 DCHECK(!request_completed_); | 132 DCHECK(!request_completed_); |
133 context_getter_for_request_->set_user_agent(user_agent); | 133 context_getter_for_request_->set_user_agent(user_agent); |
134 } | 134 } |
135 | 135 |
136 void HttpBridge::SetExtraRequestHeaders(const char * headers) { | 136 void HttpBridge::SetExtraRequestHeaders(const char * headers) { |
137 DCHECK(extra_headers_.empty()) | 137 DCHECK(extra_headers_.empty()) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 request_content_.assign(content, content_length); | 169 request_content_.assign(content, content_length); |
170 } | 170 } |
171 } | 171 } |
172 | 172 |
173 bool HttpBridge::MakeSynchronousPost(int* os_error_code, int* response_code) { | 173 bool HttpBridge::MakeSynchronousPost(int* os_error_code, int* response_code) { |
174 DCHECK_EQ(MessageLoop::current(), created_on_loop_); | 174 DCHECK_EQ(MessageLoop::current(), created_on_loop_); |
175 DCHECK(!request_completed_); | 175 DCHECK(!request_completed_); |
176 DCHECK(url_for_request_.is_valid()) << "Invalid URL for request"; | 176 DCHECK(url_for_request_.is_valid()) << "Invalid URL for request"; |
177 DCHECK(!content_type_.empty()) << "Payload not set"; | 177 DCHECK(!content_type_.empty()) << "Payload not set"; |
178 | 178 |
179 io_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, | 179 ChromeThread::PostTask( |
180 &HttpBridge::CallMakeAsynchronousPost)); | 180 ChromeThread::IO, FROM_HERE, |
| 181 NewRunnableMethod(this, &HttpBridge::CallMakeAsynchronousPost)); |
181 | 182 |
182 if (!http_post_completed_.Wait()) // Block until network request completes. | 183 if (!http_post_completed_.Wait()) // Block until network request completes. |
183 NOTREACHED(); // See OnURLFetchComplete. | 184 NOTREACHED(); // See OnURLFetchComplete. |
184 | 185 |
185 DCHECK(request_completed_); | 186 DCHECK(request_completed_); |
186 *os_error_code = os_error_code_; | 187 *os_error_code = os_error_code_; |
187 *response_code = http_response_code_; | 188 *response_code = http_response_code_; |
188 return request_succeeded_; | 189 return request_succeeded_; |
189 } | 190 } |
190 | 191 |
191 void HttpBridge::MakeAsynchronousPost() { | 192 void HttpBridge::MakeAsynchronousPost() { |
192 DCHECK_EQ(MessageLoop::current(), io_loop_); | 193 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
193 DCHECK(!request_completed_); | 194 DCHECK(!request_completed_); |
194 | 195 |
195 url_poster_ = new URLFetcher(url_for_request_, URLFetcher::POST, this); | 196 url_poster_ = new URLFetcher(url_for_request_, URLFetcher::POST, this); |
196 url_poster_->set_request_context(context_getter_for_request_); | 197 url_poster_->set_request_context(context_getter_for_request_); |
197 url_poster_->set_upload_data(content_type_, request_content_); | 198 url_poster_->set_upload_data(content_type_, request_content_); |
198 url_poster_->set_extra_request_headers(extra_headers_); | 199 url_poster_->set_extra_request_headers(extra_headers_); |
199 | |
200 if (use_io_loop_for_testing_) | |
201 url_poster_->set_io_loop(io_loop_); | |
202 | |
203 url_poster_->Start(); | 200 url_poster_->Start(); |
204 } | 201 } |
205 | 202 |
206 int HttpBridge::GetResponseContentLength() const { | 203 int HttpBridge::GetResponseContentLength() const { |
207 DCHECK_EQ(MessageLoop::current(), created_on_loop_); | 204 DCHECK_EQ(MessageLoop::current(), created_on_loop_); |
208 DCHECK(request_completed_); | 205 DCHECK(request_completed_); |
209 return response_content_.size(); | 206 return response_content_.size(); |
210 } | 207 } |
211 | 208 |
212 const char* HttpBridge::GetResponseContent() const { | 209 const char* HttpBridge::GetResponseContent() const { |
213 DCHECK_EQ(MessageLoop::current(), created_on_loop_); | 210 DCHECK_EQ(MessageLoop::current(), created_on_loop_); |
214 DCHECK(request_completed_); | 211 DCHECK(request_completed_); |
215 return response_content_.data(); | 212 return response_content_.data(); |
216 } | 213 } |
217 | 214 |
218 void HttpBridge::OnURLFetchComplete(const URLFetcher *source, const GURL &url, | 215 void HttpBridge::OnURLFetchComplete(const URLFetcher *source, const GURL &url, |
219 const URLRequestStatus &status, | 216 const URLRequestStatus &status, |
220 int response_code, | 217 int response_code, |
221 const ResponseCookies &cookies, | 218 const ResponseCookies &cookies, |
222 const std::string &data) { | 219 const std::string &data) { |
223 DCHECK_EQ(MessageLoop::current(), io_loop_); | 220 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
224 | 221 |
225 request_completed_ = true; | 222 request_completed_ = true; |
226 request_succeeded_ = (URLRequestStatus::SUCCESS == status.status()); | 223 request_succeeded_ = (URLRequestStatus::SUCCESS == status.status()); |
227 http_response_code_ = response_code; | 224 http_response_code_ = response_code; |
228 os_error_code_ = status.os_error(); | 225 os_error_code_ = status.os_error(); |
229 | 226 |
230 response_content_ = data; | 227 response_content_ = data; |
231 | 228 |
232 // End of the line for url_poster_. It lives only on the io_loop. | 229 // End of the line for url_poster_. It lives only on the IO loop. |
233 // We defer deletion because we're inside a callback from a component of the | 230 // We defer deletion because we're inside a callback from a component of the |
234 // URLFetcher, so it seems most natural / "polite" to let the stack unwind. | 231 // URLFetcher, so it seems most natural / "polite" to let the stack unwind. |
235 io_loop_->DeleteSoon(FROM_HERE, url_poster_); | 232 MessageLoop::current()->DeleteSoon(FROM_HERE, url_poster_); |
236 url_poster_ = NULL; | 233 url_poster_ = NULL; |
237 | 234 |
238 // Wake the blocked syncer thread in MakeSynchronousPost. | 235 // Wake the blocked syncer thread in MakeSynchronousPost. |
239 // WARNING: DONT DO ANYTHING AFTER THIS CALL! |this| may be deleted! | 236 // WARNING: DONT DO ANYTHING AFTER THIS CALL! |this| may be deleted! |
240 http_post_completed_.Signal(); | 237 http_post_completed_.Signal(); |
241 } | 238 } |
242 | 239 |
243 } // namespace browser_sync | 240 } // namespace browser_sync |
244 | 241 |
245 #endif // defined(BROWSER_SYNC) | 242 #endif // defined(BROWSER_SYNC) |
OLD | NEW |