00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "test.h"
00023 #include "memdebug.h"
00024
00025 static const char *HOSTHEADER = "Host: www.host.foo.com";
00026 static const char *JAR = "log/jar506";
00027 #define THREADS 2
00028
00029
00030 struct Tdata {
00031 CURLSH *share;
00032 char *url;
00033 };
00034
00035 struct userdata {
00036 char *text;
00037 int counter;
00038 };
00039
00040 int lock[3];
00041
00042
00043 static void my_lock(CURL *handle, curl_lock_data data,
00044 curl_lock_access laccess, void *useptr)
00045 {
00046 const char *what;
00047 struct userdata *user = (struct userdata *)useptr;
00048 int locknum;
00049
00050 (void)handle;
00051 (void)laccess;
00052
00053 switch(data) {
00054 case CURL_LOCK_DATA_SHARE:
00055 what = "share";
00056 locknum = 0;
00057 break;
00058 case CURL_LOCK_DATA_DNS:
00059 what = "dns";
00060 locknum = 1;
00061 break;
00062 case CURL_LOCK_DATA_COOKIE:
00063 what = "cookie";
00064 locknum = 2;
00065 break;
00066 default:
00067 fprintf(stderr, "lock: no such data: %d\n", (int)data);
00068 return;
00069 }
00070
00071
00072 if(lock[locknum]) {
00073 printf("lock: double locked %s\n", what);
00074 return;
00075 }
00076 lock[locknum]++;
00077
00078 printf("lock: %-6s [%s]: %d\n", what, user->text, user->counter);
00079 user->counter++;
00080 }
00081
00082
00083 static void my_unlock(CURL *handle, curl_lock_data data, void *useptr)
00084 {
00085 const char *what;
00086 struct userdata *user = (struct userdata *)useptr;
00087 int locknum;
00088 (void)handle;
00089 switch(data) {
00090 case CURL_LOCK_DATA_SHARE:
00091 what = "share";
00092 locknum = 0;
00093 break;
00094 case CURL_LOCK_DATA_DNS:
00095 what = "dns";
00096 locknum = 1;
00097 break;
00098 case CURL_LOCK_DATA_COOKIE:
00099 what = "cookie";
00100 locknum = 2;
00101 break;
00102 default:
00103 fprintf(stderr, "unlock: no such data: %d\n", (int)data);
00104 return;
00105 }
00106
00107
00108 if(!lock[locknum]) {
00109 printf("unlock: double unlocked %s\n", what);
00110 return;
00111 }
00112 lock[locknum]--;
00113
00114 printf("unlock: %-6s [%s]: %d\n", what, user->text, user->counter);
00115 user->counter++;
00116 }
00117
00118
00119
00120 static struct curl_slist *sethost(struct curl_slist *headers)
00121 {
00122 (void)headers;
00123 return curl_slist_append(NULL, HOSTHEADER);
00124 }
00125
00126
00127
00128 static void *fire(void *ptr)
00129 {
00130 CURLcode code;
00131 struct curl_slist *headers;
00132 struct Tdata *tdata = (struct Tdata*)ptr;
00133 CURL *curl;
00134 int i=0;
00135
00136 curl = curl_easy_init();
00137 if(!curl) {
00138 fprintf(stderr, "curl_easy_init() failed\n");
00139 return NULL;
00140 }
00141
00142 headers = sethost(NULL);
00143 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
00144 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
00145 curl_easy_setopt(curl, CURLOPT_URL, tdata->url);
00146 printf("CURLOPT_SHARE\n");
00147 curl_easy_setopt(curl, CURLOPT_SHARE, tdata->share);
00148
00149 printf("PERFORM\n");
00150 code = curl_easy_perform(curl);
00151 if(code) {
00152 fprintf(stderr, "perform url '%s' repeat %d failed, curlcode %d\n",
00153 tdata->url, i, (int)code);
00154 }
00155
00156 printf("CLEANUP\n");
00157 curl_easy_cleanup(curl);
00158 curl_slist_free_all(headers);
00159
00160 return NULL;
00161 }
00162
00163
00164
00165 static char *suburl(const char *base, int i)
00166 {
00167 return curl_maprintf("%s%.4d", base, i);
00168 }
00169
00170
00171
00172 int test(char *URL)
00173 {
00174 int res;
00175 CURLSHcode scode = CURLSHE_OK;
00176 CURLcode code = CURLE_OK;
00177 char *url = NULL;
00178 struct Tdata tdata;
00179 CURL *curl;
00180 CURLSH *share;
00181 struct curl_slist *headers = NULL;
00182 struct curl_slist *cookies = NULL;
00183 struct curl_slist *next_cookie = NULL;
00184 int i;
00185 struct userdata user;
00186
00187 user.text = (char *)"Pigs in space";
00188 user.counter = 0;
00189
00190 printf("GLOBAL_INIT\n");
00191 if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
00192 fprintf(stderr, "curl_global_init() failed\n");
00193 return TEST_ERR_MAJOR_BAD;
00194 }
00195
00196
00197 printf("SHARE_INIT\n");
00198 share = curl_share_init();
00199 if(!share) {
00200 fprintf(stderr, "curl_share_init() failed\n");
00201 curl_global_cleanup();
00202 return TEST_ERR_MAJOR_BAD;
00203 }
00204
00205 if(CURLSHE_OK == scode) {
00206 printf("CURLSHOPT_LOCKFUNC\n");
00207 scode = curl_share_setopt(share, CURLSHOPT_LOCKFUNC, my_lock);
00208 }
00209 if(CURLSHE_OK == scode) {
00210 printf("CURLSHOPT_UNLOCKFUNC\n");
00211 scode = curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, my_unlock);
00212 }
00213 if(CURLSHE_OK == scode) {
00214 printf("CURLSHOPT_USERDATA\n");
00215 scode = curl_share_setopt(share, CURLSHOPT_USERDATA, &user);
00216 }
00217 if(CURLSHE_OK == scode) {
00218 printf("CURL_LOCK_DATA_COOKIE\n");
00219 scode = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
00220 }
00221 if(CURLSHE_OK == scode) {
00222 printf("CURL_LOCK_DATA_DNS\n");
00223 scode = curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
00224 }
00225
00226 if(CURLSHE_OK != scode) {
00227 fprintf(stderr, "curl_share_setopt() failed\n");
00228 curl_share_cleanup(share);
00229 curl_global_cleanup();
00230 return TEST_ERR_MAJOR_BAD;
00231 }
00232
00233
00234 curl = curl_easy_init();
00235 if(!curl) {
00236 fprintf(stderr, "curl_easy_init() failed\n");
00237 curl_share_cleanup(share);
00238 curl_global_cleanup();
00239 return TEST_ERR_MAJOR_BAD;
00240 }
00241 printf("CURLOPT_SHARE\n");
00242 test_setopt(curl, CURLOPT_SHARE, share);
00243 printf("CURLOPT_COOKIELIST injected_and_clobbered\n");
00244 test_setopt(curl, CURLOPT_COOKIELIST,
00245 "Set-Cookie: injected_and_clobbered=yes; "
00246 "domain=host.foo.com; expires=Sat Feb 2 11:56:27 GMT 2030");
00247 printf("CURLOPT_COOKIELIST ALL\n");
00248 test_setopt(curl, CURLOPT_COOKIELIST, "ALL");
00249 printf("CURLOPT_COOKIELIST session\n");
00250 test_setopt(curl, CURLOPT_COOKIELIST, "Set-Cookie: session=elephants");
00251 printf("CURLOPT_COOKIELIST injected\n");
00252 test_setopt(curl, CURLOPT_COOKIELIST,
00253 "Set-Cookie: injected=yes; domain=host.foo.com; "
00254 "expires=Sat Feb 2 11:56:27 GMT 2030");
00255 printf("CURLOPT_COOKIELIST SESS\n");
00256 test_setopt(curl, CURLOPT_COOKIELIST, "SESS");
00257 printf("CLEANUP\n");
00258 curl_easy_cleanup(curl);
00259
00260
00261 res = 0;
00262
00263
00264 for(i=1; i<=THREADS; i++) {
00265
00266
00267 tdata.url = suburl(URL, i);
00268 tdata.share = share;
00269
00270
00271 printf("*** run %d\n",i);
00272 fire(&tdata);
00273
00274 curl_free(tdata.url);
00275 }
00276
00277
00278
00279 printf("*** run %d\n", i);
00280 curl = curl_easy_init();
00281 if(!curl) {
00282 fprintf(stderr, "curl_easy_init() failed\n");
00283 curl_share_cleanup(share);
00284 curl_global_cleanup();
00285 return TEST_ERR_MAJOR_BAD;
00286 }
00287
00288 url = suburl(URL, i);
00289 headers = sethost(NULL);
00290 test_setopt(curl, CURLOPT_HTTPHEADER, headers);
00291 test_setopt(curl, CURLOPT_URL, url);
00292 printf("CURLOPT_SHARE\n");
00293 test_setopt(curl, CURLOPT_SHARE, share);
00294 printf("CURLOPT_COOKIEJAR\n");
00295 test_setopt(curl, CURLOPT_COOKIEJAR, JAR);
00296 printf("CURLOPT_COOKIELIST FLUSH\n");
00297 test_setopt(curl, CURLOPT_COOKIELIST, "FLUSH");
00298
00299 printf("PERFORM\n");
00300 curl_easy_perform(curl);
00301
00302 printf("CLEANUP\n");
00303 curl_easy_cleanup(curl);
00304 curl_free(url);
00305 curl_slist_free_all(headers);
00306
00307
00308 curl = curl_easy_init();
00309 if(!curl) {
00310 fprintf(stderr, "curl_easy_init() failed\n");
00311 curl_share_cleanup(share);
00312 curl_global_cleanup();
00313 return TEST_ERR_MAJOR_BAD;
00314 }
00315 url = suburl(URL, i);
00316 headers = sethost(NULL);
00317 test_setopt(curl, CURLOPT_HTTPHEADER, headers);
00318 test_setopt(curl, CURLOPT_URL, url);
00319 printf("CURLOPT_SHARE\n");
00320 test_setopt(curl, CURLOPT_SHARE, share);
00321 printf("CURLOPT_COOKIELIST ALL\n");
00322 test_setopt(curl, CURLOPT_COOKIELIST, "ALL");
00323 printf("CURLOPT_COOKIEJAR\n");
00324 test_setopt(curl, CURLOPT_COOKIEFILE, JAR);
00325 printf("CURLOPT_COOKIELIST RELOAD\n");
00326 test_setopt(curl, CURLOPT_COOKIELIST, "RELOAD");
00327
00328 code = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
00329 if(code != CURLE_OK) {
00330 fprintf(stderr, "curl_easy_getinfo() failed\n");
00331 res = TEST_ERR_MAJOR_BAD;
00332 goto test_cleanup;
00333 }
00334 printf("loaded cookies:\n");
00335 if(!cookies) {
00336 fprintf(stderr, " reloading cookies from '%s' failed\n", JAR);
00337 res = TEST_ERR_MAJOR_BAD;
00338 goto test_cleanup;
00339 }
00340 printf("-----------------\n");
00341 next_cookie = cookies;
00342 while(next_cookie) {
00343 printf(" %s\n", next_cookie->data);
00344 next_cookie = next_cookie->next;
00345 }
00346 printf("-----------------\n");
00347 curl_slist_free_all(cookies);
00348
00349
00350 printf("try SHARE_CLEANUP...\n");
00351 scode = curl_share_cleanup(share);
00352 if(scode==CURLSHE_OK) {
00353 fprintf(stderr, "curl_share_cleanup succeed but error expected\n");
00354 share = NULL;
00355 }
00356 else {
00357 printf("SHARE_CLEANUP failed, correct\n");
00358 }
00359
00360 test_cleanup:
00361
00362
00363 printf("CLEANUP\n");
00364 curl_easy_cleanup(curl);
00365 curl_slist_free_all(headers);
00366 curl_free(url);
00367
00368
00369 printf("SHARE_CLEANUP\n");
00370 scode = curl_share_cleanup(share);
00371 if(scode!=CURLSHE_OK)
00372 fprintf(stderr, "curl_share_cleanup failed, code errno %d\n",
00373 (int)scode);
00374
00375 printf("GLOBAL_CLEANUP\n");
00376 curl_global_cleanup();
00377
00378 return res;
00379 }
00380