lib506.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2017, 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 {
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) {
55  what = "share";
56  locknum = 0;
57  break;
58  case CURL_LOCK_DATA_DNS:
59  what = "dns";
60  locknum = 1;
61  break;
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) {
91  what = "share";
92  locknum = 0;
93  break;
94  case CURL_LOCK_DATA_DNS:
95  what = "dns";
96  locknum = 1;
97  break;
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  int i = 0;
135 
136  curl = curl_easy_init();
137  if(!curl) {
138  fprintf(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  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  fprintf(stderr, "perform url '%s' repeat %d failed, curlcode %d\n",
153  tdata->url, i, (int)code);
154  }
155 
156  printf("CLEANUP\n");
157  curl_easy_cleanup(curl);
158  curl_slist_free_all(headers);
159 
160  return NULL;
161 }
162 
163 
164 /* build request url */
165 static char *suburl(const char *base, int i)
166 {
167  return curl_maprintf("%s%.4d", base, i);
168 }
169 
170 
171 /* test function */
172 int test(char *URL)
173 {
174  int res;
175  CURLSHcode scode = CURLSHE_OK;
176  CURLcode code = CURLE_OK;
177  char *url = NULL;
178  struct Tdata tdata;
179  CURL *curl;
180  CURLSH *share;
181  struct curl_slist *headers = NULL;
182  struct curl_slist *cookies = NULL;
183  struct curl_slist *next_cookie = NULL;
184  int i;
185  struct userdata user;
186 
187  user.text = "Pigs in space";
188  user.counter = 0;
189 
190  printf("GLOBAL_INIT\n");
192  fprintf(stderr, "curl_global_init() failed\n");
193  return TEST_ERR_MAJOR_BAD;
194  }
195 
196  /* prepare share */
197  printf("SHARE_INIT\n");
198  share = curl_share_init();
199  if(!share) {
200  fprintf(stderr, "curl_share_init() failed\n");
202  return TEST_ERR_MAJOR_BAD;
203  }
204 
205  if(CURLSHE_OK == scode) {
206  printf("CURLSHOPT_LOCKFUNC\n");
208  }
209  if(CURLSHE_OK == scode) {
210  printf("CURLSHOPT_UNLOCKFUNC\n");
212  }
213  if(CURLSHE_OK == scode) {
214  printf("CURLSHOPT_USERDATA\n");
215  scode = curl_share_setopt(share, CURLSHOPT_USERDATA, &user);
216  }
217  if(CURLSHE_OK == scode) {
218  printf("CURL_LOCK_DATA_COOKIE\n");
220  }
221  if(CURLSHE_OK == scode) {
222  printf("CURL_LOCK_DATA_DNS\n");
224  }
225 
226  if(CURLSHE_OK != scode) {
227  fprintf(stderr, "curl_share_setopt() failed\n");
228  curl_share_cleanup(share);
230  return TEST_ERR_MAJOR_BAD;
231  }
232 
233  /* initial cookie manipulation */
234  curl = curl_easy_init();
235  if(!curl) {
236  fprintf(stderr, "curl_easy_init() failed\n");
237  curl_share_cleanup(share);
239  return TEST_ERR_MAJOR_BAD;
240  }
241  printf("CURLOPT_SHARE\n");
242  test_setopt(curl, CURLOPT_SHARE, share);
243  printf("CURLOPT_COOKIELIST injected_and_clobbered\n");
244  test_setopt(curl, CURLOPT_COOKIELIST,
245  "Set-Cookie: injected_and_clobbered=yes; "
246  "domain=host.foo.com; expires=Sat Feb 2 11:56:27 GMT 2030");
247  printf("CURLOPT_COOKIELIST ALL\n");
248  test_setopt(curl, CURLOPT_COOKIELIST, "ALL");
249  printf("CURLOPT_COOKIELIST session\n");
250  test_setopt(curl, CURLOPT_COOKIELIST, "Set-Cookie: session=elephants");
251  printf("CURLOPT_COOKIELIST injected\n");
252  test_setopt(curl, CURLOPT_COOKIELIST,
253  "Set-Cookie: injected=yes; domain=host.foo.com; "
254  "expires=Sat Feb 2 11:56:27 GMT 2030");
255  printf("CURLOPT_COOKIELIST SESS\n");
256  test_setopt(curl, CURLOPT_COOKIELIST, "SESS");
257  printf("CLEANUP\n");
258  curl_easy_cleanup(curl);
259 
260 
261  res = 0;
262 
263  /* start treads */
264  for(i = 1; i <= THREADS; i++) {
265 
266  /* set thread data */
267  tdata.url = suburl(URL, i); /* must be curl_free()d */
268  tdata.share = share;
269 
270  /* simulate thread, direct call of "thread" function */
271  printf("*** run %d\n",i);
272  fire(&tdata);
273 
274  curl_free(tdata.url);
275  }
276 
277 
278  /* fetch a another one and save cookies */
279  printf("*** run %d\n", i);
280  curl = curl_easy_init();
281  if(!curl) {
282  fprintf(stderr, "curl_easy_init() failed\n");
283  curl_share_cleanup(share);
285  return TEST_ERR_MAJOR_BAD;
286  }
287 
288  url = suburl(URL, i);
289  headers = sethost(NULL);
290  test_setopt(curl, CURLOPT_HTTPHEADER, headers);
291  test_setopt(curl, CURLOPT_URL, url);
292  printf("CURLOPT_SHARE\n");
293  test_setopt(curl, CURLOPT_SHARE, share);
294  printf("CURLOPT_COOKIEJAR\n");
295  test_setopt(curl, CURLOPT_COOKIEJAR, JAR);
296  printf("CURLOPT_COOKIELIST FLUSH\n");
297  test_setopt(curl, CURLOPT_COOKIELIST, "FLUSH");
298 
299  printf("PERFORM\n");
300  curl_easy_perform(curl);
301 
302  printf("CLEANUP\n");
303  curl_easy_cleanup(curl);
304  curl_free(url);
305  curl_slist_free_all(headers);
306 
307  /* load cookies */
308  curl = curl_easy_init();
309  if(!curl) {
310  fprintf(stderr, "curl_easy_init() failed\n");
311  curl_share_cleanup(share);
313  return TEST_ERR_MAJOR_BAD;
314  }
315  url = suburl(URL, i);
316  headers = sethost(NULL);
317  test_setopt(curl, CURLOPT_HTTPHEADER, headers);
318  test_setopt(curl, CURLOPT_URL, url);
319  printf("CURLOPT_SHARE\n");
320  test_setopt(curl, CURLOPT_SHARE, share);
321  printf("CURLOPT_COOKIELIST ALL\n");
322  test_setopt(curl, CURLOPT_COOKIELIST, "ALL");
323  printf("CURLOPT_COOKIEJAR\n");
324  test_setopt(curl, CURLOPT_COOKIEFILE, JAR);
325  printf("CURLOPT_COOKIELIST RELOAD\n");
326  test_setopt(curl, CURLOPT_COOKIELIST, "RELOAD");
327 
328  code = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
329  if(code != CURLE_OK) {
330  fprintf(stderr, "curl_easy_getinfo() failed\n");
331  res = TEST_ERR_MAJOR_BAD;
332  goto test_cleanup;
333  }
334  printf("loaded cookies:\n");
335  if(!cookies) {
336  fprintf(stderr, " reloading cookies from '%s' failed\n", JAR);
337  res = TEST_ERR_MAJOR_BAD;
338  goto test_cleanup;
339  }
340  printf("-----------------\n");
341  next_cookie = cookies;
342  while(next_cookie) {
343  printf(" %s\n", next_cookie->data);
344  next_cookie = next_cookie->next;
345  }
346  printf("-----------------\n");
347  curl_slist_free_all(cookies);
348 
349  /* try to free share, expect to fail because share is in use*/
350  printf("try SHARE_CLEANUP...\n");
351  scode = curl_share_cleanup(share);
352  if(scode == CURLSHE_OK) {
353  fprintf(stderr, "curl_share_cleanup succeed but error expected\n");
354  share = NULL;
355  }
356  else {
357  printf("SHARE_CLEANUP failed, correct\n");
358  }
359 
360 test_cleanup:
361 
362  /* clean up last handle */
363  printf("CLEANUP\n");
364  curl_easy_cleanup(curl);
365  curl_slist_free_all(headers);
366  curl_free(url);
367 
368  /* free share */
369  printf("SHARE_CLEANUP\n");
370  scode = curl_share_cleanup(share);
371  if(scode != CURLSHE_OK)
372  fprintf(stderr, "curl_share_cleanup failed, code errno %d\n",
373  (int)scode);
374 
375  printf("GLOBAL_CLEANUP\n");
377 
378  return res;
379 }
380 
#define test_setopt(A, B, C)
Definition: test.h:47
auto base
CURL_EXTERN void curl_free(void *p)
Definition: escape.c:239
char * data
Definition: curl.h:2336
UNITTEST_START char * ptr
Definition: unit1330.c:38
CURLcode
Definition: curl.h:454
CURL_EXTERN CURLSH * curl_share_init(void)
Definition: share.c:35
Definition: lib506.c:30
static char * suburl(const char *base, int i)
Definition: lib506.c:165
static int res
const char * text
Definition: lib506.c:36
static struct curl_slist * sethost(struct curl_slist *headers)
Definition: lib506.c:120
CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *)
#define curl_easy_setopt(handle, option, value)
Definition: typecheck-gcc.h:41
unsigned int i
Definition: unit1303.c:79
#define THREADS
Definition: lib506.c:27
#define TEST_ERR_MAJOR_BAD
Definition: test.h:85
static const char * HOSTHEADER
Definition: lib506.c:25
#define curl_easy_getinfo(handle, info, arg)
static void my_lock(CURL *handle, curl_lock_data data, curl_lock_access laccess, void *useptr)
Definition: lib506.c:43
static void * fire(void *ptr)
Definition: lib506.c:128
struct curl_slist * next
Definition: curl.h:2337
CURL_EXTERN struct curl_slist * curl_slist_append(struct curl_slist *, const char *)
Definition: slist.c:89
CURLSHcode
Definition: curl.h:2561
#define printf
Definition: curl_printf.h:40
static int locks[3]
Definition: lib506.c:40
CURL_EXTERN CURL * curl_easy_init(void)
Definition: easy.c:343
CURL_EXTERN void curl_easy_cleanup(CURL *curl)
void CURLSH
Definition: curl.h:103
CURLSH * share
Definition: lib506.c:31
static const char * JAR
Definition: lib506.c:26
curl_lock_access
Definition: curl.h:2545
Definition: curl.h:455
int test(char *URL)
Definition: lib506.c:172
CURL_EXTERN CURLcode curl_global_init(long flags)
curl_global_init() globally initializes curl given a bitwise set of the different features of what to...
Definition: easy.c:271
void CURL
Definition: curl.h:102
int counter
Definition: lib506.c:37
curl_lock_data
Definition: curl.h:2530
#define fprintf
Definition: curl_printf.h:41
CURL_EXTERN void curl_global_cleanup(void)
curl_global_cleanup() globally cleanups curl, uses the value of "init_flags" to determine what needs ...
Definition: easy.c:312
#define CURL_GLOBAL_ALL
Definition: curl.h:2519
CURL_EXTERN char * curl_maprintf(const char *format,...)
Definition: mprintf.c:1066
#define curl_share_setopt(share, opt, param)
static CURL * curl
Definition: sessioninfo.c:35
CURL_EXTERN void curl_slist_free_all(struct curl_slist *)
Definition: slist.c:129
char * url
Definition: lib506.c:32
Definition: debug.c:29
CURL_EXTERN CURLcode curl_easy_perform(CURL *curl)
static void my_unlock(CURL *handle, curl_lock_data data, void *useptr)
Definition: lib506.c:83


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:15