quickjs-tart

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

lib670.c (6698B)


      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 #include "first.h"
     25 
     26 #include "memdebug.h"
     27 
     28 #define PAUSE_TIME      5
     29 
     30 struct t670_ReadThis {
     31   CURL *easy;
     32   time_t origin;
     33   int count;
     34 };
     35 
     36 static size_t t670_read_cb(char *ptr, size_t size, size_t nmemb, void *userp)
     37 {
     38   struct t670_ReadThis *pooh = (struct t670_ReadThis *) userp;
     39   time_t delta;
     40 
     41   if(size * nmemb < 1)
     42     return 0;
     43 
     44   switch(pooh->count++) {
     45   case 0:
     46     *ptr = '\x41'; /* ASCII A. */
     47     return 1;
     48   case 1:
     49     pooh->origin = time(NULL);
     50     return CURL_READFUNC_PAUSE;
     51   case 2:
     52     delta = time(NULL) - pooh->origin;
     53     *ptr = delta >= PAUSE_TIME ? '\x42' : '\x41'; /* ASCII A or B. */
     54     return 1;
     55   case 3:
     56     return 0;
     57   }
     58   curl_mfprintf(stderr, "Read callback called after EOF\n");
     59   exit(1);
     60 }
     61 
     62 static int t670_xferinfo(void *clientp,
     63                          curl_off_t dltotal, curl_off_t dlnow,
     64                          curl_off_t ultotal, curl_off_t ulnow)
     65 {
     66   struct t670_ReadThis *pooh = (struct t670_ReadThis *) clientp;
     67 
     68   (void) dltotal;
     69   (void) dlnow;
     70   (void) ultotal;
     71   (void) ulnow;
     72 
     73   if(pooh->origin) {
     74     time_t delta = time(NULL) - pooh->origin;
     75 
     76     if(delta >= 4 * PAUSE_TIME) {
     77       curl_mfprintf(stderr, "unpausing failed: drain problem?\n");
     78       return CURLE_ABORTED_BY_CALLBACK;
     79     }
     80 
     81     if(delta >= PAUSE_TIME)
     82       curl_easy_pause(pooh->easy, CURLPAUSE_CONT);
     83   }
     84 
     85   return 0;
     86 }
     87 
     88 static CURLcode test_lib670(char *URL)
     89 {
     90   static const char testname[] = "field";
     91 
     92   curl_mime *mime = NULL;
     93   struct curl_httppost *formpost = NULL;
     94 
     95   struct t670_ReadThis pooh;
     96   CURLcode res = TEST_ERR_FAILURE;
     97 
     98   /*
     99    * Check proper pausing/unpausing from a mime or form read callback.
    100    */
    101 
    102   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    103     curl_mfprintf(stderr, "curl_global_init() failed\n");
    104     return TEST_ERR_MAJOR_BAD;
    105   }
    106 
    107   pooh.origin = (time_t) 0;
    108   pooh.count = 0;
    109   pooh.easy = curl_easy_init();
    110 
    111   /* First set the URL that is about to receive our POST. */
    112   test_setopt(pooh.easy, CURLOPT_URL, URL);
    113 
    114   /* get verbose debug output please */
    115   test_setopt(pooh.easy, CURLOPT_VERBOSE, 1L);
    116 
    117   /* include headers in the output */
    118   test_setopt(pooh.easy, CURLOPT_HEADER, 1L);
    119 
    120   if(testnum == 670 || testnum == 671) {
    121     curl_mimepart *part;
    122     /* Build the mime tree. */
    123     mime = curl_mime_init(pooh.easy);
    124     part = curl_mime_addpart(mime);
    125     res = curl_mime_name(part, testname);
    126     if(res != CURLE_OK) {
    127       curl_mfprintf(stderr,
    128               "Something went wrong when building the mime structure: %d\n",
    129               res);
    130       goto test_cleanup;
    131     }
    132 
    133     res = curl_mime_data_cb(part, (curl_off_t) 2, t670_read_cb,
    134                             NULL, NULL, &pooh);
    135 
    136     /* Bind mime data to its easy handle. */
    137     if(res == CURLE_OK)
    138       test_setopt(pooh.easy, CURLOPT_MIMEPOST, mime);
    139   }
    140   else {
    141     struct curl_httppost *lastptr = NULL;
    142     CURLFORMcode formrc;
    143     /* Build the form. */
    144     formrc = curl_formadd(&formpost, &lastptr,
    145                           CURLFORM_COPYNAME, testname,
    146                           CURLFORM_STREAM, &pooh,
    147                           CURLFORM_CONTENTLEN, (curl_off_t) 2,
    148                           CURLFORM_END);
    149     if(formrc) {
    150       curl_mfprintf(stderr, "curl_formadd() = %d\n", (int) formrc);
    151       goto test_cleanup;
    152     }
    153 
    154     /* We want to use our own read function. */
    155     test_setopt(pooh.easy, CURLOPT_READFUNCTION, t670_read_cb);
    156 
    157     /* Send a multi-part formpost. */
    158     test_setopt(pooh.easy, CURLOPT_HTTPPOST, formpost);
    159   }
    160 
    161   if(testnum == 670 || testnum == 672) {
    162     CURLMcode mres;
    163     CURLM *multi;
    164     /* Use the multi interface. */
    165     multi = curl_multi_init();
    166     mres = curl_multi_add_handle(multi, pooh.easy);
    167     while(!mres) {
    168       struct timeval timeout;
    169       int rc = 0;
    170       fd_set fdread;
    171       fd_set fdwrite;
    172       fd_set fdexcept;
    173       int maxfd = -1;
    174       int still_running = 0;
    175 
    176       mres = curl_multi_perform(multi, &still_running);
    177       if(!still_running || mres != CURLM_OK)
    178         break;
    179 
    180       if(pooh.origin) {
    181         time_t delta = time(NULL) - pooh.origin;
    182 
    183         if(delta >= 4 * PAUSE_TIME) {
    184           curl_mfprintf(stderr, "unpausing failed: drain problem?\n");
    185           res = CURLE_OPERATION_TIMEDOUT;
    186           break;
    187         }
    188 
    189         if(delta >= PAUSE_TIME)
    190           curl_easy_pause(pooh.easy, CURLPAUSE_CONT);
    191       }
    192 
    193       FD_ZERO(&fdread);
    194       FD_ZERO(&fdwrite);
    195       FD_ZERO(&fdexcept);
    196       timeout.tv_sec = 0;
    197       timeout.tv_usec = 1000000 * PAUSE_TIME / 10;
    198       mres = curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcept, &maxfd);
    199       if(mres)
    200         break;
    201 #ifdef _WIN32
    202       if(maxfd == -1)
    203         curlx_wait_ms(100);
    204       else
    205 #endif
    206       rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcept, &timeout);
    207       if(rc == -1) {
    208         curl_mfprintf(stderr, "Select error\n");
    209         break;
    210       }
    211     }
    212 
    213     if(mres != CURLM_OK)
    214       for(;;) {
    215         int msgs_left;
    216         CURLMsg *msg;
    217         msg = curl_multi_info_read(multi, &msgs_left);
    218         if(!msg)
    219           break;
    220         if(msg->msg == CURLMSG_DONE) {
    221           res = msg->data.result;
    222         }
    223       }
    224 
    225     curl_multi_remove_handle(multi, pooh.easy);
    226     curl_multi_cleanup(multi);
    227   }
    228   else {
    229     /* Use the easy interface. */
    230     test_setopt(pooh.easy, CURLOPT_XFERINFODATA, &pooh);
    231     test_setopt(pooh.easy, CURLOPT_XFERINFOFUNCTION, t670_xferinfo);
    232     test_setopt(pooh.easy, CURLOPT_NOPROGRESS, 0L);
    233     res = curl_easy_perform(pooh.easy);
    234   }
    235 
    236 test_cleanup:
    237   curl_easy_cleanup(pooh.easy);
    238 
    239   if(testnum == 670 || testnum == 671) {
    240     curl_mime_free(mime);
    241   }
    242   else {
    243     curl_formfree(formpost);
    244   }
    245 
    246   curl_global_cleanup();
    247   return res;
    248 }