1// Copyright (c) 2011 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 "chrome/browser/sync/engine/net/syncapi_server_connection_manager.h"
6
7#include "chrome/browser/sync/engine/http_post_provider_factory.h"
8#include "chrome/browser/sync/engine/http_post_provider_interface.h"
9#include "chrome/browser/sync/engine/syncapi.h"
10#include "chrome/common/net/http_return.h"
11
12using browser_sync::HttpResponse;
13
14namespace sync_api {
15
16SyncAPIBridgedPost::SyncAPIBridgedPost(
17    browser_sync::ServerConnectionManager* scm,
18    HttpPostProviderFactory* factory)
19    : Post(scm), factory_(factory) {
20}
21
22SyncAPIBridgedPost::~SyncAPIBridgedPost() {}
23
24bool SyncAPIBridgedPost::Init(const char* path,
25                              const std::string& auth_token,
26                              const std::string& payload,
27                              HttpResponse* response) {
28  std::string sync_server;
29  int sync_server_port = 0;
30  bool use_ssl = false;
31  GetServerParams(&sync_server, &sync_server_port, &use_ssl);
32  std::string connection_url = MakeConnectionURL(sync_server, path, use_ssl);
33
34  HttpPostProviderInterface* http = factory_->Create();
35  http->SetUserAgent(scm_->user_agent().c_str());
36  http->SetURL(connection_url.c_str(), sync_server_port);
37
38  if (!auth_token.empty()) {
39    std::string headers = "Authorization: GoogleLogin auth=" + auth_token;
40    http->SetExtraRequestHeaders(headers.c_str());
41  }
42
43  // Must be octet-stream, or the payload may be parsed for a cookie.
44  http->SetPostPayload("application/octet-stream", payload.length(),
45                       payload.data());
46
47  // Issue the POST, blocking until it finishes.
48  int os_error_code = 0;
49  int response_code = 0;
50  if (!http->MakeSynchronousPost(&os_error_code, &response_code)) {
51    VLOG(1) << "Http POST failed, error returns: " << os_error_code;
52    response->server_status = HttpResponse::IO_ERROR;
53    factory_->Destroy(http);
54    return false;
55  }
56
57  // We got a server response, copy over response codes and content.
58  response->response_code = response_code;
59  response->content_length =
60      static_cast<int64>(http->GetResponseContentLength());
61  response->payload_length =
62      static_cast<int64>(http->GetResponseContentLength());
63  if (response->response_code < 400)
64    response->server_status = HttpResponse::SERVER_CONNECTION_OK;
65  else if (response->response_code == RC_UNAUTHORIZED)
66    response->server_status = HttpResponse::SYNC_AUTH_ERROR;
67  else
68    response->server_status = HttpResponse::SYNC_SERVER_ERROR;
69
70  response->update_client_auth_header =
71      http->GetResponseHeaderValue("Update-Client-Auth");
72
73  // Write the content into our buffer.
74  buffer_.assign(http->GetResponseContent(), http->GetResponseContentLength());
75
76  // We're done with the HttpPostProvider.
77  factory_->Destroy(http);
78  return true;
79}
80
81SyncAPIServerConnectionManager::SyncAPIServerConnectionManager(
82    const std::string& server,
83    int port,
84    bool use_ssl,
85    const std::string& client_version,
86    HttpPostProviderFactory* factory)
87    : ServerConnectionManager(server, port, use_ssl, client_version),
88      post_provider_factory_(factory) {
89  DCHECK(post_provider_factory_.get());
90}
91
92SyncAPIServerConnectionManager::~SyncAPIServerConnectionManager() {}
93
94browser_sync::ServerConnectionManager::Post*
95SyncAPIServerConnectionManager::MakePost() {
96  return new SyncAPIBridgedPost(this, post_provider_factory_.get());
97}
98
99}  // namespace sync_api
100