Index: chrome/browser/sync/engine/net/server_connection_manager.cc |
diff --git a/chrome/browser/sync/engine/net/server_connection_manager.cc b/chrome/browser/sync/engine/net/server_connection_manager.cc |
deleted file mode 100644 |
index 2d531472543e8543d11f56d9e67f8ee4de707db2..0000000000000000000000000000000000000000 |
--- a/chrome/browser/sync/engine/net/server_connection_manager.cc |
+++ /dev/null |
@@ -1,414 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/sync/engine/net/server_connection_manager.h" |
- |
-#include <errno.h> |
- |
-#include <ostream> |
-#include <string> |
-#include <vector> |
- |
-#include "base/command_line.h" |
-#include "build/build_config.h" |
-#include "chrome/browser/sync/engine/net/url_translator.h" |
-#include "chrome/browser/sync/engine/syncer.h" |
-#include "chrome/browser/sync/engine/syncproto.h" |
-#include "googleurl/src/gurl.h" |
-#include "net/http/http_status_code.h" |
-#include "sync/protocol/sync.pb.h" |
- |
-namespace browser_sync { |
- |
-using std::ostream; |
-using std::string; |
-using std::vector; |
- |
-static const char kSyncServerSyncPath[] = "/command/"; |
- |
-// At the /time/ path of the sync server, we expect to find a very simple |
-// time of day service that we can use to synchronize the local clock with |
-// server time. |
-static const char kSyncServerGetTimePath[] = "/time"; |
- |
-HttpResponse::HttpResponse() |
- : response_code(kUnsetResponseCode), |
- content_length(kUnsetContentLength), |
- payload_length(kUnsetPayloadLength), |
- server_status(NONE) {} |
- |
-#define ENUM_CASE(x) case x: return #x; break |
- |
-const char* HttpResponse::GetServerConnectionCodeString( |
- ServerConnectionCode code) { |
- switch (code) { |
- ENUM_CASE(NONE); |
- ENUM_CASE(CONNECTION_UNAVAILABLE); |
- ENUM_CASE(IO_ERROR); |
- ENUM_CASE(SYNC_SERVER_ERROR); |
- ENUM_CASE(SYNC_AUTH_ERROR); |
- ENUM_CASE(SERVER_CONNECTION_OK); |
- ENUM_CASE(RETRY); |
- } |
- NOTREACHED(); |
- return ""; |
-} |
- |
-#undef ENUM_CASE |
- |
-ServerConnectionManager::Connection::Connection( |
- ServerConnectionManager* scm) : scm_(scm) { |
-} |
- |
-ServerConnectionManager::Connection::~Connection() { |
-} |
- |
-bool ServerConnectionManager::Connection::ReadBufferResponse( |
- string* buffer_out, |
- HttpResponse* response, |
- bool require_response) { |
- if (net::HTTP_OK != response->response_code) { |
- response->server_status = HttpResponse::SYNC_SERVER_ERROR; |
- return false; |
- } |
- |
- if (require_response && (1 > response->content_length)) |
- return false; |
- |
- const int64 bytes_read = ReadResponse(buffer_out, |
- static_cast<int>(response->content_length)); |
- if (bytes_read != response->content_length) { |
- response->server_status = HttpResponse::IO_ERROR; |
- return false; |
- } |
- return true; |
-} |
- |
-bool ServerConnectionManager::Connection::ReadDownloadResponse( |
- HttpResponse* response, |
- string* buffer_out) { |
- const int64 bytes_read = ReadResponse(buffer_out, |
- static_cast<int>(response->content_length)); |
- |
- if (bytes_read != response->content_length) { |
- LOG(ERROR) << "Mismatched content lengths, server claimed " << |
- response->content_length << ", but sent " << bytes_read; |
- response->server_status = HttpResponse::IO_ERROR; |
- return false; |
- } |
- return true; |
-} |
- |
-ServerConnectionManager::ScopedConnectionHelper::ScopedConnectionHelper( |
- ServerConnectionManager* manager, Connection* connection) |
- : manager_(manager), connection_(connection) {} |
- |
-ServerConnectionManager::ScopedConnectionHelper::~ScopedConnectionHelper() { |
- if (connection_.get()) |
- manager_->OnConnectionDestroyed(connection_.get()); |
- connection_.reset(); |
-} |
- |
-ServerConnectionManager::Connection* |
-ServerConnectionManager::ScopedConnectionHelper::get() { |
- return connection_.get(); |
-} |
- |
-namespace { |
- |
-string StripTrailingSlash(const string& s) { |
- int stripped_end_pos = s.size(); |
- if (s.at(stripped_end_pos - 1) == '/') { |
- stripped_end_pos = stripped_end_pos - 1; |
- } |
- |
- return s.substr(0, stripped_end_pos); |
-} |
- |
-} // namespace |
- |
-// TODO(chron): Use a GURL instead of string concatenation. |
-string ServerConnectionManager::Connection::MakeConnectionURL( |
- const string& sync_server, |
- const string& path, |
- bool use_ssl) const { |
- string connection_url = (use_ssl ? "https://" : "http://"); |
- connection_url += sync_server; |
- connection_url = StripTrailingSlash(connection_url); |
- connection_url += path; |
- |
- return connection_url; |
-} |
- |
-int ServerConnectionManager::Connection::ReadResponse(string* out_buffer, |
- int length) { |
- int bytes_read = buffer_.length(); |
- CHECK(length <= bytes_read); |
- out_buffer->assign(buffer_); |
- return bytes_read; |
-} |
- |
-ScopedServerStatusWatcher::ScopedServerStatusWatcher( |
- ServerConnectionManager* conn_mgr, HttpResponse* response) |
- : conn_mgr_(conn_mgr), |
- response_(response), |
- server_reachable_(conn_mgr->server_reachable_) { |
- response->server_status = conn_mgr->server_status_; |
-} |
- |
-ScopedServerStatusWatcher::~ScopedServerStatusWatcher() { |
- if (conn_mgr_->server_status_ != response_->server_status) { |
- conn_mgr_->server_status_ = response_->server_status; |
- conn_mgr_->NotifyStatusChanged(); |
- return; |
- } |
- // Notify if we've gone on or offline. |
- if (server_reachable_ != conn_mgr_->server_reachable_) |
- conn_mgr_->NotifyStatusChanged(); |
-} |
- |
-ServerConnectionManager::ServerConnectionManager( |
- const string& server, |
- int port, |
- bool use_ssl, |
- const string& user_agent) |
- : sync_server_(server), |
- sync_server_port_(port), |
- user_agent_(user_agent), |
- use_ssl_(use_ssl), |
- proto_sync_path_(kSyncServerSyncPath), |
- get_time_path_(kSyncServerGetTimePath), |
- server_status_(HttpResponse::NONE), |
- server_reachable_(false), |
- terminated_(false), |
- active_connection_(NULL) { |
-} |
- |
-ServerConnectionManager::~ServerConnectionManager() { |
-} |
- |
-ServerConnectionManager::Connection* |
-ServerConnectionManager::MakeActiveConnection() { |
- base::AutoLock lock(terminate_connection_lock_); |
- DCHECK(!active_connection_); |
- if (terminated_) |
- return NULL; |
- |
- active_connection_ = MakeConnection(); |
- return active_connection_; |
-} |
- |
-void ServerConnectionManager::OnConnectionDestroyed(Connection* connection) { |
- DCHECK(connection); |
- base::AutoLock lock(terminate_connection_lock_); |
- // |active_connection_| can be NULL already if it was aborted. Also, |
- // it can legitimately be a different Connection object if a new Connection |
- // was created after a previous one was Aborted and destroyed. |
- if (active_connection_ != connection) |
- return; |
- |
- active_connection_ = NULL; |
-} |
- |
-void ServerConnectionManager::NotifyStatusChanged() { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- FOR_EACH_OBSERVER(ServerConnectionEventListener, listeners_, |
- OnServerConnectionEvent( |
- ServerConnectionEvent(server_status_, server_reachable_))); |
-} |
- |
-bool ServerConnectionManager::PostBufferWithCachedAuth( |
- PostBufferParams* params, ScopedServerStatusWatcher* watcher) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- string path = |
- MakeSyncServerPath(proto_sync_path(), MakeSyncQueryString(client_id_)); |
- return PostBufferToPath(params, path, auth_token(), watcher); |
-} |
- |
-bool ServerConnectionManager::PostBufferToPath(PostBufferParams* params, |
- const string& path, const string& auth_token, |
- ScopedServerStatusWatcher* watcher) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(watcher != NULL); |
- |
- if (auth_token.empty()) { |
- params->response.server_status = HttpResponse::SYNC_AUTH_ERROR; |
- return false; |
- } |
- |
- // When our connection object falls out of scope, it clears itself from |
- // active_connection_. |
- ScopedConnectionHelper post(this, MakeActiveConnection()); |
- if (!post.get()) { |
- params->response.server_status = HttpResponse::CONNECTION_UNAVAILABLE; |
- return false; |
- } |
- |
- // Note that |post| may be aborted by now, which will just cause Init to fail |
- // with CONNECTION_UNAVAILABLE. |
- bool ok = post.get()->Init( |
- path.c_str(), auth_token, params->buffer_in, ¶ms->response); |
- |
- if (params->response.server_status == HttpResponse::SYNC_AUTH_ERROR) |
- InvalidateAndClearAuthToken(); |
- |
- if (!ok || net::HTTP_OK != params->response.response_code) |
- return false; |
- |
- if (post.get()->ReadBufferResponse( |
- ¶ms->buffer_out, ¶ms->response, true)) { |
- params->response.server_status = HttpResponse::SERVER_CONNECTION_OK; |
- server_reachable_ = true; |
- return true; |
- } |
- return false; |
-} |
- |
-bool ServerConnectionManager::CheckTime(int32* out_time) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- // Verify that the server really is reachable by checking the time. We need |
- // to do this because of wifi interstitials that intercept messages from the |
- // client and return HTTP OK instead of a redirect. |
- HttpResponse response; |
- ScopedServerStatusWatcher watcher(this, &response); |
- string post_body = "command=get_time"; |
- |
- for (int i = 0 ; i < 3; i++) { |
- ScopedConnectionHelper post(this, MakeActiveConnection()); |
- if (!post.get()) |
- break; |
- |
- // Note that the server's get_time path doesn't require authentication. |
- string get_time_path = |
- MakeSyncServerPath(kSyncServerGetTimePath, post_body); |
- DVLOG(1) << "Requesting get_time from:" << get_time_path; |
- |
- string blank_post_body; |
- bool ok = post.get()->Init(get_time_path.c_str(), blank_post_body, |
- blank_post_body, &response); |
- if (!ok) { |
- DVLOG(1) << "Unable to check the time"; |
- continue; |
- } |
- string time_response; |
- time_response.resize( |
- static_cast<string::size_type>(response.content_length)); |
- ok = post.get()->ReadDownloadResponse(&response, &time_response); |
- if (!ok || string::npos != |
- time_response.find_first_not_of("0123456789")) { |
- LOG(ERROR) << "unable to read a non-numeric response from get_time:" |
- << time_response; |
- continue; |
- } |
- *out_time = atoi(time_response.c_str()); |
- DVLOG(1) << "Server was reachable."; |
- return true; |
- } |
- return false; |
-} |
- |
-bool ServerConnectionManager::IsServerReachable() { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- int32 time; |
- return CheckTime(&time); |
-} |
- |
-bool ServerConnectionManager::IsUserAuthenticated() { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- return IsGoodReplyFromServer(server_status_); |
-} |
- |
-bool ServerConnectionManager::CheckServerReachable() { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- const bool server_is_reachable = IsServerReachable(); |
- if (server_reachable_ != server_is_reachable) { |
- server_reachable_ = server_is_reachable; |
- NotifyStatusChanged(); |
- } |
- return server_is_reachable; |
-} |
- |
-void ServerConnectionManager::SetServerParameters(const string& server_url, |
- int port, |
- bool use_ssl) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- sync_server_ = server_url; |
- sync_server_port_ = port; |
- use_ssl_ = use_ssl; |
-} |
- |
-// Returns the current server parameters in server_url and port. |
-void ServerConnectionManager::GetServerParameters(string* server_url, |
- int* port, |
- bool* use_ssl) const { |
- if (server_url != NULL) |
- *server_url = sync_server_; |
- if (port != NULL) |
- *port = sync_server_port_; |
- if (use_ssl != NULL) |
- *use_ssl = use_ssl_; |
-} |
- |
-std::string ServerConnectionManager::GetServerHost() const { |
- string server_url; |
- int port; |
- bool use_ssl; |
- GetServerParameters(&server_url, &port, &use_ssl); |
- // For unit tests. |
- if (server_url.empty()) |
- return std::string(); |
- // We just want the hostname, so we don't need to switch on use_ssl. |
- server_url = "http://" + server_url; |
- GURL gurl(server_url); |
- DCHECK(gurl.is_valid()) << gurl; |
- return gurl.host(); |
-} |
- |
-void ServerConnectionManager::AddListener( |
- ServerConnectionEventListener* listener) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- listeners_.AddObserver(listener); |
-} |
- |
-void ServerConnectionManager::RemoveListener( |
- ServerConnectionEventListener* listener) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- listeners_.RemoveObserver(listener); |
-} |
- |
-ServerConnectionManager::Connection* ServerConnectionManager::MakeConnection() |
-{ |
- return NULL; // For testing. |
-} |
- |
-void ServerConnectionManager::TerminateAllIO() { |
- base::AutoLock lock(terminate_connection_lock_); |
- terminated_ = true; |
- if (active_connection_) |
- active_connection_->Abort(); |
- |
- // Sever our ties to this connection object. Note that it still may exist, |
- // since we don't own it, but it has been neutered. |
- active_connection_ = NULL; |
-} |
- |
-bool FillMessageWithShareDetails(sync_pb::ClientToServerMessage* csm, |
- syncable::Directory* directory, |
- const std::string& share) { |
- string birthday = directory->store_birthday(); |
- if (!birthday.empty()) |
- csm->set_store_birthday(birthday); |
- csm->set_share(share); |
- return true; |
-} |
- |
-std::ostream& operator << (std::ostream& s, const struct HttpResponse& hr) { |
- s << " Response Code (bogus on error): " << hr.response_code; |
- s << " Content-Length (bogus on error): " << hr.content_length; |
- s << " Server Status: " << hr.server_status; |
- return s; |
-} |
- |
-} // namespace browser_sync |