| 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 |