gnunet-android

GNUnet for Android
Log | Files | Refs | README

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