• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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