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  private:
    117   DISALLOW_COPY_AND_ASSIGN(CurlInterface);
    118 };
    119 
    120 class BRILLO_EXPORT CurlApi : public CurlInterface {
    121  public:
    122   CurlApi();
    123   ~CurlApi() override;
    124 
    125   // Wrapper around curl_easy_init().
    126   CURL* EasyInit() override;
    127 
    128   // Wrapper around curl_easy_cleanup().
    129   void EasyCleanup(CURL* curl) override;
    130 
    131   // Wrappers around curl_easy_setopt().
    132   CURLcode EasySetOptInt(CURL* curl, CURLoption option, int value) override;
    133   CURLcode EasySetOptStr(CURL* curl,
    134                          CURLoption option,
    135                          const std::string& value) override;
    136   CURLcode EasySetOptPtr(CURL* curl, CURLoption option, void* value) override;
    137   CURLcode EasySetOptCallback(CURL* curl,
    138                               CURLoption option,
    139                               intptr_t address) override;
    140   CURLcode EasySetOptOffT(CURL* curl,
    141                           CURLoption option,
    142                           curl_off_t value) override;
    143 
    144   // Wrapper around curl_easy_perform().
    145   CURLcode EasyPerform(CURL* curl) override;
    146 
    147   // Wrappers around curl_easy_getinfo().
    148   CURLcode EasyGetInfoInt(CURL* curl, CURLINFO info, int* value) const override;
    149   CURLcode EasyGetInfoDbl(CURL* curl,
    150                           CURLINFO info,
    151                           double* value) const override;
    152   CURLcode EasyGetInfoStr(CURL* curl,
    153                           CURLINFO info,
    154                           std::string* value) const override;
    155   CURLcode EasyGetInfoPtr(CURL* curl,
    156                           CURLINFO info,
    157                           void** value) const override;
    158 
    159   // Wrapper around curl_easy_strerror().
    160   std::string EasyStrError(CURLcode code) const override;
    161 
    162   // Wrapper around curl_multi_init().
    163   CURLM* MultiInit() override;
    164 
    165   // Wrapper around curl_multi_cleanup().
    166   CURLMcode MultiCleanup(CURLM* multi_handle) override;
    167 
    168   // Wrapper around curl_multi_info_read().
    169   CURLMsg* MultiInfoRead(CURLM* multi_handle, int* msgs_in_queue) override;
    170 
    171   // Wrapper around curl_multi_add_handle().
    172   CURLMcode MultiAddHandle(CURLM* multi_handle, CURL* curl_handle) override;
    173 
    174   // Wrapper around curl_multi_remove_handle().
    175   CURLMcode MultiRemoveHandle(CURLM* multi_handle, CURL* curl_handle) override;
    176 
    177   // Wrapper around curl_multi_setopt(CURLMOPT_SOCKETFUNCTION/SOCKETDATA).
    178   CURLMcode MultiSetSocketCallback(
    179       CURLM* multi_handle,
    180       curl_socket_callback socket_callback,
    181       void* userp) override;
    182 
    183   // Wrapper around curl_multi_setopt(CURLMOPT_TIMERFUNCTION/TIMERDATA).
    184   CURLMcode MultiSetTimerCallback(
    185       CURLM* multi_handle,
    186       curl_multi_timer_callback timer_callback,
    187       void* userp) override;
    188 
    189   // Wrapper around curl_multi_assign().
    190   CURLMcode MultiAssign(CURLM* multi_handle,
    191                         curl_socket_t sockfd,
    192                         void* sockp) override;
    193 
    194   // Wrapper around curl_multi_socket_action().
    195   CURLMcode MultiSocketAction(CURLM* multi_handle,
    196                               curl_socket_t s,
    197                               int ev_bitmask,
    198                               int* running_handles) override;
    199 
    200   // Wrapper around curl_multi_strerror().
    201   std::string MultiStrError(CURLMcode code) const override;
    202 
    203  private:
    204   DISALLOW_COPY_AND_ASSIGN(CurlApi);
    205 };
    206 
    207 }  // namespace http
    208 }  // namespace brillo
    209 
    210 #endif  // LIBBRILLO_BRILLO_HTTP_CURL_API_H_
    211