Git init
[external/curl.git] / tests / libtest / lib506.c
1 /*****************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  */
9
10 #include "test.h"
11 #include <stdlib.h>
12 #include <ctype.h>
13 #include <errno.h>
14
15 #include <curl/mprintf.h>
16
17 #include "memdebug.h"
18
19 static const char *HOSTHEADER = "Host: www.host.foo.com";
20 static const char *JAR = "log/jar506";
21 #define THREADS 2
22
23 /* struct containing data of a thread */
24 struct Tdata {
25   CURLSH *share;
26   char *url;
27 };
28
29 struct userdata {
30   char *text;
31   int counter;
32 };
33
34 /* lock callback */
35 static void my_lock(CURL *handle, curl_lock_data data, curl_lock_access laccess,
36           void *useptr )
37 {
38   const char *what;
39   struct userdata *user = (struct userdata *)useptr;
40
41   (void)handle;
42   (void)laccess;
43
44   switch ( data ) {
45     case CURL_LOCK_DATA_SHARE:
46       what = "share";
47       break;
48     case CURL_LOCK_DATA_DNS:
49       what = "dns";
50       break;
51     case CURL_LOCK_DATA_COOKIE:
52       what = "cookie";
53       break;
54     default:
55       fprintf(stderr, "lock: no such data: %d\n", (int)data);
56       return;
57   }
58   printf("lock:   %-6s [%s]: %d\n", what, user->text, user->counter);
59   user->counter++;
60 }
61
62 /* unlock callback */
63 static void my_unlock(CURL *handle, curl_lock_data data, void *useptr )
64 {
65   const char *what;
66   struct userdata *user = (struct userdata *)useptr;
67   (void)handle;
68   switch ( data ) {
69     case CURL_LOCK_DATA_SHARE:
70       what = "share";
71       break;
72     case CURL_LOCK_DATA_DNS:
73       what = "dns";
74       break;
75     case CURL_LOCK_DATA_COOKIE:
76       what = "cookie";
77       break;
78     default:
79       fprintf(stderr, "unlock: no such data: %d\n", (int)data);
80       return;
81   }
82   printf("unlock: %-6s [%s]: %d\n", what, user->text, user->counter);
83   user->counter++;
84 }
85
86
87 /* build host entry */
88 static struct curl_slist *sethost(struct curl_slist *headers)
89 {
90   (void)headers;
91   return curl_slist_append(NULL, HOSTHEADER );
92 }
93
94
95 /* the dummy thread function */
96 static void *fire(void *ptr)
97 {
98   CURLcode code;
99   struct curl_slist *headers;
100   struct Tdata *tdata = (struct Tdata*)ptr;
101   CURL *curl;
102   int i=0;
103
104   if ((curl = curl_easy_init()) == NULL) {
105     fprintf(stderr, "curl_easy_init() failed\n");
106     return NULL;
107   }
108
109   headers = sethost(NULL);
110   curl_easy_setopt(curl, CURLOPT_VERBOSE,    1L);
111   curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
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   curl_slist_free_all(headers);
126
127   return NULL;
128 }
129
130
131 /* build request url */
132 static char *suburl(const char *base, int i)
133 {
134   return curl_maprintf("%s%.4d", base, i);
135 }
136
137
138 /* test function */
139 int test(char *URL)
140 {
141   int res;
142   CURLSHcode scode = CURLSHE_OK;
143   char *url;
144   struct Tdata tdata;
145   CURL *curl;
146   CURLSH *share;
147   struct curl_slist *headers;
148   int i;
149   struct userdata user;
150
151   user.text = (char *)"Pigs in space";
152   user.counter = 0;
153
154   printf( "GLOBAL_INIT\n" );
155   if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
156     fprintf(stderr, "curl_global_init() failed\n");
157     return TEST_ERR_MAJOR_BAD;
158   }
159
160   /* prepare share */
161   printf( "SHARE_INIT\n" );
162   if ((share = curl_share_init()) == NULL) {
163     fprintf(stderr, "curl_share_init() failed\n");
164     curl_global_cleanup();
165     return TEST_ERR_MAJOR_BAD;
166   }
167
168   if ( CURLSHE_OK == scode ) {
169     printf( "CURLSHOPT_LOCKFUNC\n" );
170     scode = curl_share_setopt( share, CURLSHOPT_LOCKFUNC, my_lock);
171   }
172   if ( CURLSHE_OK == scode ) {
173     printf( "CURLSHOPT_UNLOCKFUNC\n" );
174     scode = curl_share_setopt( share, CURLSHOPT_UNLOCKFUNC, my_unlock);
175   }
176   if ( CURLSHE_OK == scode ) {
177     printf( "CURLSHOPT_USERDATA\n" );
178     scode = curl_share_setopt( share, CURLSHOPT_USERDATA, &user);
179   }
180   if ( CURLSHE_OK == scode ) {
181     printf( "CURL_LOCK_DATA_COOKIE\n" );
182     scode = curl_share_setopt( share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
183   }
184   if ( CURLSHE_OK == scode ) {
185     printf( "CURL_LOCK_DATA_DNS\n" );
186     scode = curl_share_setopt( share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
187   }
188
189   if ( CURLSHE_OK != scode ) {
190     fprintf(stderr, "curl_share_setopt() failed\n");
191     curl_share_cleanup(share);
192     curl_global_cleanup();
193     return TEST_ERR_MAJOR_BAD;
194   }
195
196
197   res = 0;
198
199   /* start treads */
200   for (i=1; i<=THREADS; i++ ) {
201
202     /* set thread data */
203     tdata.url   = suburl( URL, i ); /* must be curl_free()d */
204     tdata.share = share;
205
206     /* simulate thread, direct call of "thread" function */
207     printf( "*** run %d\n",i );
208     fire( &tdata );
209
210     curl_free( tdata.url );
211
212   }
213
214
215   /* fetch a another one and save cookies */
216   printf( "*** run %d\n", i );
217   if ((curl = curl_easy_init()) == NULL) {
218     fprintf(stderr, "curl_easy_init() failed\n");
219     curl_share_cleanup(share);
220     curl_global_cleanup();
221     return TEST_ERR_MAJOR_BAD;
222   }
223
224   url = suburl( URL, i );
225   headers = sethost( NULL );
226   test_setopt( curl, CURLOPT_HTTPHEADER, headers );
227   test_setopt( curl, CURLOPT_URL,        url );
228   printf( "CURLOPT_SHARE\n" );
229   test_setopt( curl, CURLOPT_SHARE,      share );
230   printf( "CURLOPT_COOKIEJAR\n" );
231   test_setopt( curl, CURLOPT_COOKIEJAR,  JAR );
232
233   printf( "PERFORM\n" );
234   curl_easy_perform( curl );
235
236   /* try to free share, expect to fail because share is in use*/
237   printf( "try SHARE_CLEANUP...\n" );
238   scode = curl_share_cleanup( share );
239   if ( scode==CURLSHE_OK )
240   {
241     fprintf(stderr, "curl_share_cleanup succeed but error expected\n");
242     share = NULL;
243   } else {
244     printf( "SHARE_CLEANUP failed, correct\n" );
245   }
246
247 test_cleanup:
248
249   /* clean up last handle */
250   printf( "CLEANUP\n" );
251   curl_easy_cleanup( curl );
252   curl_slist_free_all( headers );
253
254   curl_free(url);
255
256   /* free share */
257   printf( "SHARE_CLEANUP\n" );
258   scode = curl_share_cleanup( share );
259   if ( scode!=CURLSHE_OK )
260     fprintf(stderr, "curl_share_cleanup failed, code errno %d\n",
261             (int)scode);
262
263   printf( "GLOBAL_CLEANUP\n" );
264   curl_global_cleanup();
265
266   return res;
267 }
268