| Index: sync/engine/net/server_connection_manager.cc
|
| diff --git a/sync/engine/net/server_connection_manager.cc b/sync/engine/net/server_connection_manager.cc
|
| deleted file mode 100644
|
| index b496f5b674bd0a28d1420374f60da77d4bf2faec..0000000000000000000000000000000000000000
|
| --- a/sync/engine/net/server_connection_manager.cc
|
| +++ /dev/null
|
| @@ -1,337 +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 "sync/engine/net/server_connection_manager.h"
|
| -
|
| -#include <errno.h>
|
| -#include <stdint.h>
|
| -
|
| -#include <ostream>
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/metrics/histogram.h"
|
| -#include "build/build_config.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/http/http_status_code.h"
|
| -#include "sync/engine/net/url_translator.h"
|
| -#include "sync/engine/syncer.h"
|
| -#include "sync/internal_api/public/base/cancelation_signal.h"
|
| -#include "sync/protocol/sync.pb.h"
|
| -#include "sync/syncable/directory.h"
|
| -#include "url/gurl.h"
|
| -
|
| -namespace syncer {
|
| -
|
| -using std::ostream;
|
| -using std::string;
|
| -using std::vector;
|
| -
|
| -static const char kSyncServerSyncPath[] = "/command/";
|
| -
|
| -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_t 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_t 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_)
|
| - 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;
|
| -}
|
| -
|
| -ServerConnectionManager::ServerConnectionManager(
|
| - const string& server,
|
| - int port,
|
| - bool use_ssl,
|
| - CancelationSignal* cancelation_signal)
|
| - : sync_server_(server),
|
| - sync_server_port_(port),
|
| - use_ssl_(use_ssl),
|
| - proto_sync_path_(kSyncServerSyncPath),
|
| - server_status_(HttpResponse::NONE),
|
| - terminated_(false),
|
| - active_connection_(NULL),
|
| - cancelation_signal_(cancelation_signal),
|
| - signal_handler_registered_(false) {
|
| - signal_handler_registered_ = cancelation_signal_->TryRegisterHandler(this);
|
| - if (!signal_handler_registered_) {
|
| - // Calling a virtual function from a constructor. We can get away with it
|
| - // here because ServerConnectionManager::OnSignalReceived() is the function
|
| - // we want to call.
|
| - OnSignalReceived();
|
| - }
|
| -}
|
| -
|
| -ServerConnectionManager::~ServerConnectionManager() {
|
| - if (signal_handler_registered_) {
|
| - cancelation_signal_->UnregisterHandler(this);
|
| - }
|
| -}
|
| -
|
| -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;
|
| -}
|
| -
|
| -bool ServerConnectionManager::SetAuthToken(const std::string& auth_token) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - if (previously_invalidated_token != auth_token) {
|
| - auth_token_.assign(auth_token);
|
| - previously_invalidated_token = std::string();
|
| - return true;
|
| - }
|
| -
|
| - // This could happen in case like server outage/bug. E.g. token returned by
|
| - // first request is considered invalid by sync server and because
|
| - // of token server's caching policy, etc, same token is returned on second
|
| - // request. Need to notify sync frontend again to request new token,
|
| - // otherwise backend will stay in SYNC_AUTH_ERROR state while frontend thinks
|
| - // everything is fine and takes no actions.
|
| - SetServerStatus(HttpResponse::SYNC_AUTH_ERROR);
|
| - return false;
|
| -}
|
| -
|
| -void ServerConnectionManager::InvalidateAndClearAuthToken() {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - // Copy over the token to previous invalid token.
|
| - if (!auth_token_.empty()) {
|
| - previously_invalidated_token.assign(auth_token_);
|
| - auth_token_ = std::string();
|
| - }
|
| -}
|
| -
|
| -void ServerConnectionManager::SetServerStatus(
|
| - HttpResponse::ServerConnectionCode server_status) {
|
| - // SYNC_AUTH_ERROR is permanent error. Need to notify observer to take
|
| - // action externally to resolve.
|
| - if (server_status != HttpResponse::SYNC_AUTH_ERROR &&
|
| - server_status_ == server_status) {
|
| - return;
|
| - }
|
| - server_status_ = server_status;
|
| - NotifyStatusChanged();
|
| -}
|
| -
|
| -void ServerConnectionManager::NotifyStatusChanged() {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - FOR_EACH_OBSERVER(ServerConnectionEventListener, listeners_,
|
| - OnServerConnectionEvent(
|
| - ServerConnectionEvent(server_status_)));
|
| -}
|
| -
|
| -bool ServerConnectionManager::PostBufferWithCachedAuth(
|
| - PostBufferParams* params) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - string path =
|
| - MakeSyncServerPath(proto_sync_path(), MakeSyncQueryString(client_id_));
|
| - bool result = PostBufferToPath(params, path, auth_token());
|
| - SetServerStatus(params->response.server_status);
|
| - return result;
|
| -}
|
| -
|
| -bool ServerConnectionManager::PostBufferToPath(PostBufferParams* params,
|
| - const string& path,
|
| - const string& auth_token) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| -
|
| - // TODO(pavely): crbug.com/273096. Check for "credentials_lost" is added as
|
| - // workaround for M29 blocker to avoid sending RPC to sync with known invalid
|
| - // token but instead to trigger refreshing token in ProfileSyncService. Need
|
| - // to clean it.
|
| - if (auth_token.empty() || auth_token == "credentials_lost") {
|
| - params->response.server_status = HttpResponse::SYNC_AUTH_ERROR;
|
| - // Print a log to distinguish this "known failure" from others.
|
| - LOG(WARNING) << "ServerConnectionManager forcing 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;
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -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::OnSignalReceived() {
|
| - 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;
|
| -}
|
| -
|
| -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: "
|
| - << HttpResponse::GetServerConnectionCodeString(hr.server_status);
|
| - return s;
|
| -}
|
| -
|
| -} // namespace syncer
|
|
|