1// Copyright 2015 The Weave 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#ifndef LIBWEAVE_INCLUDE_WEAVE_PROVIDER_HTTP_CLIENT_H_
6#define LIBWEAVE_INCLUDE_WEAVE_PROVIDER_HTTP_CLIENT_H_
7
8#include <string>
9#include <utility>
10#include <vector>
11
12#include <base/callback.h>
13#include <weave/error.h>
14
15namespace weave {
16namespace provider {
17
18// This interface should be implemented by the user of libweave and
19// provided during device creation in Device::Create(...)
20// libweave will use this interface to make HTTP/HTTPS calls to external
21// services.
22//
23// HttpClient interface has only one method SendRequest(...) to implement.
24// However, user code should also implement Response interface, that will be
25// passed into callback.
26//
27// Implementation of the SendRequest(...) method should make a proper
28// HTTP / HTTPS call according to the input parameters:
29//   method - of the supported methods (kGet, kPatch, kPost, kPut) which
30//     should map to the corresponding HTTP verb (GET, PATCH, POST, PUT) in
31//     the request.
32//   url - full URL including protocol, domain, path and parameters. Protocol
33//     may be "http" or "https". In case of "https", it is implementer's
34//     responsibility to establish a secure connection and verify endpoint
35//     certificate chain. libweave will attempt connecting to Google Weave
36//     servers. Proper root CA certificates should be available on the device.
37//   headers - list of HTTP request headers that should be attached to the
38//     request.
39//   data - binary data that should be sent within HTTP request body. Empty
40//     string means no data. Implementation needs to check for that. For
41//     example, kGet method should never have data. It is also possible to have
42//     no data for other methods as well.
43//   callback - standard callback to notify libweave when request is complete
44//     and provide results and response data.
45//
46// Implementation of the SendRequest(...) should be non-blocking, meaning it
47// should schedule network request and return right away. Later (after the
48// request is complete), callback should be invokes on the same thread.
49// Callback should never be called before SendRequest(...) returns.
50//
51// When invoking callback function, user should privide implementation
52// of the Response interface. For example, the following could be used as a
53// simple implementation:
54//   struct ResponseImpl : public provider::HttpClient::Response {
55//     int GetStatusCode() const override { return status; }
56//     std::string GetContentType() const override { return content_type; }
57//     std::string GetData() const override { return data; }
58//     int status{0};
59//     std::string content_type;
60//     std::string data;
61//   };
62//
63// See libweave/examples/provider/curl_http_client.cc for complete example
64// implementing HttpClient interface using curl.
65
66class HttpClient {
67 public:
68  enum class Method {
69    kGet,
70    kPatch,
71    kPost,
72    kPut,
73  };
74
75  class Response {
76   public:
77    virtual int GetStatusCode() const = 0;
78    virtual std::string GetContentType() const = 0;
79    virtual std::string GetData() const = 0;
80
81    virtual ~Response() {}
82  };
83
84  using Headers = std::vector<std::pair<std::string, std::string>>;
85  using SendRequestCallback =
86      base::Callback<void(std::unique_ptr<Response> response, ErrorPtr error)>;
87
88  virtual void SendRequest(Method method,
89                           const std::string& url,
90                           const Headers& headers,
91                           const std::string& data,
92                           const SendRequestCallback& callback) = 0;
93
94 protected:
95  virtual ~HttpClient() {}
96};
97
98}  // namespace provider
99}  // namespace weave
100
101#endif  // LIBWEAVE_INCLUDE_WEAVE_PROVIDER_HTTP_CLIENT_H_
102