| 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 "net/base/cookie_monster.h" | 13 #include "net/base/cookie_monster.h" |
| 14 #include "net/base/load_flags.h" | 14 #include "net/base/load_flags.h" |
| 15 #include "net/http/http_cache.h" | 15 #include "net/http/http_cache.h" |
| 16 #include "net/http/http_network_layer.h" | 16 #include "net/http/http_network_layer.h" |
| 17 #include "net/proxy/proxy_service.h" | 17 #include "net/proxy/proxy_service.h" |
| 18 #include "net/url_request/url_request_context.h" | 18 #include "net/url_request/url_request_context.h" |
| 19 #include "net/url_request/url_request_status.h" | 19 #include "net/url_request/url_request_status.h" |
| 20 #include "webkit/glue/webkit_glue.h" | 20 #include "webkit/glue/webkit_glue.h" |
| 21 | 21 |
| 22 namespace browser_sync { | 22 namespace browser_sync { |
| 23 | 23 |
| 24 HttpBridge::RequestContextGetter::RequestContextGetter( |
| 25 URLRequestContextGetter* baseline_context_getter) |
| 26 : baseline_context_getter_(baseline_context_getter) { |
| 27 } |
| 28 |
| 29 URLRequestContext* HttpBridge::RequestContextGetter::GetURLRequestContext() { |
| 30 // Lazily create the context. |
| 31 if (!context_) { |
| 32 URLRequestContext* baseline_context = |
| 33 baseline_context_getter_->GetURLRequestContext(); |
| 34 context_ = new RequestContext(baseline_context); |
| 35 baseline_context_getter_ = NULL; |
| 36 } |
| 37 |
| 38 // Apply the user agent which was set earlier. |
| 39 if (is_user_agent_set()) |
| 40 context_->set_user_agent(user_agent_); |
| 41 |
| 42 return context_; |
| 43 } |
| 44 |
| 24 HttpBridgeFactory::HttpBridgeFactory( | 45 HttpBridgeFactory::HttpBridgeFactory( |
| 25 URLRequestContext* baseline_context) { | 46 URLRequestContextGetter* baseline_context_getter) { |
| 26 DCHECK(baseline_context != NULL); | 47 DCHECK(baseline_context_getter != NULL); |
| 27 request_context_ = new HttpBridge::RequestContext(baseline_context); | 48 request_context_getter_ = |
| 28 request_context_->AddRef(); | 49 new HttpBridge::RequestContextGetter(baseline_context_getter); |
| 50 request_context_getter_->AddRef(); |
| 29 } | 51 } |
| 30 | 52 |
| 31 HttpBridgeFactory::~HttpBridgeFactory() { | 53 HttpBridgeFactory::~HttpBridgeFactory() { |
| 32 if (request_context_) { | 54 if (request_context_getter_) { |
| 33 // Clean up request context on IO thread. | 55 // Clean up request context getter on IO thread. |
| 34 ChromeThread::GetMessageLoop(ChromeThread::IO)->ReleaseSoon(FROM_HERE, | 56 ChromeThread::GetMessageLoop(ChromeThread::IO)->ReleaseSoon(FROM_HERE, |
| 35 request_context_); | 57 request_context_getter_); |
| 36 request_context_ = NULL; | 58 request_context_getter_ = NULL; |
| 37 } | 59 } |
| 38 } | 60 } |
| 39 | 61 |
| 40 sync_api::HttpPostProviderInterface* HttpBridgeFactory::Create() { | 62 sync_api::HttpPostProviderInterface* HttpBridgeFactory::Create() { |
| 41 HttpBridge* http = new HttpBridge(request_context_, | 63 HttpBridge* http = new HttpBridge(request_context_getter_, |
| 42 ChromeThread::GetMessageLoop(ChromeThread::IO)); | 64 ChromeThread::GetMessageLoop(ChromeThread::IO)); |
| 43 http->AddRef(); | 65 http->AddRef(); |
| 44 return http; | 66 return http; |
| 45 } | 67 } |
| 46 | 68 |
| 47 void HttpBridgeFactory::Destroy(sync_api::HttpPostProviderInterface* http) { | 69 void HttpBridgeFactory::Destroy(sync_api::HttpPostProviderInterface* http) { |
| 48 static_cast<HttpBridge*>(http)->Release(); | 70 static_cast<HttpBridge*>(http)->Release(); |
| 49 } | 71 } |
| 50 | 72 |
| 51 HttpBridge::RequestContext::RequestContext(URLRequestContext* baseline_context) | 73 HttpBridge::RequestContext::RequestContext(URLRequestContext* baseline_context) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 80 | 102 |
| 81 // We default to the browser's user agent. This can (and should) be overridden | 103 // We default to the browser's user agent. This can (and should) be overridden |
| 82 // with set_user_agent. | 104 // with set_user_agent. |
| 83 user_agent_ = webkit_glue::GetUserAgent(GURL()); | 105 user_agent_ = webkit_glue::GetUserAgent(GURL()); |
| 84 } | 106 } |
| 85 | 107 |
| 86 HttpBridge::RequestContext::~RequestContext() { | 108 HttpBridge::RequestContext::~RequestContext() { |
| 87 delete http_transaction_factory_; | 109 delete http_transaction_factory_; |
| 88 } | 110 } |
| 89 | 111 |
| 90 HttpBridge::HttpBridge(HttpBridge::RequestContext* context, | 112 HttpBridge::HttpBridge(HttpBridge::RequestContextGetter* context_getter, |
| 91 MessageLoop* io_loop) | 113 MessageLoop* io_loop) |
| 92 : context_for_request_(context), | 114 : context_getter_for_request_(context_getter), |
| 93 url_poster_(NULL), | 115 url_poster_(NULL), |
| 94 created_on_loop_(MessageLoop::current()), | 116 created_on_loop_(MessageLoop::current()), |
| 95 io_loop_(io_loop), | 117 io_loop_(io_loop), |
| 96 request_completed_(false), | 118 request_completed_(false), |
| 97 request_succeeded_(false), | 119 request_succeeded_(false), |
| 98 http_response_code_(-1), | 120 http_response_code_(-1), |
| 99 http_post_completed_(false, false), | 121 http_post_completed_(false, false), |
| 100 use_io_loop_for_testing_(false) { | 122 use_io_loop_for_testing_(false) { |
| 101 context_for_request_->AddRef(); | 123 context_getter_for_request_->AddRef(); |
| 102 } | 124 } |
| 103 | 125 |
| 104 HttpBridge::~HttpBridge() { | 126 HttpBridge::~HttpBridge() { |
| 105 io_loop_->ReleaseSoon(FROM_HERE, context_for_request_); | 127 io_loop_->ReleaseSoon(FROM_HERE, context_getter_for_request_); |
| 106 } | 128 } |
| 107 | 129 |
| 108 void HttpBridge::SetUserAgent(const char* user_agent) { | 130 void HttpBridge::SetUserAgent(const char* user_agent) { |
| 109 DCHECK_EQ(MessageLoop::current(), created_on_loop_); | 131 DCHECK_EQ(MessageLoop::current(), created_on_loop_); |
| 110 DCHECK(!request_completed_); | 132 DCHECK(!request_completed_); |
| 111 context_for_request_->set_user_agent(user_agent); | 133 context_getter_for_request_->set_user_agent(user_agent); |
| 112 } | 134 } |
| 113 | 135 |
| 114 void HttpBridge::SetExtraRequestHeaders(const char * headers) { | 136 void HttpBridge::SetExtraRequestHeaders(const char * headers) { |
| 115 DCHECK(extra_headers_.empty()) | 137 DCHECK(extra_headers_.empty()) |
| 116 << "HttpBridge::SetExtraRequestHeaders called twice."; | 138 << "HttpBridge::SetExtraRequestHeaders called twice."; |
| 117 extra_headers_.assign(headers); | 139 extra_headers_.assign(headers); |
| 118 } | 140 } |
| 119 | 141 |
| 120 void HttpBridge::SetURL(const char* url, int port) { | 142 void HttpBridge::SetURL(const char* url, int port) { |
| 121 DCHECK_EQ(MessageLoop::current(), created_on_loop_); | 143 DCHECK_EQ(MessageLoop::current(), created_on_loop_); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 146 } else { | 168 } else { |
| 147 request_content_.assign(content, content_length); | 169 request_content_.assign(content, content_length); |
| 148 } | 170 } |
| 149 } | 171 } |
| 150 | 172 |
| 151 bool HttpBridge::MakeSynchronousPost(int* os_error_code, int* response_code) { | 173 bool HttpBridge::MakeSynchronousPost(int* os_error_code, int* response_code) { |
| 152 DCHECK_EQ(MessageLoop::current(), created_on_loop_); | 174 DCHECK_EQ(MessageLoop::current(), created_on_loop_); |
| 153 DCHECK(!request_completed_); | 175 DCHECK(!request_completed_); |
| 154 DCHECK(url_for_request_.is_valid()) << "Invalid URL for request"; | 176 DCHECK(url_for_request_.is_valid()) << "Invalid URL for request"; |
| 155 DCHECK(!content_type_.empty()) << "Payload not set"; | 177 DCHECK(!content_type_.empty()) << "Payload not set"; |
| 156 DCHECK(context_for_request_->is_user_agent_set()) << "User agent not set"; | |
| 157 | 178 |
| 158 io_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, | 179 io_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, |
| 159 &HttpBridge::CallMakeAsynchronousPost)); | 180 &HttpBridge::CallMakeAsynchronousPost)); |
| 160 | 181 |
| 161 if (!http_post_completed_.Wait()) // Block until network request completes. | 182 if (!http_post_completed_.Wait()) // Block until network request completes. |
| 162 NOTREACHED(); // See OnURLFetchComplete. | 183 NOTREACHED(); // See OnURLFetchComplete. |
| 163 | 184 |
| 164 DCHECK(request_completed_); | 185 DCHECK(request_completed_); |
| 165 *os_error_code = os_error_code_; | 186 *os_error_code = os_error_code_; |
| 166 *response_code = http_response_code_; | 187 *response_code = http_response_code_; |
| 167 return request_succeeded_; | 188 return request_succeeded_; |
| 168 } | 189 } |
| 169 | 190 |
| 170 void HttpBridge::MakeAsynchronousPost() { | 191 void HttpBridge::MakeAsynchronousPost() { |
| 171 DCHECK_EQ(MessageLoop::current(), io_loop_); | 192 DCHECK_EQ(MessageLoop::current(), io_loop_); |
| 172 DCHECK(!request_completed_); | 193 DCHECK(!request_completed_); |
| 173 | 194 |
| 174 url_poster_ = new URLFetcher(url_for_request_, URLFetcher::POST, this); | 195 url_poster_ = new URLFetcher(url_for_request_, URLFetcher::POST, this); |
| 175 url_poster_->set_request_context(context_for_request_); | 196 url_poster_->set_request_context(context_getter_for_request_); |
| 176 url_poster_->set_upload_data(content_type_, request_content_); | 197 url_poster_->set_upload_data(content_type_, request_content_); |
| 177 url_poster_->set_extra_request_headers(extra_headers_); | 198 url_poster_->set_extra_request_headers(extra_headers_); |
| 178 | 199 |
| 179 if (use_io_loop_for_testing_) | 200 if (use_io_loop_for_testing_) |
| 180 url_poster_->set_io_loop(io_loop_); | 201 url_poster_->set_io_loop(io_loop_); |
| 181 | 202 |
| 182 url_poster_->Start(); | 203 url_poster_->Start(); |
| 183 } | 204 } |
| 184 | 205 |
| 185 int HttpBridge::GetResponseContentLength() const { | 206 int HttpBridge::GetResponseContentLength() const { |
| 186 DCHECK_EQ(MessageLoop::current(), created_on_loop_); | 207 DCHECK_EQ(MessageLoop::current(), created_on_loop_); |
| 187 DCHECK(request_completed_); | 208 DCHECK(request_completed_); |
| 188 return response_content_.size(); | 209 return response_content_.size(); |
| 189 } | 210 } |
| 190 | 211 |
| 191 const char* HttpBridge::GetResponseContent() const { | 212 const char* HttpBridge::GetResponseContent() const { |
| 192 DCHECK_EQ(MessageLoop::current(), created_on_loop_); | 213 DCHECK_EQ(MessageLoop::current(), created_on_loop_); |
| 193 DCHECK(request_completed_); | 214 DCHECK(request_completed_); |
| 194 return response_content_.data(); | 215 return response_content_.data(); |
| 195 } | 216 } |
| 196 | 217 |
| 197 URLRequestContext* HttpBridge::GetRequestContext() const { | |
| 198 return context_for_request_; | |
| 199 } | |
| 200 | |
| 201 void HttpBridge::OnURLFetchComplete(const URLFetcher *source, const GURL &url, | 218 void HttpBridge::OnURLFetchComplete(const URLFetcher *source, const GURL &url, |
| 202 const URLRequestStatus &status, | 219 const URLRequestStatus &status, |
| 203 int response_code, | 220 int response_code, |
| 204 const ResponseCookies &cookies, | 221 const ResponseCookies &cookies, |
| 205 const std::string &data) { | 222 const std::string &data) { |
| 206 DCHECK_EQ(MessageLoop::current(), io_loop_); | 223 DCHECK_EQ(MessageLoop::current(), io_loop_); |
| 207 | 224 |
| 208 request_completed_ = true; | 225 request_completed_ = true; |
| 209 request_succeeded_ = (URLRequestStatus::SUCCESS == status.status()); | 226 request_succeeded_ = (URLRequestStatus::SUCCESS == status.status()); |
| 210 http_response_code_ = response_code; | 227 http_response_code_ = response_code; |
| 211 os_error_code_ = status.os_error(); | 228 os_error_code_ = status.os_error(); |
| 212 | 229 |
| 213 response_content_ = data; | 230 response_content_ = data; |
| 214 | 231 |
| 215 // End of the line for url_poster_. It lives only on the io_loop. | 232 // End of the line for url_poster_. It lives only on the io_loop. |
| 216 // We defer deletion because we're inside a callback from a component of the | 233 // We defer deletion because we're inside a callback from a component of the |
| 217 // URLFetcher, so it seems most natural / "polite" to let the stack unwind. | 234 // URLFetcher, so it seems most natural / "polite" to let the stack unwind. |
| 218 io_loop_->DeleteSoon(FROM_HERE, url_poster_); | 235 io_loop_->DeleteSoon(FROM_HERE, url_poster_); |
| 219 url_poster_ = NULL; | 236 url_poster_ = NULL; |
| 220 | 237 |
| 221 // Wake the blocked syncer thread in MakeSynchronousPost. | 238 // Wake the blocked syncer thread in MakeSynchronousPost. |
| 222 // WARNING: DONT DO ANYTHING AFTER THIS CALL! |this| may be deleted! | 239 // WARNING: DONT DO ANYTHING AFTER THIS CALL! |this| may be deleted! |
| 223 http_post_completed_.Signal(); | 240 http_post_completed_.Signal(); |
| 224 } | 241 } |
| 225 | 242 |
| 226 } // namespace browser_sync | 243 } // namespace browser_sync |
| 227 | 244 |
| 228 #endif // defined(BROWSER_SYNC) | 245 #endif // defined(BROWSER_SYNC) |
| OLD | NEW |