| OLD | NEW |
| 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 "sync/engine/net/server_connection_manager.h" | 5 #include "components/sync/engine_impl/net/server_connection_manager.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <ostream> | 10 #include <ostream> |
| 11 #include <string> | 11 #include <string> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
| 15 #include "build/build_config.h" | 15 #include "build/build_config.h" |
| 16 #include "components/sync/base/cancelation_signal.h" |
| 17 #include "components/sync/engine_impl/net/url_translator.h" |
| 18 #include "components/sync/engine_impl/syncer.h" |
| 19 #include "components/sync/protocol/sync.pb.h" |
| 20 #include "components/sync/syncable/directory.h" |
| 16 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
| 17 #include "net/http/http_status_code.h" | 22 #include "net/http/http_status_code.h" |
| 18 #include "sync/engine/net/url_translator.h" | |
| 19 #include "sync/engine/syncer.h" | |
| 20 #include "sync/internal_api/public/base/cancelation_signal.h" | |
| 21 #include "sync/protocol/sync.pb.h" | |
| 22 #include "sync/syncable/directory.h" | |
| 23 #include "url/gurl.h" | 23 #include "url/gurl.h" |
| 24 | 24 |
| 25 namespace syncer { | 25 namespace syncer { |
| 26 | 26 |
| 27 using std::ostream; | 27 using std::ostream; |
| 28 using std::string; | 28 using std::string; |
| 29 using std::vector; | 29 using std::vector; |
| 30 | 30 |
| 31 static const char kSyncServerSyncPath[] = "/command/"; | 31 static const char kSyncServerSyncPath[] = "/command/"; |
| 32 | 32 |
| 33 HttpResponse::HttpResponse() | 33 HttpResponse::HttpResponse() |
| 34 : response_code(kUnsetResponseCode), | 34 : response_code(kUnsetResponseCode), |
| 35 content_length(kUnsetContentLength), | 35 content_length(kUnsetContentLength), |
| 36 payload_length(kUnsetPayloadLength), | 36 payload_length(kUnsetPayloadLength), |
| 37 server_status(NONE) {} | 37 server_status(NONE) {} |
| 38 | 38 |
| 39 #define ENUM_CASE(x) case x: return #x; break | 39 #define ENUM_CASE(x) \ |
| 40 case x: \ |
| 41 return #x; \ |
| 42 break |
| 40 | 43 |
| 41 const char* HttpResponse::GetServerConnectionCodeString( | 44 const char* HttpResponse::GetServerConnectionCodeString( |
| 42 ServerConnectionCode code) { | 45 ServerConnectionCode code) { |
| 43 switch (code) { | 46 switch (code) { |
| 44 ENUM_CASE(NONE); | 47 ENUM_CASE(NONE); |
| 45 ENUM_CASE(CONNECTION_UNAVAILABLE); | 48 ENUM_CASE(CONNECTION_UNAVAILABLE); |
| 46 ENUM_CASE(IO_ERROR); | 49 ENUM_CASE(IO_ERROR); |
| 47 ENUM_CASE(SYNC_SERVER_ERROR); | 50 ENUM_CASE(SYNC_SERVER_ERROR); |
| 48 ENUM_CASE(SYNC_AUTH_ERROR); | 51 ENUM_CASE(SYNC_AUTH_ERROR); |
| 49 ENUM_CASE(SERVER_CONNECTION_OK); | 52 ENUM_CASE(SERVER_CONNECTION_OK); |
| 50 ENUM_CASE(RETRY); | 53 ENUM_CASE(RETRY); |
| 51 } | 54 } |
| 52 NOTREACHED(); | 55 NOTREACHED(); |
| 53 return ""; | 56 return ""; |
| 54 } | 57 } |
| 55 | 58 |
| 56 #undef ENUM_CASE | 59 #undef ENUM_CASE |
| 57 | 60 |
| 58 ServerConnectionManager::Connection::Connection( | 61 ServerConnectionManager::Connection::Connection(ServerConnectionManager* scm) |
| 59 ServerConnectionManager* scm) : scm_(scm) { | 62 : scm_(scm) {} |
| 60 } | |
| 61 | 63 |
| 62 ServerConnectionManager::Connection::~Connection() { | 64 ServerConnectionManager::Connection::~Connection() {} |
| 63 } | |
| 64 | 65 |
| 65 bool ServerConnectionManager::Connection::ReadBufferResponse( | 66 bool ServerConnectionManager::Connection::ReadBufferResponse( |
| 66 string* buffer_out, | 67 string* buffer_out, |
| 67 HttpResponse* response, | 68 HttpResponse* response, |
| 68 bool require_response) { | 69 bool require_response) { |
| 69 if (net::HTTP_OK != response->response_code) { | 70 if (net::HTTP_OK != response->response_code) { |
| 70 response->server_status = HttpResponse::SYNC_SERVER_ERROR; | 71 response->server_status = HttpResponse::SYNC_SERVER_ERROR; |
| 71 return false; | 72 return false; |
| 72 } | 73 } |
| 73 | 74 |
| 74 if (require_response && (1 > response->content_length)) | 75 if (require_response && (1 > response->content_length)) |
| 75 return false; | 76 return false; |
| 76 | 77 |
| 77 const int64_t bytes_read = | 78 const int64_t bytes_read = |
| 78 ReadResponse(buffer_out, static_cast<int>(response->content_length)); | 79 ReadResponse(buffer_out, static_cast<int>(response->content_length)); |
| 79 if (bytes_read != response->content_length) { | 80 if (bytes_read != response->content_length) { |
| 80 response->server_status = HttpResponse::IO_ERROR; | 81 response->server_status = HttpResponse::IO_ERROR; |
| 81 return false; | 82 return false; |
| 82 } | 83 } |
| 83 return true; | 84 return true; |
| 84 } | 85 } |
| 85 | 86 |
| 86 bool ServerConnectionManager::Connection::ReadDownloadResponse( | 87 bool ServerConnectionManager::Connection::ReadDownloadResponse( |
| 87 HttpResponse* response, | 88 HttpResponse* response, |
| 88 string* buffer_out) { | 89 string* buffer_out) { |
| 89 const int64_t bytes_read = | 90 const int64_t bytes_read = |
| 90 ReadResponse(buffer_out, static_cast<int>(response->content_length)); | 91 ReadResponse(buffer_out, static_cast<int>(response->content_length)); |
| 91 | 92 |
| 92 if (bytes_read != response->content_length) { | 93 if (bytes_read != response->content_length) { |
| 93 LOG(ERROR) << "Mismatched content lengths, server claimed " << | 94 LOG(ERROR) << "Mismatched content lengths, server claimed " |
| 94 response->content_length << ", but sent " << bytes_read; | 95 << response->content_length << ", but sent " << bytes_read; |
| 95 response->server_status = HttpResponse::IO_ERROR; | 96 response->server_status = HttpResponse::IO_ERROR; |
| 96 return false; | 97 return false; |
| 97 } | 98 } |
| 98 return true; | 99 return true; |
| 99 } | 100 } |
| 100 | 101 |
| 101 ServerConnectionManager::ScopedConnectionHelper::ScopedConnectionHelper( | 102 ServerConnectionManager::ScopedConnectionHelper::ScopedConnectionHelper( |
| 102 ServerConnectionManager* manager, Connection* connection) | 103 ServerConnectionManager* manager, |
| 104 Connection* connection) |
| 103 : manager_(manager), connection_(connection) {} | 105 : manager_(manager), connection_(connection) {} |
| 104 | 106 |
| 105 ServerConnectionManager::ScopedConnectionHelper::~ScopedConnectionHelper() { | 107 ServerConnectionManager::ScopedConnectionHelper::~ScopedConnectionHelper() { |
| 106 if (connection_) | 108 if (connection_) |
| 107 manager_->OnConnectionDestroyed(connection_.get()); | 109 manager_->OnConnectionDestroyed(connection_.get()); |
| 108 connection_.reset(); | 110 connection_.reset(); |
| 109 } | 111 } |
| 110 | 112 |
| 111 ServerConnectionManager::Connection* | 113 ServerConnectionManager::Connection* |
| 112 ServerConnectionManager::ScopedConnectionHelper::get() { | 114 ServerConnectionManager::ScopedConnectionHelper::get() { |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 if (server_status != HttpResponse::SYNC_AUTH_ERROR && | 235 if (server_status != HttpResponse::SYNC_AUTH_ERROR && |
| 234 server_status_ == server_status) { | 236 server_status_ == server_status) { |
| 235 return; | 237 return; |
| 236 } | 238 } |
| 237 server_status_ = server_status; | 239 server_status_ = server_status; |
| 238 NotifyStatusChanged(); | 240 NotifyStatusChanged(); |
| 239 } | 241 } |
| 240 | 242 |
| 241 void ServerConnectionManager::NotifyStatusChanged() { | 243 void ServerConnectionManager::NotifyStatusChanged() { |
| 242 DCHECK(thread_checker_.CalledOnValidThread()); | 244 DCHECK(thread_checker_.CalledOnValidThread()); |
| 243 FOR_EACH_OBSERVER(ServerConnectionEventListener, listeners_, | 245 FOR_EACH_OBSERVER( |
| 244 OnServerConnectionEvent( | 246 ServerConnectionEventListener, listeners_, |
| 245 ServerConnectionEvent(server_status_))); | 247 OnServerConnectionEvent(ServerConnectionEvent(server_status_))); |
| 246 } | 248 } |
| 247 | 249 |
| 248 bool ServerConnectionManager::PostBufferWithCachedAuth( | 250 bool ServerConnectionManager::PostBufferWithCachedAuth( |
| 249 PostBufferParams* params) { | 251 PostBufferParams* params) { |
| 250 DCHECK(thread_checker_.CalledOnValidThread()); | 252 DCHECK(thread_checker_.CalledOnValidThread()); |
| 251 string path = | 253 string path = |
| 252 MakeSyncServerPath(proto_sync_path(), MakeSyncQueryString(client_id_)); | 254 MakeSyncServerPath(proto_sync_path(), MakeSyncQueryString(client_id_)); |
| 253 bool result = PostBufferToPath(params, path, auth_token()); | 255 bool result = PostBufferToPath(params, path, auth_token()); |
| 254 SetServerStatus(params->response.server_status); | 256 SetServerStatus(params->response.server_status); |
| 255 return result; | 257 return result; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 274 // When our connection object falls out of scope, it clears itself from | 276 // When our connection object falls out of scope, it clears itself from |
| 275 // active_connection_. | 277 // active_connection_. |
| 276 ScopedConnectionHelper post(this, MakeActiveConnection()); | 278 ScopedConnectionHelper post(this, MakeActiveConnection()); |
| 277 if (!post.get()) { | 279 if (!post.get()) { |
| 278 params->response.server_status = HttpResponse::CONNECTION_UNAVAILABLE; | 280 params->response.server_status = HttpResponse::CONNECTION_UNAVAILABLE; |
| 279 return false; | 281 return false; |
| 280 } | 282 } |
| 281 | 283 |
| 282 // Note that |post| may be aborted by now, which will just cause Init to fail | 284 // Note that |post| may be aborted by now, which will just cause Init to fail |
| 283 // with CONNECTION_UNAVAILABLE. | 285 // with CONNECTION_UNAVAILABLE. |
| 284 bool ok = post.get()->Init( | 286 bool ok = post.get()->Init(path.c_str(), auth_token, params->buffer_in, |
| 285 path.c_str(), auth_token, params->buffer_in, ¶ms->response); | 287 ¶ms->response); |
| 286 | 288 |
| 287 if (params->response.server_status == HttpResponse::SYNC_AUTH_ERROR) { | 289 if (params->response.server_status == HttpResponse::SYNC_AUTH_ERROR) { |
| 288 InvalidateAndClearAuthToken(); | 290 InvalidateAndClearAuthToken(); |
| 289 } | 291 } |
| 290 | 292 |
| 291 if (!ok || net::HTTP_OK != params->response.response_code) | 293 if (!ok || net::HTTP_OK != params->response.response_code) |
| 292 return false; | 294 return false; |
| 293 | 295 |
| 294 if (post.get()->ReadBufferResponse( | 296 if (post.get()->ReadBufferResponse(¶ms->buffer_out, ¶ms->response, |
| 295 ¶ms->buffer_out, ¶ms->response, true)) { | 297 true)) { |
| 296 params->response.server_status = HttpResponse::SERVER_CONNECTION_OK; | 298 params->response.server_status = HttpResponse::SERVER_CONNECTION_OK; |
| 297 return true; | 299 return true; |
| 298 } | 300 } |
| 299 return false; | 301 return false; |
| 300 } | 302 } |
| 301 | 303 |
| 302 void ServerConnectionManager::AddListener( | 304 void ServerConnectionManager::AddListener( |
| 303 ServerConnectionEventListener* listener) { | 305 ServerConnectionEventListener* listener) { |
| 304 DCHECK(thread_checker_.CalledOnValidThread()); | 306 DCHECK(thread_checker_.CalledOnValidThread()); |
| 305 listeners_.AddObserver(listener); | 307 listeners_.AddObserver(listener); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 319 base::AutoLock lock(terminate_connection_lock_); | 321 base::AutoLock lock(terminate_connection_lock_); |
| 320 terminated_ = true; | 322 terminated_ = true; |
| 321 if (active_connection_) | 323 if (active_connection_) |
| 322 active_connection_->Abort(); | 324 active_connection_->Abort(); |
| 323 | 325 |
| 324 // Sever our ties to this connection object. Note that it still may exist, | 326 // Sever our ties to this connection object. Note that it still may exist, |
| 325 // since we don't own it, but it has been neutered. | 327 // since we don't own it, but it has been neutered. |
| 326 active_connection_ = NULL; | 328 active_connection_ = NULL; |
| 327 } | 329 } |
| 328 | 330 |
| 329 std::ostream& operator << (std::ostream& s, const struct HttpResponse& hr) { | 331 std::ostream& operator<<(std::ostream& s, const struct HttpResponse& hr) { |
| 330 s << " Response Code (bogus on error): " << hr.response_code; | 332 s << " Response Code (bogus on error): " << hr.response_code; |
| 331 s << " Content-Length (bogus on error): " << hr.content_length; | 333 s << " Content-Length (bogus on error): " << hr.content_length; |
| 332 s << " Server Status: " | 334 s << " Server Status: " |
| 333 << HttpResponse::GetServerConnectionCodeString(hr.server_status); | 335 << HttpResponse::GetServerConnectionCodeString(hr.server_status); |
| 334 return s; | 336 return s; |
| 335 } | 337 } |
| 336 | 338 |
| 337 } // namespace syncer | 339 } // namespace syncer |
| OLD | NEW |