quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

upload_pausing.c (5635B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  * SPDX-License-Identifier: curl
     22  *
     23  ***************************************************************************/
     24 /* This is based on the PoC client of issue #11769
     25  */
     26 #include "first.h"
     27 
     28 static size_t total_read = 0;
     29 
     30 static size_t read_callback(char *ptr, size_t size, size_t nmemb,
     31                             void *userdata)
     32 {
     33   static const size_t PAUSE_READ_AFTER = 1;
     34 
     35   (void)size;
     36   (void)nmemb;
     37   (void)userdata;
     38   if(total_read >= PAUSE_READ_AFTER) {
     39     curl_mfprintf(stderr, "read_callback, return PAUSE\n");
     40     return CURL_READFUNC_PAUSE;
     41   }
     42   else {
     43     ptr[0] = '\n';
     44     ++total_read;
     45     curl_mfprintf(stderr, "read_callback, return 1 byte\n");
     46     return 1;
     47   }
     48 }
     49 
     50 static int progress_callback(void *clientp,
     51                              curl_off_t dltotal,
     52                              curl_off_t dlnow,
     53                              curl_off_t ultotal,
     54                              curl_off_t ulnow)
     55 {
     56   (void)dltotal;
     57   (void)dlnow;
     58   (void)ultotal;
     59   (void)ulnow;
     60   (void)clientp;
     61 #if 0
     62   /* Used to unpause on progress, but keeping for now. */
     63   {
     64     CURL *curl = (CURL *)clientp;
     65     curl_easy_pause(curl, CURLPAUSE_CONT);
     66     /* curl_easy_pause(curl, CURLPAUSE_RECV_CONT); */
     67   }
     68 #endif
     69   return 0;
     70 }
     71 
     72 static void usage_upload_pausing(const char *msg)
     73 {
     74   if(msg)
     75     curl_mfprintf(stderr, "%s\n", msg);
     76   curl_mfprintf(stderr,
     77     "usage: [options] url\n"
     78     "  upload and pause, options:\n"
     79     "  -V http_version (http/1.1, h2, h3) http version to use\n"
     80   );
     81 }
     82 
     83 static int test_upload_pausing(int argc, char *argv[])
     84 {
     85   CURL *curl;
     86   CURLcode rc = CURLE_OK;
     87   CURLU *cu;
     88   struct curl_slist *resolve = NULL;
     89   char resolve_buf[1024];
     90   char *url, *host = NULL, *port = NULL;
     91   long http_version = CURL_HTTP_VERSION_1_1;
     92   int ch;
     93 
     94   while((ch = cgetopt(argc, argv, "V:")) != -1) {
     95     switch(ch) {
     96     case 'V': {
     97       if(!strcmp("http/1.1", coptarg))
     98         http_version = CURL_HTTP_VERSION_1_1;
     99       else if(!strcmp("h2", coptarg))
    100         http_version = CURL_HTTP_VERSION_2_0;
    101       else if(!strcmp("h3", coptarg))
    102         http_version = CURL_HTTP_VERSION_3ONLY;
    103       else {
    104         usage_upload_pausing("invalid http version");
    105         return 1;
    106       }
    107       break;
    108     }
    109     default:
    110       usage_upload_pausing("invalid option");
    111       return 1;
    112     }
    113   }
    114   argc -= coptind;
    115   argv += coptind;
    116 
    117   if(argc != 1) {
    118     usage_upload_pausing("not enough arguments");
    119     return 2;
    120   }
    121   url = argv[0];
    122 
    123   curl_global_init(CURL_GLOBAL_DEFAULT);
    124   curl_global_trace("ids,time");
    125 
    126   cu = curl_url();
    127   if(!cu) {
    128     curl_mfprintf(stderr, "out of memory\n");
    129     return 1;
    130   }
    131   if(curl_url_set(cu, CURLUPART_URL, url, 0)) {
    132     curl_mfprintf(stderr, "not a URL: '%s'\n", url);
    133     return 1;
    134   }
    135   if(curl_url_get(cu, CURLUPART_HOST, &host, 0)) {
    136     curl_mfprintf(stderr, "could not get host of '%s'\n", url);
    137     return 1;
    138   }
    139   if(curl_url_get(cu, CURLUPART_PORT, &port, 0)) {
    140     curl_mfprintf(stderr, "could not get port of '%s'\n", url);
    141     return 1;
    142   }
    143   memset(&resolve, 0, sizeof(resolve));
    144   curl_msnprintf(resolve_buf, sizeof(resolve_buf)-1, "%s:%s:127.0.0.1",
    145                  host, port);
    146   resolve = curl_slist_append(resolve, resolve_buf);
    147 
    148   curl = curl_easy_init();
    149   if(!curl) {
    150     curl_mfprintf(stderr, "out of memory\n");
    151     return 1;
    152   }
    153   /* We want to use our own read function. */
    154   curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
    155 
    156   /* It will help us to continue the read function. */
    157   curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
    158   curl_easy_setopt(curl, CURLOPT_XFERINFODATA, curl);
    159   curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
    160 
    161   /* It will help us to ensure that keepalive does not help. */
    162   curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
    163   curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 1L);
    164   curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 1L);
    165   curl_easy_setopt(curl, CURLOPT_TCP_KEEPCNT, 1L);
    166 
    167   /* Enable uploading. */
    168   curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
    169   curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    170 
    171   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
    172   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
    173 
    174   if(curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L) != CURLE_OK ||
    175      curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, debug_cb)
    176      != CURLE_OK ||
    177      curl_easy_setopt(curl, CURLOPT_RESOLVE, resolve) != CURLE_OK)
    178     ERR();
    179 
    180   curl_easy_setopt(curl, CURLOPT_URL, url);
    181   curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, http_version);
    182 
    183   rc = curl_easy_perform(curl);
    184 
    185   if(curl) {
    186     curl_easy_cleanup(curl);
    187   }
    188 
    189   curl_slist_free_all(resolve);
    190   curl_free(host);
    191   curl_free(port);
    192   curl_url_cleanup(cu);
    193   curl_global_cleanup();
    194 
    195   return (int)rc;
    196 }