Home | History | Annotate | Download | only in libtest
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel (at) 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.haxx.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  ***************************************************************************/
     22 #include "test.h"
     23 #include "memdebug.h"
     24 
     25 #define THREADS 2
     26 
     27 /* struct containing data of a thread */
     28 struct Tdata {
     29   CURLSH *share;
     30   char *url;
     31 };
     32 
     33 struct userdata {
     34   const char *text;
     35   int counter;
     36 };
     37 
     38 /* lock callback */
     39 static void my_lock(CURL *handle, curl_lock_data data,
     40                     curl_lock_access laccess, void *useptr)
     41 {
     42   const char *what;
     43   struct userdata *user = (struct userdata *)useptr;
     44 
     45   (void)handle;
     46   (void)laccess;
     47 
     48   switch(data) {
     49     case CURL_LOCK_DATA_SHARE:
     50       what = "share";
     51       break;
     52     case CURL_LOCK_DATA_DNS:
     53       what = "dns";
     54       break;
     55     case CURL_LOCK_DATA_COOKIE:
     56       what = "cookie";
     57       break;
     58     case CURL_LOCK_DATA_SSL_SESSION:
     59       what = "ssl_session";
     60       break;
     61     default:
     62       fprintf(stderr, "lock: no such data: %d\n", (int)data);
     63       return;
     64   }
     65   printf("lock:   %-6s [%s]: %d\n", what, user->text, user->counter);
     66   user->counter++;
     67 }
     68 
     69 /* unlock callback */
     70 static void my_unlock(CURL *handle, curl_lock_data data, void *useptr)
     71 {
     72   const char *what;
     73   struct userdata *user = (struct userdata *)useptr;
     74   (void)handle;
     75   switch(data) {
     76     case CURL_LOCK_DATA_SHARE:
     77       what = "share";
     78       break;
     79     case CURL_LOCK_DATA_DNS:
     80       what = "dns";
     81       break;
     82     case CURL_LOCK_DATA_COOKIE:
     83       what = "cookie";
     84       break;
     85     case CURL_LOCK_DATA_SSL_SESSION:
     86       what = "ssl_session";
     87       break;
     88     default:
     89       fprintf(stderr, "unlock: no such data: %d\n", (int)data);
     90       return;
     91   }
     92   printf("unlock: %-6s [%s]: %d\n", what, user->text, user->counter);
     93   user->counter++;
     94 }
     95 
     96 /* the dummy thread function */
     97 static void *fire(void *ptr)
     98 {
     99   CURLcode code;
    100   struct Tdata *tdata = (struct Tdata*)ptr;
    101   CURL *curl;
    102   int i = 0;
    103 
    104   curl = curl_easy_init();
    105   if(!curl) {
    106     fprintf(stderr, "curl_easy_init() failed\n");
    107     return NULL;
    108   }
    109 
    110   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
    111   curl_easy_setopt(curl, CURLOPT_VERBOSE,    1L);
    112   curl_easy_setopt(curl, CURLOPT_URL,        tdata->url);
    113   printf("CURLOPT_SHARE\n");
    114   curl_easy_setopt(curl, CURLOPT_SHARE, tdata->share);
    115 
    116   printf("PERFORM\n");
    117   code = curl_easy_perform(curl);
    118   if(code != CURLE_OK) {
    119     fprintf(stderr, "perform url '%s' repeat %d failed, curlcode %d\n",
    120             tdata->url, i, (int)code);
    121   }
    122 
    123   printf("CLEANUP\n");
    124   curl_easy_cleanup(curl);
    125 
    126   return NULL;
    127 }
    128 
    129 /* test function */
    130 int test(char *URL)
    131 {
    132   int res;
    133   CURLSHcode scode = CURLSHE_OK;
    134   char *url;
    135   struct Tdata tdata;
    136   CURL *curl;
    137   CURLSH *share;
    138   int i;
    139   struct userdata user;
    140 
    141   user.text = "Pigs in space";
    142   user.counter = 0;
    143 
    144   printf("GLOBAL_INIT\n");
    145   if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
    146     fprintf(stderr, "curl_global_init() failed\n");
    147     return TEST_ERR_MAJOR_BAD;
    148   }
    149 
    150   /* prepare share */
    151   printf("SHARE_INIT\n");
    152   share = curl_share_init();
    153   if(!share) {
    154     fprintf(stderr, "curl_share_init() failed\n");
    155     curl_global_cleanup();
    156     return TEST_ERR_MAJOR_BAD;
    157   }
    158 
    159   if(CURLSHE_OK == scode) {
    160     printf("CURLSHOPT_LOCKFUNC\n");
    161     scode = curl_share_setopt(share, CURLSHOPT_LOCKFUNC, my_lock);
    162   }
    163   if(CURLSHE_OK == scode) {
    164     printf("CURLSHOPT_UNLOCKFUNC\n");
    165     scode = curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, my_unlock);
    166   }
    167   if(CURLSHE_OK == scode) {
    168     printf("CURLSHOPT_USERDATA\n");
    169     scode = curl_share_setopt(share, CURLSHOPT_USERDATA, &user);
    170   }
    171   if(CURLSHE_OK == scode) {
    172     printf("CURL_LOCK_DATA_SSL_SESSION\n");
    173     scode = curl_share_setopt(share, CURLSHOPT_SHARE,
    174                               CURL_LOCK_DATA_SSL_SESSION);
    175   }
    176 
    177   if(CURLSHE_OK != scode) {
    178     fprintf(stderr, "curl_share_setopt() failed\n");
    179     curl_share_cleanup(share);
    180     curl_global_cleanup();
    181     return TEST_ERR_MAJOR_BAD;
    182   }
    183 
    184 
    185   res = 0;
    186 
    187   /* start treads */
    188   for(i = 1; i <= THREADS; i++) {
    189 
    190     /* set thread data */
    191     tdata.url   = URL;
    192     tdata.share = share;
    193 
    194     /* simulate thread, direct call of "thread" function */
    195     printf("*** run %d\n",i);
    196     fire(&tdata);
    197   }
    198 
    199 
    200   /* fetch a another one */
    201   printf("*** run %d\n", i);
    202   curl = curl_easy_init();
    203   if(!curl) {
    204     fprintf(stderr, "curl_easy_init() failed\n");
    205     curl_share_cleanup(share);
    206     curl_global_cleanup();
    207     return TEST_ERR_MAJOR_BAD;
    208   }
    209 
    210   url = URL;
    211   test_setopt(curl, CURLOPT_URL, url);
    212   printf("CURLOPT_SHARE\n");
    213   test_setopt(curl, CURLOPT_SHARE, share);
    214 
    215   printf("PERFORM\n");
    216   curl_easy_perform(curl);
    217 
    218   /* try to free share, expect to fail because share is in use*/
    219   printf("try SHARE_CLEANUP...\n");
    220   scode = curl_share_cleanup(share);
    221   if(scode == CURLSHE_OK) {
    222     fprintf(stderr, "curl_share_cleanup succeed but error expected\n");
    223     share = NULL;
    224   }
    225   else {
    226     printf("SHARE_CLEANUP failed, correct\n");
    227   }
    228 
    229 test_cleanup:
    230 
    231   /* clean up last handle */
    232   printf("CLEANUP\n");
    233   curl_easy_cleanup(curl);
    234 
    235   /* free share */
    236   printf("SHARE_CLEANUP\n");
    237   scode = curl_share_cleanup(share);
    238   if(scode != CURLSHE_OK)
    239     fprintf(stderr, "curl_share_cleanup failed, code errno %d\n",
    240             (int)scode);
    241 
    242   printf("GLOBAL_CLEANUP\n");
    243   curl_global_cleanup();
    244 
    245   return res;
    246 }
    247 
    248