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