File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / tests / libtest / lib506.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:16 2020 UTC (5 years ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    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>