gnunet_curl_lib.h (13587B)
1 /* 2 This file is part of GNUnet 3 Copyright (C) 2014, 2015, 2016 GNUnet e.V. 4 5 GNUnet is free software: you can redistribute it and/or modify it 6 under the terms of the GNU Affero General Public License as published 7 by the Free Software Foundation, either version 3 of the License, 8 or (at your option) any later version. 9 10 GNUnet is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Affero General Public License for more details. 14 15 You should have received a copy of the GNU Affero General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 SPDX-License-Identifier: AGPL3.0-or-later 19 */ 20 /** 21 * @addtogroup lib_extra Additional libraries 22 * @{ 23 * 24 * @file src/include/gnunet_curl_lib.h 25 * @brief library to make it easy to download JSON replies over HTTP 26 * @author Sree Harsha Totakura <sreeharsha@totakura.in> 27 * @author Christian Grothoff 28 * 29 * @defgroup curl CURL integration library 30 * Download JSON using libcurl. 31 * @{ 32 */ 33 #ifndef GNUNET_CURL_LIB_H 34 #define GNUNET_CURL_LIB_H 35 36 #include <curl/curl.h> 37 #include "gnunet_util_lib.h" 38 39 40 /** 41 * Function called by the context to ask for the event loop to be 42 * rescheduled, that is the application should call 43 * #GNUNET_CURL_get_select_info() as the set of sockets we care about 44 * just changed. 45 * 46 * @param cls closure 47 */ 48 typedef void 49 (*GNUNET_CURL_RescheduleCallback)(void *cls); 50 51 /** 52 * @brief Buffer data structure we use to buffer the HTTP download 53 * before giving it to the JSON parser. 54 */ 55 struct GNUNET_CURL_DownloadBuffer 56 { 57 /** 58 * Download buffer 59 */ 60 void *buf; 61 62 /** 63 * The size of the download buffer 64 */ 65 size_t buf_size; 66 67 /** 68 * Error code (based on libc errno) if we failed to download 69 * (e.g. response too large). 70 */ 71 int eno; 72 }; 73 74 75 /** 76 * Parses the raw response we got from the Web server. 77 * 78 * @param db the raw data 79 * @param eh handle 80 * @param response_code HTTP response code 81 * @return the parsed object 82 */ 83 typedef void * 84 (*GNUNET_CURL_RawParser) (struct GNUNET_CURL_DownloadBuffer *db, 85 CURL *eh, 86 long *response_code); 87 88 /** 89 * Deallocate the response. 90 * 91 * @param response object to clean 92 */ 93 typedef void 94 (*GNUNET_CURL_ResponseCleaner) (void *response); 95 96 /** 97 * Initialise this library. This function should be called before using any of 98 * the following functions. 99 * 100 * @param cb function to call when rescheduling is required 101 * @param cb_cls closure for @a cb 102 * @return library context 103 */ 104 struct GNUNET_CURL_Context * 105 GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, 106 void *cb_cls); 107 108 109 /** 110 * Obtain the information for a select() call to wait until 111 * #GNUNET_CURL_perform() is ready again. 112 * 113 * Basically, a client should use this API to prepare for select(), 114 * then block on select(), then call #GNUNET_CURL_perform() and then 115 * start again until the work with the context is done. 116 * 117 * This function will NOT zero out the sets and assumes that @a max_fd 118 * and @a timeout are already set to minimal applicable values. It is 119 * safe to give this API FD-sets and @a max_fd and @a timeout that are 120 * already initialized to some other descriptors that need to go into 121 * the select() call. 122 * 123 * @param ctx context to get the event loop information for 124 * @param read_fd_set will be set for any pending read operations 125 * @param write_fd_set will be set for any pending write operations 126 * @param except_fd_set is here because curl_multi_fdset() has this argument 127 * @param max_fd set to the highest FD included in any set; 128 * if the existing sets have no FDs in it, the initial 129 * value should be "-1". (Note that `max_fd + 1` will need 130 * to be passed to select().) 131 * @param timeout set to the timeout in milliseconds (!); -1 means 132 * no timeout (NULL, blocking forever is OK), 0 means to 133 * proceed immediately with #GNUNET_CURL_perform(). 134 */ 135 void 136 GNUNET_CURL_get_select_info (struct GNUNET_CURL_Context *ctx, 137 fd_set *read_fd_set, 138 fd_set *write_fd_set, 139 fd_set *except_fd_set, 140 int *max_fd, 141 long *timeout); 142 143 144 /** 145 * Add custom request header. 146 * 147 * @param ctx cURL context. 148 * @param header header string; will be given to the context AS IS. 149 * @return #GNUNET_OK if no errors occurred, #GNUNET_SYSERR otherwise. 150 */ 151 enum GNUNET_GenericReturnValue 152 GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, 153 const char *header); 154 155 /** 156 * Run the main event loop for the CURL interaction. 157 * 158 * @param ctx the library context 159 */ 160 void 161 GNUNET_CURL_perform (struct GNUNET_CURL_Context *ctx); 162 163 164 /** 165 * Run the main event loop for the HTTP interaction. 166 * 167 * @param ctx the library context 168 * @param rp parses the raw response returned from 169 * the Web server. 170 * @param rc cleans/frees the response 171 */ 172 void 173 GNUNET_CURL_perform2 (struct GNUNET_CURL_Context *ctx, 174 GNUNET_CURL_RawParser rp, 175 GNUNET_CURL_ResponseCleaner rc); 176 177 /** 178 * Cleanup library initialisation resources. This function should be called 179 * after using this library to cleanup the resources occupied during library's 180 * initialisation. 181 * 182 * @param ctx the library context 183 */ 184 void 185 GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx); 186 187 188 /** 189 * Entry in the context's job queue. 190 */ 191 struct GNUNET_CURL_Job; 192 193 /** 194 * Function to call upon completion of a job. 195 * 196 * @param cls closure 197 * @param response_code HTTP response code from server, 0 on hard error 198 * @param response in JSON, NULL if response was not in JSON format 199 */ 200 typedef void 201 (*GNUNET_CURL_JobCompletionCallback)(void *cls, 202 long response_code, 203 const void *response); 204 205 206 /** 207 * Function to call upon completion of a raw job. 208 * 209 * @param cls closure 210 * @param response_code HTTP response code from server, 0 on hard error 211 * @param body http body of the response 212 * @param body_size number of bytes in @a body 213 */ 214 typedef void 215 (*GNUNET_CURL_RawJobCompletionCallback)(void *cls, 216 long response_code, 217 const void *body, 218 size_t body_size); 219 220 221 /** 222 * Schedule a CURL request to be executed and call the given @a jcc 223 * upon its completion. Note that the context will make use of the 224 * CURLOPT_PRIVATE facility of the CURL @a eh. 225 * 226 * @param ctx context to execute the job in 227 * @param eh curl easy handle for the request, will 228 * be executed AND cleaned up 229 * @param jcc callback to invoke upon completion 230 * @param jcc_cls closure for @a jcc 231 * @return NULL on error (in this case, @a eh is still released!) 232 */ 233 struct GNUNET_CURL_Job * 234 GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx, 235 CURL *eh, 236 GNUNET_CURL_JobCompletionCallback jcc, 237 void *jcc_cls); 238 239 240 /** 241 * Schedule a CURL request to be executed and call the given @a jcc 242 * upon its completion. Note that the context will make use of the 243 * CURLOPT_PRIVATE facility of the CURL @a eh. 244 * 245 * This function modifies the CURL handle to add the 246 * "Content-Type: application/json" header. 247 * 248 * @param ctx context to execute the job in 249 * @param eh curl easy handle for the request, will 250 * be executed AND cleaned up 251 * @param jcc callback to invoke upon completion 252 * @param jcc_cls closure for @a jcc 253 * @return NULL on error (in this case, @a eh is still released!) 254 */ 255 struct GNUNET_CURL_Job * 256 GNUNET_CURL_job_add_with_ct_json (struct GNUNET_CURL_Context *ctx, 257 CURL *eh, 258 GNUNET_CURL_JobCompletionCallback jcc, 259 void *jcc_cls); 260 261 262 /** 263 * Force use of the provided username and password 264 * for client authentication for all operations performed 265 * with @a ctx. 266 * 267 * @param ctx context to set authentication data for 268 * @param userpass string with "$USERNAME:$PASSWORD" 269 */ 270 void 271 GNUNET_CURL_set_userpass (struct GNUNET_CURL_Context *ctx, 272 const char *userpass); 273 274 275 /** 276 * Force use of the provided TLS client certificate for client authentication 277 * for all operations performed with @a ctx. 278 * 279 * Note that if the provided information is incorrect, 280 * the earliest operation that could fail is 281 * #GNUNET_CURL_job_add() or #GNUNET_CURL_job_add2()! 282 * 283 * @param ctx context to set authentication data for 284 * @param certtype type of the certificate 285 * @param certfile file with the certificate 286 * @param keyfile file with the private key 287 * @param keypass passphrase to decrypt @a keyfile (or NULL) 288 */ 289 void 290 GNUNET_CURL_set_tlscert (struct GNUNET_CURL_Context *ctx, 291 const char *certtype, 292 const char *certfile, 293 const char *keyfile, 294 const char *keypass); 295 296 297 /** 298 * Schedule a CURL request to be executed and call the given @a jcc upon its 299 * completion. Note that the context will make use of the CURLOPT_PRIVATE 300 * facility of the CURL @a eh. 301 * 302 * @param ctx context to execute the job in 303 * @param eh curl easy handle for the request, will 304 * be executed AND cleaned up 305 * @param job_headers extra headers to add for this request 306 * @param jcc callback to invoke upon completion 307 * @param jcc_cls closure for @a jcc 308 * @return NULL on error (in this case, @a eh is still released!) 309 */ 310 struct GNUNET_CURL_Job * 311 GNUNET_CURL_job_add2 (struct GNUNET_CURL_Context *ctx, 312 CURL *eh, 313 const struct curl_slist *job_headers, 314 GNUNET_CURL_JobCompletionCallback jcc, 315 void *jcc_cls); 316 317 318 /** 319 * Schedule a CURL request to be executed and call the given @a jcc 320 * upon its completion. Note that the context will make use of the 321 * CURLOPT_PRIVATE facility of the CURL @a eh. Used to download 322 * resources that are NOT in JSON. The raw body will be returned. 323 * 324 * @param ctx context to execute the job in 325 * @param eh curl easy handle for the request, will 326 * be executed AND cleaned up 327 * @param job_headers extra headers to add for this request 328 * @param jcc callback to invoke upon completion 329 * @param jcc_cls closure for @a jcc 330 * @return NULL on error (in this case, @a eh is still released!) 331 */ 332 struct GNUNET_CURL_Job * 333 GNUNET_CURL_job_add_raw (struct GNUNET_CURL_Context *ctx, 334 CURL *eh, 335 const struct curl_slist *job_headers, 336 GNUNET_CURL_RawJobCompletionCallback jcc, 337 void *jcc_cls); 338 339 340 /** 341 * Add @a extra_headers to the HTTP headers for @a job. 342 * 343 * @param[in,out] job the job to modify 344 * @param extra_headers headers to append 345 */ 346 void 347 GNUNET_CURL_extend_headers (struct GNUNET_CURL_Job *job, 348 const struct curl_slist *extra_headers); 349 350 351 /** 352 * Cancel a job. Must only be called before the job completion 353 * callback is called for the respective job. 354 * 355 * @param job job to cancel 356 */ 357 void 358 GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job); 359 360 361 /* ******* GNUnet SCHEDULER integration ************ */ 362 363 364 /** 365 * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule(). 366 */ 367 struct GNUNET_CURL_RescheduleContext; 368 369 370 /** 371 * Initialize reschedule context. 372 * 373 * @param ctx context to manage 374 * @return closure for #GNUNET_CURL_gnunet_scheduler_reschedule(). 375 */ 376 struct GNUNET_CURL_RescheduleContext * 377 GNUNET_CURL_gnunet_rc_create (struct GNUNET_CURL_Context *ctx); 378 379 /** 380 * Initialize reschedule context; with custom response parser 381 * 382 * @param ctx context to manage 383 * @return closure for #GNUNET_CURL_gnunet_scheduler_reschedule(). 384 */ 385 struct GNUNET_CURL_RescheduleContext * 386 GNUNET_CURL_gnunet_rc_create_with_parser (struct GNUNET_CURL_Context *ctx, 387 GNUNET_CURL_RawParser rp, 388 GNUNET_CURL_ResponseCleaner rc); 389 390 391 /** 392 * Destroy reschedule context. 393 * 394 * @param rc context to destroy 395 */ 396 void 397 GNUNET_CURL_gnunet_rc_destroy (struct GNUNET_CURL_RescheduleContext *rc); 398 399 400 /** 401 * Implementation of the #GNUNET_CURL_RescheduleCallback for GNUnet's 402 * scheduler. Will run the CURL context using GNUnet's scheduler. 403 * Note that you MUST immediately destroy the reschedule context after 404 * calling #GNUNET_CURL_fini(). 405 * 406 * @param cls must point to a `struct GNUNET_CURL_RescheduleContext *` 407 * (pointer to a pointer!) 408 */ 409 void 410 GNUNET_CURL_gnunet_scheduler_reschedule (void *cls); 411 412 413 /** 414 * Enable sending the async scope ID as a header. 415 * 416 * @param ctx the context to enable this for 417 * @param header_name name of the header to send. 418 */ 419 void 420 GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx, 421 const char *header_name); 422 423 424 /** 425 * Return #GNUNET_YES if given a valid scope ID and 426 * #GNUNET_NO otherwise. See 427 * #GNUNET_CURL_enable_async_scope_header() for the 428 * code that generates such a @a scope_id in an HTTP 429 * header. 430 * 431 * @returns #GNUNET_YES iff given a valid scope ID 432 */ 433 enum GNUNET_GenericReturnValue 434 GNUNET_CURL_is_valid_scope_id (const char *scope_id); 435 436 437 #endif 438 /** @} */ /* end of group */ 439 440 /** @} */ /* end of group addition to lib_extra */ 441 442 /* end of gnunet_curl_lib.h */