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