14615e0d5aa416ab1a8596bde68f71f7ebe431b86Vitaly Buka// Copyright 2015 The Weave Authors. All rights reserved. 26da9425a14ac345b657354e62307d17df4a721dbVitaly Buka// Use of this source code is governed by a BSD-style license that can be 36da9425a14ac345b657354e62307d17df4a721dbVitaly Buka// found in the LICENSE file. 46da9425a14ac345b657354e62307d17df4a721dbVitaly Buka 51e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka#ifndef LIBWEAVE_INCLUDE_WEAVE_PROVIDER_HTTP_CLIENT_H_ 61e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka#define LIBWEAVE_INCLUDE_WEAVE_PROVIDER_HTTP_CLIENT_H_ 76da9425a14ac345b657354e62307d17df4a721dbVitaly Buka 86da9425a14ac345b657354e62307d17df4a721dbVitaly Buka#include <string> 96da9425a14ac345b657354e62307d17df4a721dbVitaly Buka#include <utility> 106da9425a14ac345b657354e62307d17df4a721dbVitaly Buka#include <vector> 116da9425a14ac345b657354e62307d17df4a721dbVitaly Buka 126da9425a14ac345b657354e62307d17df4a721dbVitaly Buka#include <base/callback.h> 130801a1f20a0c8f34130d567cd3b7dcbd2be9cb3cVitaly Buka#include <weave/error.h> 146da9425a14ac345b657354e62307d17df4a721dbVitaly Buka 156da9425a14ac345b657354e62307d17df4a721dbVitaly Bukanamespace weave { 161e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Bukanamespace provider { 176da9425a14ac345b657354e62307d17df4a721dbVitaly Buka 18282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// This interface should be implemented by the user of libweave and 19282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// provided during device creation in Device::Create(...) 20282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// libweave will use this interface to make HTTP/HTTPS calls to external 21282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// services. 22282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// 23282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// HttpClient interface has only one method SendRequest(...) to implement. 24282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// However, user code should also implement Response interface, that will be 25282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// passed into callback. 26282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// 27282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// Implementation of the SendRequest(...) method should make a proper 28282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// HTTP / HTTPS call according to the input parameters: 29282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// method - of the supported methods (kGet, kPatch, kPost, kPut) which 30282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// should map to the corresponding HTTP verb (GET, PATCH, POST, PUT) in 31282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// the request. 32282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// url - full URL including protocol, domain, path and parameters. Protocol 33282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// may be "http" or "https". In case of "https", it is implementer's 34282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// responsibility to establish a secure connection and verify endpoint 35282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// certificate chain. libweave will attempt connecting to Google Weave 36282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// servers. Proper root CA certificates should be available on the device. 37282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// headers - list of HTTP request headers that should be attached to the 38282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// request. 39282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// data - binary data that should be sent within HTTP request body. Empty 40282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// string means no data. Implementation needs to check for that. For 41282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// example, kGet method should never have data. It is also possible to have 42282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// no data for other methods as well. 43282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// callback - standard callback to notify libweave when request is complete 44282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// and provide results and response data. 45282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// 46282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// Implementation of the SendRequest(...) should be non-blocking, meaning it 47282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// should schedule network request and return right away. Later (after the 48282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// request is complete), callback should be invokes on the same thread. 49282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// Callback should never be called before SendRequest(...) returns. 50282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// 51282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// When invoking callback function, user should privide implementation 52282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// of the Response interface. For example, the following could be used as a 53282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// simple implementation: 54282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// struct ResponseImpl : public provider::HttpClient::Response { 55282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// int GetStatusCode() const override { return status; } 56282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// std::string GetContentType() const override { return content_type; } 57282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// std::string GetData() const override { return data; } 58282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// int status{0}; 59282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// std::string content_type; 60282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// std::string data; 61282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// }; 62282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// 63282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// See libweave/examples/provider/curl_http_client.cc for complete example 64282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik// implementing HttpClient interface using curl. 65282ea317435e0b0b32ef084dc78c7609b5de1ac2Gene Gutnik 666da9425a14ac345b657354e62307d17df4a721dbVitaly Bukaclass HttpClient { 676da9425a14ac345b657354e62307d17df4a721dbVitaly Buka public: 681a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Buka enum class Method { 691a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Buka kGet, 701a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Buka kPatch, 711a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Buka kPost, 721a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Buka kPut, 731a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Buka }; 741a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Buka 756da9425a14ac345b657354e62307d17df4a721dbVitaly Buka class Response { 766da9425a14ac345b657354e62307d17df4a721dbVitaly Buka public: 776da9425a14ac345b657354e62307d17df4a721dbVitaly Buka virtual int GetStatusCode() const = 0; 786da9425a14ac345b657354e62307d17df4a721dbVitaly Buka virtual std::string GetContentType() const = 0; 794774df2734a2b74f16047983751673388b6cb5b5Vitaly Buka virtual std::string GetData() const = 0; 806da9425a14ac345b657354e62307d17df4a721dbVitaly Buka 813bfb13d1a7a1d1677b3b3af9264f7cbecb6b71bdVitaly Buka virtual ~Response() {} 826da9425a14ac345b657354e62307d17df4a721dbVitaly Buka }; 836da9425a14ac345b657354e62307d17df4a721dbVitaly Buka 846da9425a14ac345b657354e62307d17df4a721dbVitaly Buka using Headers = std::vector<std::pair<std::string, std::string>>; 85747634273144e0df7b37475375ad4790b6a7b0e8Vitaly Buka using SendRequestCallback = 86747634273144e0df7b37475375ad4790b6a7b0e8Vitaly Buka base::Callback<void(std::unique_ptr<Response> response, ErrorPtr error)>; 876da9425a14ac345b657354e62307d17df4a721dbVitaly Buka 881a42e1466de3edd0c79215b739cd8e929ef8a7e8Vitaly Buka virtual void SendRequest(Method method, 89866b60a19c99f6db4def7f18cc902370d344a33aVitaly Buka const std::string& url, 90866b60a19c99f6db4def7f18cc902370d344a33aVitaly Buka const Headers& headers, 91866b60a19c99f6db4def7f18cc902370d344a33aVitaly Buka const std::string& data, 92747634273144e0df7b37475375ad4790b6a7b0e8Vitaly Buka const SendRequestCallback& callback) = 0; 936da9425a14ac345b657354e62307d17df4a721dbVitaly Buka 946da9425a14ac345b657354e62307d17df4a721dbVitaly Buka protected: 953bfb13d1a7a1d1677b3b3af9264f7cbecb6b71bdVitaly Buka virtual ~HttpClient() {} 966da9425a14ac345b657354e62307d17df4a721dbVitaly Buka}; 976da9425a14ac345b657354e62307d17df4a721dbVitaly Buka 981e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka} // namespace provider 996da9425a14ac345b657354e62307d17df4a721dbVitaly Buka} // namespace weave 1006da9425a14ac345b657354e62307d17df4a721dbVitaly Buka 1011e3636732171afb8cceb9e5cb835ec6a93787dbaVitaly Buka#endif // LIBWEAVE_INCLUDE_WEAVE_PROVIDER_HTTP_CLIENT_H_ 102