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> EasySetOptCallback(CURL * curl,CURLoption option,R (* callback)(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