Home | History | Annotate | Download | only in http
      1 // Copyright 2014 The Chromium OS 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 LIBBRILLO_BRILLO_HTTP_CURL_API_H_
      6 #define LIBBRILLO_BRILLO_HTTP_CURL_API_H_
      7 
      8 #include <curl/curl.h>
      9 
     10 #include <string>
     11 
     12 #include <base/macros.h>
     13 #include <brillo/brillo_export.h>
     14 
     15 namespace brillo {
     16 namespace http {
     17 
     18 // Abstract wrapper around libcurl C API that allows us to mock it out in tests.
     19 class CurlInterface {
     20  public:
     21   CurlInterface() = default;
     22   virtual ~CurlInterface() = default;
     23 
     24   // Wrapper around curl_easy_init().
     25   virtual CURL* EasyInit() = 0;
     26 
     27   // Wrapper around curl_easy_cleanup().
     28   virtual void EasyCleanup(CURL* curl) = 0;
     29 
     30   // Wrappers around curl_easy_setopt().
     31   virtual CURLcode EasySetOptInt(CURL* curl, CURLoption option, int value) = 0;
     32   virtual CURLcode EasySetOptStr(CURL* curl,
     33                                  CURLoption option,
     34                                  const std::string& value) = 0;
     35   virtual CURLcode EasySetOptPtr(CURL* curl,
     36                                  CURLoption option,
     37                                  void* value) = 0;
     38   virtual CURLcode EasySetOptCallback(CURL* curl,
     39                                       CURLoption option,
     40                                       intptr_t address) = 0;
     41   virtual CURLcode EasySetOptOffT(CURL* curl,
     42                                   CURLoption option,
     43                                   curl_off_t value) = 0;
     44 
     45   // A type-safe wrapper around function callback options.
     46   template<typename R, typename... Args>
     47   inline CURLcode EasySetOptCallback(CURL* curl,
     48                                      CURLoption option,
     49                                      R(*callback)(Args...)) {
     50     return EasySetOptCallback(
     51         curl, option, reinterpret_cast<intptr_t>(callback));
     52   }
     53 
     54   // Wrapper around curl_easy_perform().
     55   virtual CURLcode EasyPerform(CURL* curl) = 0;
     56 
     57   // Wrappers around curl_easy_getinfo().
     58   virtual CURLcode EasyGetInfoInt(CURL* curl,
     59                                   CURLINFO info,
     60                                   int* value) const = 0;
     61   virtual CURLcode EasyGetInfoDbl(CURL* curl,
     62                                   CURLINFO info,
     63                                   double* value) const = 0;
     64   virtual CURLcode EasyGetInfoStr(CURL* curl,
     65                                   CURLINFO info,
     66                                   std::string* value) const = 0;
     67   virtual CURLcode EasyGetInfoPtr(CURL* curl,
     68                                   CURLINFO info,
     69                                   void** value) const = 0;
     70 
     71   // Wrapper around curl_easy_strerror().
     72   virtual std::string EasyStrError(CURLcode code) const = 0;
     73 
     74   // Wrapper around curl_multi_init().
     75   virtual CURLM* MultiInit() = 0;
     76 
     77   // Wrapper around curl_multi_cleanup().
     78   virtual CURLMcode MultiCleanup(CURLM* multi_handle) = 0;
     79 
     80   // Wrapper around curl_multi_info_read().
     81   virtual CURLMsg* MultiInfoRead(CURLM* multi_handle, int* msgs_in_queue) = 0;
     82 
     83   // Wrapper around curl_multi_add_handle().
     84   virtual CURLMcode MultiAddHandle(CURLM* multi_handle, CURL* curl_handle) = 0;
     85 
     86   // Wrapper around curl_multi_remove_handle().
     87   virtual CURLMcode MultiRemoveHandle(CURLM* multi_handle,
     88                                       CURL* curl_handle) = 0;
     89 
     90   // Wrapper around curl_multi_setopt(CURLMOPT_SOCKETFUNCTION/SOCKETDATA).
     91   virtual CURLMcode MultiSetSocketCallback(
     92       CURLM* multi_handle,
     93       curl_socket_callback socket_callback,
     94       void* userp) = 0;
     95 
     96   // Wrapper around curl_multi_setopt(CURLMOPT_TIMERFUNCTION/TIMERDATA).
     97   virtual CURLMcode MultiSetTimerCallback(
     98       CURLM* multi_handle,
     99       curl_multi_timer_callback timer_callback,
    100       void* userp) = 0;
    101 
    102   // Wrapper around curl_multi_assign().
    103   virtual CURLMcode MultiAssign(CURLM* multi_handle,
    104                                 curl_socket_t sockfd,
    105                                 void* sockp) = 0;
    106 
    107   // Wrapper around curl_multi_socket_action().
    108   virtual CURLMcode MultiSocketAction(CURLM* multi_handle,
    109                                       curl_socket_t s,
    110                                       int ev_bitmask,
    111                                       int* running_handles) = 0;
    112 
    113   // Wrapper around curl_multi_strerror().
    114   virtual std::string MultiStrError(CURLMcode code) const = 0;
    115 
    116   // Wrapper around curl_multi_perform().
    117   virtual CURLMcode MultiPerform(CURLM* multi_handle,
    118                                  int* running_handles) = 0;
    119 
    120   // Wrapper around curl_multi_wait().
    121   virtual CURLMcode MultiWait(CURLM* multi_handle,
    122                               curl_waitfd extra_fds[],
    123                               unsigned int extra_nfds,
    124                               int timeout_ms,
    125                               int* numfds) = 0;
    126 
    127  private:
    128   DISALLOW_COPY_AND_ASSIGN(CurlInterface);
    129 };
    130 
    131 class BRILLO_EXPORT CurlApi : public CurlInterface {
    132  public:
    133   CurlApi();
    134   ~CurlApi() override;
    135 
    136   // Wrapper around curl_easy_init().
    137   CURL* EasyInit() override;
    138 
    139   // Wrapper around curl_easy_cleanup().
    140   void EasyCleanup(CURL* curl) override;
    141 
    142   // Wrappers around curl_easy_setopt().
    143   CURLcode EasySetOptInt(CURL* curl, CURLoption option, int value) override;
    144   CURLcode EasySetOptStr(CURL* curl,
    145                          CURLoption option,
    146                          const std::string& value) override;
    147   CURLcode EasySetOptPtr(CURL* curl, CURLoption option, void* value) override;
    148   CURLcode EasySetOptCallback(CURL* curl,
    149                               CURLoption option,
    150                               intptr_t address) override;
    151   CURLcode EasySetOptOffT(CURL* curl,
    152                           CURLoption option,
    153                           curl_off_t value) override;
    154 
    155   // Wrapper around curl_easy_perform().
    156   CURLcode EasyPerform(CURL* curl) override;
    157 
    158   // Wrappers around curl_easy_getinfo().
    159   CURLcode EasyGetInfoInt(CURL* curl, CURLINFO info, int* value) const override;
    160   CURLcode EasyGetInfoDbl(CURL* curl,
    161                           CURLINFO info,
    162                           double* value) const override;
    163   CURLcode EasyGetInfoStr(CURL* curl,
    164                           CURLINFO info,
    165                           std::string* value) const override;
    166   CURLcode EasyGetInfoPtr(CURL* curl,
    167                           CURLINFO info,
    168                           void** value) const override;
    169 
    170   // Wrapper around curl_easy_strerror().
    171   std::string EasyStrError(CURLcode code) const override;
    172 
    173   // Wrapper around curl_multi_init().
    174   CURLM* MultiInit() override;
    175 
    176   // Wrapper around curl_multi_cleanup().
    177   CURLMcode MultiCleanup(CURLM* multi_handle) override;
    178 
    179   // Wrapper around curl_multi_info_read().
    180   CURLMsg* MultiInfoRead(CURLM* multi_handle, int* msgs_in_queue) override;
    181 
    182   // Wrapper around curl_multi_add_handle().
    183   CURLMcode MultiAddHandle(CURLM* multi_handle, CURL* curl_handle) override;
    184 
    185   // Wrapper around curl_multi_remove_handle().
    186   CURLMcode MultiRemoveHandle(CURLM* multi_handle, CURL* curl_handle) override;
    187 
    188   // Wrapper around curl_multi_setopt(CURLMOPT_SOCKETFUNCTION/SOCKETDATA).
    189   CURLMcode MultiSetSocketCallback(
    190       CURLM* multi_handle,
    191       curl_socket_callback socket_callback,
    192       void* userp) override;
    193 
    194   // Wrapper around curl_multi_setopt(CURLMOPT_TIMERFUNCTION/TIMERDATA).
    195   CURLMcode MultiSetTimerCallback(
    196       CURLM* multi_handle,
    197       curl_multi_timer_callback timer_callback,
    198       void* userp) override;
    199 
    200   // Wrapper around curl_multi_assign().
    201   CURLMcode MultiAssign(CURLM* multi_handle,
    202                         curl_socket_t sockfd,
    203                         void* sockp) override;
    204 
    205   // Wrapper around curl_multi_socket_action().
    206   CURLMcode MultiSocketAction(CURLM* multi_handle,
    207                               curl_socket_t s,
    208                               int ev_bitmask,
    209                               int* running_handles) override;
    210 
    211   // Wrapper around curl_multi_strerror().
    212   std::string MultiStrError(CURLMcode code) const override;
    213 
    214   // Wrapper around curl_multi_perform().
    215   CURLMcode MultiPerform(CURLM* multi_handle,
    216                          int* running_handles) override;
    217 
    218   // Wrapper around curl_multi_wait().
    219   CURLMcode MultiWait(CURLM* multi_handle,
    220                       curl_waitfd extra_fds[],
    221                       unsigned int extra_nfds,
    222                       int timeout_ms,
    223                       int* numfds) override;
    224 
    225  private:
    226   DISALLOW_COPY_AND_ASSIGN(CurlApi);
    227 };
    228 
    229 }  // namespace http
    230 }  // namespace brillo
    231 
    232 #endif  // LIBBRILLO_BRILLO_HTTP_CURL_API_H_
    233