quickjs-tart

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

lib506.c (10435B)


      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 "testutil.h"
     27 #include "memdebug.h"
     28 
     29 #define JAR libtest_arg2
     30 #define THREADS 2
     31 
     32 /* struct containing data of a thread */
     33 struct t506_Tdata {
     34   CURLSH *share;
     35   char *url;
     36 };
     37 
     38 struct t506_userdata {
     39   const char *text;
     40   int counter;
     41 };
     42 
     43 static int locks[3];
     44 
     45 /* lock callback */
     46 static void t506_test_lock(CURL *handle, curl_lock_data data,
     47                            curl_lock_access laccess, void *useptr)
     48 {
     49   const char *what;
     50   struct t506_userdata *user = (struct t506_userdata *)useptr;
     51   int locknum;
     52 
     53   (void)handle;
     54   (void)laccess;
     55 
     56   switch(data) {
     57     case CURL_LOCK_DATA_SHARE:
     58       what = "share";
     59       locknum = 0;
     60       break;
     61     case CURL_LOCK_DATA_DNS:
     62       what = "dns";
     63       locknum = 1;
     64       break;
     65     case CURL_LOCK_DATA_COOKIE:
     66       what = "cookie";
     67       locknum = 2;
     68       break;
     69     default:
     70       curl_mfprintf(stderr, "lock: no such data: %d\n", (int)data);
     71       return;
     72   }
     73 
     74   /* detect locking of locked locks */
     75   if(locks[locknum]) {
     76     curl_mprintf("lock: double locked %s\n", what);
     77     return;
     78   }
     79   locks[locknum]++;
     80 
     81   curl_mprintf("lock:   %-6s [%s]: %d\n", what, user->text, user->counter);
     82   user->counter++;
     83 }
     84 
     85 /* unlock callback */
     86 static void t506_test_unlock(CURL *handle, curl_lock_data data, void *useptr)
     87 {
     88   const char *what;
     89   struct t506_userdata *user = (struct t506_userdata *)useptr;
     90   int locknum;
     91   (void)handle;
     92   switch(data) {
     93     case CURL_LOCK_DATA_SHARE:
     94       what = "share";
     95       locknum = 0;
     96       break;
     97     case CURL_LOCK_DATA_DNS:
     98       what = "dns";
     99       locknum = 1;
    100       break;
    101     case CURL_LOCK_DATA_COOKIE:
    102       what = "cookie";
    103       locknum = 2;
    104       break;
    105     default:
    106       curl_mfprintf(stderr, "unlock: no such data: %d\n", (int)data);
    107       return;
    108   }
    109 
    110   /* detect unlocking of unlocked locks */
    111   if(!locks[locknum]) {
    112     curl_mprintf("unlock: double unlocked %s\n", what);
    113     return;
    114   }
    115   locks[locknum]--;
    116 
    117   curl_mprintf("unlock: %-6s [%s]: %d\n", what, user->text, user->counter);
    118   user->counter++;
    119 }
    120 
    121 /* build host entry */
    122 static struct curl_slist *sethost(struct curl_slist *headers)
    123 {
    124   (void)headers;
    125   return curl_slist_append(NULL, "Host: www.host.foo.com");
    126 }
    127 
    128 /* the dummy thread function */
    129 static void *t506_test_fire(void *ptr)
    130 {
    131   CURLcode code;
    132   struct curl_slist *headers;
    133   struct t506_Tdata *tdata = (struct t506_Tdata*)ptr;
    134   CURL *curl;
    135 
    136   curl = curl_easy_init();
    137   if(!curl) {
    138     curl_mfprintf(stderr, "curl_easy_init() failed\n");
    139     return NULL;
    140   }
    141 
    142   headers = sethost(NULL);
    143   curl_easy_setopt(curl, CURLOPT_VERBOSE,    1L);
    144   curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    145   curl_easy_setopt(curl, CURLOPT_URL,        tdata->url);
    146   curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
    147   curl_mprintf("CURLOPT_SHARE\n");
    148   curl_easy_setopt(curl, CURLOPT_SHARE, tdata->share);
    149 
    150   curl_mprintf("PERFORM\n");
    151   code = curl_easy_perform(curl);
    152   if(code) {
    153     int i = 0;
    154     curl_mfprintf(stderr, "perform url '%s' repeat %d failed, curlcode %d\n",
    155                   tdata->url, i, (int)code);
    156   }
    157 
    158   curl_mprintf("CLEANUP\n");
    159   curl_easy_cleanup(curl);
    160   curl_slist_free_all(headers);
    161 
    162   return NULL;
    163 }
    164 
    165 /* test function */
    166 static CURLcode test_lib506(char *URL)
    167 {
    168   CURLcode res;
    169   CURLSHcode scode = CURLSHE_OK;
    170   CURLcode code = CURLE_OK;
    171   char *url = NULL;
    172   struct t506_Tdata tdata;
    173   CURL *curl;
    174   CURLSH *share;
    175   struct curl_slist *headers = NULL;
    176   struct curl_slist *cookies = NULL;
    177   struct curl_slist *next_cookie = NULL;
    178   int i;
    179   struct t506_userdata user;
    180 
    181   user.text = "Pigs in space";
    182   user.counter = 0;
    183 
    184   curl_mprintf("GLOBAL_INIT\n");
    185   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    186     curl_mfprintf(stderr, "curl_global_init() failed\n");
    187     return TEST_ERR_MAJOR_BAD;
    188   }
    189 
    190   /* prepare share */
    191   curl_mprintf("SHARE_INIT\n");
    192   share = curl_share_init();
    193   if(!share) {
    194     curl_mfprintf(stderr, "curl_share_init() failed\n");
    195     curl_global_cleanup();
    196     return TEST_ERR_MAJOR_BAD;
    197   }
    198 
    199   if(CURLSHE_OK == scode) {
    200     curl_mprintf("CURLSHOPT_LOCKFUNC\n");
    201     scode = curl_share_setopt(share, CURLSHOPT_LOCKFUNC, t506_test_lock);
    202   }
    203   if(CURLSHE_OK == scode) {
    204     curl_mprintf("CURLSHOPT_UNLOCKFUNC\n");
    205     scode = curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, t506_test_unlock);
    206   }
    207   if(CURLSHE_OK == scode) {
    208     curl_mprintf("CURLSHOPT_USERDATA\n");
    209     scode = curl_share_setopt(share, CURLSHOPT_USERDATA, &user);
    210   }
    211   if(CURLSHE_OK == scode) {
    212     curl_mprintf("CURL_LOCK_DATA_COOKIE\n");
    213     scode = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
    214   }
    215   if(CURLSHE_OK == scode) {
    216     curl_mprintf("CURL_LOCK_DATA_DNS\n");
    217     scode = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
    218   }
    219 
    220   if(CURLSHE_OK != scode) {
    221     curl_mfprintf(stderr, "curl_share_setopt() failed\n");
    222     curl_share_cleanup(share);
    223     curl_global_cleanup();
    224     return TEST_ERR_MAJOR_BAD;
    225   }
    226 
    227   /* initial cookie manipulation */
    228   curl = curl_easy_init();
    229   if(!curl) {
    230     curl_mfprintf(stderr, "curl_easy_init() failed\n");
    231     curl_share_cleanup(share);
    232     curl_global_cleanup();
    233     return TEST_ERR_MAJOR_BAD;
    234   }
    235   curl_mprintf("CURLOPT_SHARE\n");
    236   test_setopt(curl, CURLOPT_SHARE,      share);
    237   curl_mprintf("CURLOPT_COOKIELIST injected_and_clobbered\n");
    238   test_setopt(curl, CURLOPT_COOKIELIST,
    239                "Set-Cookie: injected_and_clobbered=yes; "
    240                "domain=host.foo.com; expires=Sat Feb 2 11:56:27 GMT 2030");
    241   curl_mprintf("CURLOPT_COOKIELIST ALL\n");
    242   test_setopt(curl, CURLOPT_COOKIELIST, "ALL");
    243   curl_mprintf("CURLOPT_COOKIELIST session\n");
    244   test_setopt(curl, CURLOPT_COOKIELIST, "Set-Cookie: session=elephants");
    245   curl_mprintf("CURLOPT_COOKIELIST injected\n");
    246   test_setopt(curl, CURLOPT_COOKIELIST,
    247                "Set-Cookie: injected=yes; domain=host.foo.com; "
    248                "expires=Sat Feb 2 11:56:27 GMT 2030");
    249   curl_mprintf("CURLOPT_COOKIELIST SESS\n");
    250   test_setopt(curl, CURLOPT_COOKIELIST, "SESS");
    251   curl_mprintf("CLEANUP\n");
    252   curl_easy_cleanup(curl);
    253 
    254 
    255   /* start treads */
    256   for(i = 1; i <= THREADS; i++) {
    257 
    258     /* set thread data */
    259     tdata.url   = tutil_suburl(URL, i); /* must be curl_free()d */
    260     tdata.share = share;
    261 
    262     /* simulate thread, direct call of "thread" function */
    263     curl_mprintf("*** run %d\n",i);
    264     t506_test_fire(&tdata);
    265 
    266     curl_free(tdata.url);
    267   }
    268 
    269 
    270   /* fetch another one and save cookies */
    271   curl_mprintf("*** run %d\n", i);
    272   curl = curl_easy_init();
    273   if(!curl) {
    274     curl_mfprintf(stderr, "curl_easy_init() failed\n");
    275     curl_share_cleanup(share);
    276     curl_global_cleanup();
    277     return TEST_ERR_MAJOR_BAD;
    278   }
    279 
    280   url = tutil_suburl(URL, i);
    281   headers = sethost(NULL);
    282   test_setopt(curl, CURLOPT_HTTPHEADER, headers);
    283   test_setopt(curl, CURLOPT_URL,        url);
    284   curl_mprintf("CURLOPT_SHARE\n");
    285   test_setopt(curl, CURLOPT_SHARE,      share);
    286   curl_mprintf("CURLOPT_COOKIEJAR\n");
    287   test_setopt(curl, CURLOPT_COOKIEJAR,  JAR);
    288   curl_mprintf("CURLOPT_COOKIELIST FLUSH\n");
    289   test_setopt(curl, CURLOPT_COOKIELIST, "FLUSH");
    290 
    291   curl_mprintf("PERFORM\n");
    292   curl_easy_perform(curl);
    293 
    294   curl_mprintf("CLEANUP\n");
    295   curl_easy_cleanup(curl);
    296   curl_free(url);
    297   curl_slist_free_all(headers);
    298 
    299   /* load cookies */
    300   curl = curl_easy_init();
    301   if(!curl) {
    302     curl_mfprintf(stderr, "curl_easy_init() failed\n");
    303     curl_share_cleanup(share);
    304     curl_global_cleanup();
    305     return TEST_ERR_MAJOR_BAD;
    306   }
    307   url = tutil_suburl(URL, i);
    308   headers = sethost(NULL);
    309   test_setopt(curl, CURLOPT_HTTPHEADER, headers);
    310   test_setopt(curl, CURLOPT_URL,        url);
    311   curl_mprintf("CURLOPT_SHARE\n");
    312   test_setopt(curl, CURLOPT_SHARE,      share);
    313   curl_mprintf("CURLOPT_COOKIELIST ALL\n");
    314   test_setopt(curl, CURLOPT_COOKIELIST, "ALL");
    315   curl_mprintf("CURLOPT_COOKIEJAR\n");
    316   test_setopt(curl, CURLOPT_COOKIEFILE, JAR);
    317   curl_mprintf("CURLOPT_COOKIELIST RELOAD\n");
    318   test_setopt(curl, CURLOPT_COOKIELIST, "RELOAD");
    319 
    320   res = CURLE_OK;
    321 
    322   code = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
    323   if(code != CURLE_OK) {
    324     curl_mfprintf(stderr, "curl_easy_getinfo() failed\n");
    325     res = TEST_ERR_MAJOR_BAD;
    326     goto test_cleanup;
    327   }
    328   curl_mprintf("loaded cookies:\n");
    329   if(!cookies) {
    330     curl_mfprintf(stderr, "  reloading cookies from '%s' failed\n", JAR);
    331     res = TEST_ERR_MAJOR_BAD;
    332     goto test_cleanup;
    333   }
    334   curl_mprintf("-----------------\n");
    335   next_cookie = cookies;
    336   while(next_cookie) {
    337     curl_mprintf("  %s\n", next_cookie->data);
    338     next_cookie = next_cookie->next;
    339   }
    340   curl_mprintf("-----------------\n");
    341   curl_slist_free_all(cookies);
    342 
    343   /* try to free share, expect to fail because share is in use */
    344   curl_mprintf("try SHARE_CLEANUP...\n");
    345   scode = curl_share_cleanup(share);
    346   if(scode == CURLSHE_OK) {
    347     curl_mfprintf(stderr, "curl_share_cleanup succeed but error expected\n");
    348     share = NULL;
    349   }
    350   else {
    351     curl_mprintf("SHARE_CLEANUP failed, correct\n");
    352   }
    353 
    354 test_cleanup:
    355 
    356   /* clean up last handle */
    357   curl_mprintf("CLEANUP\n");
    358   curl_easy_cleanup(curl);
    359   curl_slist_free_all(headers);
    360   curl_free(url);
    361 
    362   /* free share */
    363   curl_mprintf("SHARE_CLEANUP\n");
    364   scode = curl_share_cleanup(share);
    365   if(scode != CURLSHE_OK)
    366     curl_mfprintf(stderr, "curl_share_cleanup failed, code errno %d\n",
    367                   (int)scode);
    368 
    369   curl_mprintf("GLOBAL_CLEANUP\n");
    370   curl_global_cleanup();
    371 
    372   return res;
    373 }