blob: c8695178a50f87d53318431924dba7e1beb32cab [file] [log] [blame]
Vitaly Buka00882b72015-08-06 00:32:11 -07001// Copyright 2015 The Chromium OS 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 "buffet/http_transport_client.h"
6
7#include <base/bind.h>
Alex Vakulenko41705852015-10-13 10:12:06 -07008#include <brillo/errors/error.h>
9#include <brillo/http/http_request.h>
10#include <brillo/http/http_utils.h>
11#include <brillo/streams/memory_stream.h>
Alex Vakulenko297114c2015-10-12 13:45:43 -070012#include <weave/enum_to_string.h>
Vitaly Buka00882b72015-08-06 00:32:11 -070013
Vitaly Buka4f771532015-08-14 14:58:39 -070014#include "buffet/weave_error_conversion.h"
15
Vitaly Buka00882b72015-08-06 00:32:11 -070016namespace buffet {
17
18namespace {
19
Alex Vakulenkoe32375b2015-09-28 08:55:40 -070020using weave::provider::HttpClient;
21
Vitaly Buka00882b72015-08-06 00:32:11 -070022// The number of seconds each HTTP request will be allowed before timing out.
23const int kRequestTimeoutSeconds = 30;
24
Alex Vakulenkoe32375b2015-09-28 08:55:40 -070025class ResponseImpl : public HttpClient::Response {
Vitaly Buka00882b72015-08-06 00:32:11 -070026 public:
27 ~ResponseImpl() override = default;
Alex Vakulenko41705852015-10-13 10:12:06 -070028 explicit ResponseImpl(std::unique_ptr<brillo::http::Response> response)
Vitaly Buka00882b72015-08-06 00:32:11 -070029 : response_{std::move(response)},
30 data_{response_->ExtractDataAsString()} {}
31
Alex Vakulenkoe32375b2015-09-28 08:55:40 -070032 // HttpClient::Response implementation
Vitaly Buka00882b72015-08-06 00:32:11 -070033 int GetStatusCode() const override { return response_->GetStatusCode(); }
34
35 std::string GetContentType() const override {
36 return response_->GetContentType();
37 }
38
Alex Vakulenko297114c2015-10-12 13:45:43 -070039 std::string GetData() const override { return data_; }
Vitaly Buka00882b72015-08-06 00:32:11 -070040
41 private:
Alex Vakulenko41705852015-10-13 10:12:06 -070042 std::unique_ptr<brillo::http::Response> response_;
Vitaly Buka00882b72015-08-06 00:32:11 -070043 std::string data_;
44 DISALLOW_COPY_AND_ASSIGN(ResponseImpl);
45};
46
Alex Vakulenko94f8eba2015-10-14 08:52:45 -070047void OnSuccessCallback(const HttpClient::SendRequestCallback& callback,
Alex Vakulenkoe32375b2015-09-28 08:55:40 -070048 int id,
Alex Vakulenko41705852015-10-13 10:12:06 -070049 std::unique_ptr<brillo::http::Response> response) {
Alex Vakulenko94f8eba2015-10-14 08:52:45 -070050 callback.Run(std::unique_ptr<HttpClient::Response>{new ResponseImpl{
51 std::move(response)}},
52 nullptr);
Vitaly Buka00882b72015-08-06 00:32:11 -070053}
54
Alex Vakulenko94f8eba2015-10-14 08:52:45 -070055void OnErrorCallback(const HttpClient::SendRequestCallback& callback,
Vitaly Buka00882b72015-08-06 00:32:11 -070056 int id,
Alex Vakulenko94f8eba2015-10-14 08:52:45 -070057 const brillo::Error* brillo_error) {
Vitaly Buka4f771532015-08-14 14:58:39 -070058 weave::ErrorPtr error;
Alex Vakulenko94f8eba2015-10-14 08:52:45 -070059 ConvertError(*brillo_error, &error);
60 callback.Run(nullptr, std::move(error));
Vitaly Buka00882b72015-08-06 00:32:11 -070061}
62
63} // anonymous namespace
64
65HttpTransportClient::HttpTransportClient()
Alex Vakulenko41705852015-10-13 10:12:06 -070066 : transport_{brillo::http::Transport::CreateDefault()} {
Vitaly Buka00882b72015-08-06 00:32:11 -070067 transport_->SetDefaultTimeout(
68 base::TimeDelta::FromSeconds(kRequestTimeoutSeconds));
69}
70
71HttpTransportClient::~HttpTransportClient() {}
72
Alex Vakulenko94f8eba2015-10-14 08:52:45 -070073void HttpTransportClient::SendRequest(Method method,
74 const std::string& url,
75 const Headers& headers,
76 const std::string& data,
77 const SendRequestCallback& callback) {
Alex Vakulenko41705852015-10-13 10:12:06 -070078 brillo::http::Request request(url, weave::EnumToString(method), transport_);
Vitaly Buka86852562015-08-06 11:06:25 -070079 request.AddHeaders(headers);
80 if (!data.empty()) {
Alex Vakulenko41705852015-10-13 10:12:06 -070081 auto stream = brillo::MemoryStream::OpenCopyOf(data, nullptr);
Vitaly Buka3191e6b2015-08-20 23:17:13 -070082 CHECK(stream->GetRemainingSize());
Alex Vakulenko41705852015-10-13 10:12:06 -070083 brillo::ErrorPtr cromeos_error;
Vitaly Buka4f771532015-08-14 14:58:39 -070084 if (!request.AddRequestBody(std::move(stream), &cromeos_error)) {
85 weave::ErrorPtr error;
86 ConvertError(*cromeos_error, &error);
Vitaly Buka86852562015-08-06 11:06:25 -070087 transport_->RunCallbackAsync(
Alex Vakulenko94f8eba2015-10-14 08:52:45 -070088 FROM_HERE, base::Bind(callback, nullptr, base::Passed(&error)));
Alex Vakulenko297114c2015-10-12 13:45:43 -070089 return;
Vitaly Buka86852562015-08-06 11:06:25 -070090 }
91 }
Alex Vakulenko94f8eba2015-10-14 08:52:45 -070092 request.GetResponse(base::Bind(&OnSuccessCallback, callback),
93 base::Bind(&OnErrorCallback, callback));
Vitaly Buka00882b72015-08-06 00:32:11 -070094}
95
96} // namespace buffet