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 // 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