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
3// found in the LICENSE file.
4
5#include "sync/internal_api/syncapi_server_connection_manager.h"
6
7#include "net/base/net_errors.h"
8#include "net/http/http_status_code.h"
9#include "sync/internal_api/public/http_post_provider_factory.h"
10#include "sync/internal_api/public/http_post_provider_interface.h"
11
12namespace syncer {
13
14SyncAPIBridgedConnection::SyncAPIBridgedConnection(
15    ServerConnectionManager* scm,
16    HttpPostProviderFactory* factory)
17    : Connection(scm), factory_(factory) {
18  post_provider_ = factory_->Create();
19}
20
21SyncAPIBridgedConnection::~SyncAPIBridgedConnection() {
22  DCHECK(post_provider_);
23  factory_->Destroy(post_provider_);
24  post_provider_ = NULL;
25}
26
27bool SyncAPIBridgedConnection::Init(const char* path,
28                                    const std::string& auth_token,
29                                    const std::string& payload,
30                                    HttpResponse* response) {
31  std::string sync_server;
32  int sync_server_port = 0;
33  bool use_ssl = false;
34  GetServerParams(&sync_server, &sync_server_port, &use_ssl);
35  std::string connection_url = MakeConnectionURL(sync_server, path, use_ssl);
36
37  HttpPostProviderInterface* http = post_provider_;
38  http->SetURL(connection_url.c_str(), sync_server_port);
39
40  if (!auth_token.empty()) {
41    std::string headers;
42    headers = "Authorization: Bearer " + auth_token;
43    http->SetExtraRequestHeaders(headers.c_str());
44  }
45
46  // Must be octet-stream, or the payload may be parsed for a cookie.
47  http->SetPostPayload("application/octet-stream", payload.length(),
48                       payload.data());
49
50  // Issue the POST, blocking until it finishes.
51  int error_code = 0;
52  int response_code = 0;
53  if (!http->MakeSynchronousPost(&error_code, &response_code)) {
54    DVLOG(1) << "Http POST failed, error returns: " << error_code;
55    response->server_status = HttpResponse::ServerConnectionCodeFromNetError(
56        error_code);
57    return false;
58  }
59
60  // We got a server response, copy over response codes and content.
61  response->response_code = response_code;
62  response->content_length =
63      static_cast<int64>(http->GetResponseContentLength());
64  response->payload_length =
65      static_cast<int64>(http->GetResponseContentLength());
66  if (response->response_code < 400)
67    response->server_status = HttpResponse::SERVER_CONNECTION_OK;
68  else if (response->response_code == net::HTTP_UNAUTHORIZED)
69    response->server_status = HttpResponse::SYNC_AUTH_ERROR;
70  else
71    response->server_status = HttpResponse::SYNC_SERVER_ERROR;
72
73  // Write the content into our buffer.
74  buffer_.assign(http->GetResponseContent(), http->GetResponseContentLength());
75  return true;
76}
77
78void SyncAPIBridgedConnection::Abort() {
79  DCHECK(post_provider_);
80  post_provider_->Abort();
81}
82
83SyncAPIServerConnectionManager::SyncAPIServerConnectionManager(
84    const std::string& server,
85    int port,
86    bool use_ssl,
87    HttpPostProviderFactory* factory,
88    CancelationSignal* cancelation_signal)
89    : ServerConnectionManager(server,
90                              port,
91                              use_ssl,
92                              cancelation_signal),
93      post_provider_factory_(factory) {
94  DCHECK(post_provider_factory_.get());
95}
96
97SyncAPIServerConnectionManager::~SyncAPIServerConnectionManager() {}
98
99ServerConnectionManager::Connection*
100SyncAPIServerConnectionManager::MakeConnection() {
101  return new SyncAPIBridgedConnection(this, post_provider_factory_.get());
102}
103
104}  // namespace syncer
105