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