Annotation of embedaddon/curl/tests/libtest/lib506.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>