15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/syncapi_server_connection_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_status_code.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/http_post_provider_factory.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/http_post_provider_interface.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncAPIBridgedConnection::SyncAPIBridgedConnection(
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServerConnectionManager* scm,
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpPostProviderFactory* factory)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Connection(scm), factory_(factory) {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  post_provider_ = factory_->Create();
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncAPIBridgedConnection::~SyncAPIBridgedConnection() {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(post_provider_);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  factory_->Destroy(post_provider_);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  post_provider_ = NULL;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncAPIBridgedConnection::Init(const char* path,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const std::string& auth_token,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const std::string& payload,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    HttpResponse* response) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string sync_server;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int sync_server_port = 0;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool use_ssl = false;
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GetServerParams(&sync_server, &sync_server_port, &use_ssl);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string connection_url = MakeConnectionURL(sync_server, path, use_ssl);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpPostProviderInterface* http = post_provider_;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http->SetURL(connection_url.c_str(), sync_server_port);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_token.empty()) {
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::string headers;
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    headers = "Authorization: Bearer " + auth_token;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    http->SetExtraRequestHeaders(headers.c_str());
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Must be octet-stream, or the payload may be parsed for a cookie.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http->SetPostPayload("application/octet-stream", payload.length(),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       payload.data());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the POST, blocking until it finishes.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error_code = 0;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int response_code = 0;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!http->MakeSynchronousPost(&error_code, &response_code)) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Http POST failed, error returns: " << error_code;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response->server_status = HttpResponse::ServerConnectionCodeFromNetError(
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        error_code);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We got a server response, copy over response codes and content.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->response_code = response_code;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->content_length =
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<int64>(http->GetResponseContentLength());
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->payload_length =
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<int64>(http->GetResponseContentLength());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response->response_code < 400)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response->server_status = HttpResponse::SERVER_CONNECTION_OK;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (response->response_code == net::HTTP_UNAUTHORIZED)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response->server_status = HttpResponse::SYNC_AUTH_ERROR;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response->server_status = HttpResponse::SYNC_SERVER_ERROR;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Write the content into our buffer.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_.assign(http->GetResponseContent(), http->GetResponseContentLength());
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncAPIBridgedConnection::Abort() {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(post_provider_);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  post_provider_->Abort();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncAPIServerConnectionManager::SyncAPIServerConnectionManager(
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& server,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int port,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool use_ssl,
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    HttpPostProviderFactory* factory,
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    CancelationSignal* cancelation_signal)
89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    : ServerConnectionManager(server,
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              port,
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              use_ssl,
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                              cancelation_signal),
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      post_provider_factory_(factory) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(post_provider_factory_.get());
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncAPIServerConnectionManager::~SyncAPIServerConnectionManager() {}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServerConnectionManager::Connection*
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncAPIServerConnectionManager::MakeConnection() {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new SyncAPIBridgedConnection(this, post_provider_factory_.get());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace syncer
105