1 // Copyright 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "buffet/http_transport_client.h"
16
17 #include <base/bind.h>
18 #include <brillo/errors/error.h>
19 #include <brillo/http/http_request.h>
20 #include <brillo/http/http_utils.h>
21 #include <brillo/streams/memory_stream.h>
22 #include <weave/enum_to_string.h>
23
24 #include "buffet/weave_error_conversion.h"
25
26 namespace buffet {
27
28 namespace {
29
30 using weave::provider::HttpClient;
31
32 // The number of seconds each HTTP request will be allowed before timing out.
33 const int kRequestTimeoutSeconds = 30;
34
35 class ResponseImpl : public HttpClient::Response {
36 public:
37 ~ResponseImpl() override = default;
ResponseImpl(std::unique_ptr<brillo::http::Response> response)38 explicit ResponseImpl(std::unique_ptr<brillo::http::Response> response)
39 : response_{std::move(response)},
40 data_{response_->ExtractDataAsString()} {}
41
42 // HttpClient::Response implementation
GetStatusCode() const43 int GetStatusCode() const override { return response_->GetStatusCode(); }
44
GetContentType() const45 std::string GetContentType() const override {
46 return response_->GetContentType();
47 }
48
GetData() const49 std::string GetData() const override { return data_; }
50
51 private:
52 std::unique_ptr<brillo::http::Response> response_;
53 std::string data_;
54 DISALLOW_COPY_AND_ASSIGN(ResponseImpl);
55 };
56
OnSuccessCallback(const HttpClient::SendRequestCallback & callback,int id,std::unique_ptr<brillo::http::Response> response)57 void OnSuccessCallback(const HttpClient::SendRequestCallback& callback,
58 int id,
59 std::unique_ptr<brillo::http::Response> response) {
60 callback.Run(std::unique_ptr<HttpClient::Response>{new ResponseImpl{
61 std::move(response)}},
62 nullptr);
63 }
64
OnErrorCallback(const HttpClient::SendRequestCallback & callback,int id,const brillo::Error * brillo_error)65 void OnErrorCallback(const HttpClient::SendRequestCallback& callback,
66 int id,
67 const brillo::Error* brillo_error) {
68 weave::ErrorPtr error;
69 ConvertError(*brillo_error, &error);
70 callback.Run(nullptr, std::move(error));
71 }
72
73 } // anonymous namespace
74
HttpTransportClient()75 HttpTransportClient::HttpTransportClient()
76 : transport_{brillo::http::Transport::CreateDefault()} {
77 transport_->SetDefaultTimeout(
78 base::TimeDelta::FromSeconds(kRequestTimeoutSeconds));
79 }
80
~HttpTransportClient()81 HttpTransportClient::~HttpTransportClient() {}
82
SendRequest(Method method,const std::string & url,const Headers & headers,const std::string & data,const SendRequestCallback & callback)83 void HttpTransportClient::SendRequest(Method method,
84 const std::string& url,
85 const Headers& headers,
86 const std::string& data,
87 const SendRequestCallback& callback) {
88 brillo::http::Request request(url, weave::EnumToString(method), transport_);
89 request.AddHeaders(headers);
90 if (!data.empty()) {
91 auto stream = brillo::MemoryStream::OpenCopyOf(data, nullptr);
92 CHECK(stream->GetRemainingSize());
93 brillo::ErrorPtr cromeos_error;
94 if (!request.AddRequestBody(std::move(stream), &cromeos_error)) {
95 weave::ErrorPtr error;
96 ConvertError(*cromeos_error, &error);
97 transport_->RunCallbackAsync(
98 FROM_HERE, base::Bind(callback, nullptr, base::Passed(&error)));
99 return;
100 }
101 }
102 request.GetResponse(base::Bind(&OnSuccessCallback, callback),
103 base::Bind(&OnErrorCallback, callback));
104 }
105
106 } // namespace buffet
107