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 26namespace buffet { 27 28namespace { 29 30using weave::provider::HttpClient; 31 32// The number of seconds each HTTP request will be allowed before timing out. 33const int kRequestTimeoutSeconds = 30; 34 35class ResponseImpl : public HttpClient::Response { 36 public: 37 ~ResponseImpl() override = default; 38 explicit ResponseImpl(std::unique_ptr<brillo::http::Response> response) 39 : response_{std::move(response)}, 40 data_{response_->ExtractDataAsString()} {} 41 42 // HttpClient::Response implementation 43 int GetStatusCode() const override { return response_->GetStatusCode(); } 44 45 std::string GetContentType() const override { 46 return response_->GetContentType(); 47 } 48 49 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 57void 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 65void 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 75HttpTransportClient::HttpTransportClient() 76 : transport_{brillo::http::Transport::CreateDefault()} { 77 transport_->SetDefaultTimeout( 78 base::TimeDelta::FromSeconds(kRequestTimeoutSeconds)); 79} 80 81HttpTransportClient::~HttpTransportClient() {} 82 83void 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