Git init
[external/curl.git] / tests / libtest / lib503.c
1 /*****************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  */
9
10 #include "test.h"
11
12 #include <sys/types.h>
13
14 #include "testutil.h"
15 #include "memdebug.h"
16
17 #define MAIN_LOOP_HANG_TIMEOUT     90 * 1000
18 #define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
19
20 /*
21  * Source code in here hugely as reported in bug report 651460 by
22  * Christopher R. Palmer.
23  *
24  * Use multi interface to get HTTPS document over proxy, and provide
25  * auth info.
26  */
27
28 int test(char *URL)
29 {
30   CURL *c;
31   CURLM *m = NULL;
32   int res = 0;
33   int running;
34   char done = FALSE;
35   struct timeval ml_start;
36   struct timeval mp_start;
37   char ml_timedout = FALSE;
38   char mp_timedout = FALSE;
39
40   if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
41     fprintf(stderr, "curl_global_init() failed\n");
42     return TEST_ERR_MAJOR_BAD;
43   }
44
45   if ((c = curl_easy_init()) == NULL) {
46     fprintf(stderr, "curl_easy_init() failed\n");
47     curl_global_cleanup();
48     return TEST_ERR_MAJOR_BAD;
49   }
50
51   test_setopt(c, CURLOPT_PROXY, libtest_arg2); /* set in first.c */
52   test_setopt(c, CURLOPT_URL, URL);
53   test_setopt(c, CURLOPT_USERPWD, "test:ing");
54   test_setopt(c, CURLOPT_PROXYUSERPWD, "test:ing");
55   test_setopt(c, CURLOPT_HTTPPROXYTUNNEL, 1L);
56   test_setopt(c, CURLOPT_HEADER, 1L);
57
58   if ((m = curl_multi_init()) == NULL) {
59     fprintf(stderr, "curl_multi_init() failed\n");
60     curl_easy_cleanup(c);
61     curl_global_cleanup();
62     return TEST_ERR_MAJOR_BAD;
63   }
64
65   if ((res = (int)curl_multi_add_handle(m, c)) != CURLM_OK) {
66     fprintf(stderr, "curl_multi_add_handle() failed, "
67             "with code %d\n", res);
68     curl_multi_cleanup(m);
69     curl_easy_cleanup(c);
70     curl_global_cleanup();
71     return TEST_ERR_MAJOR_BAD;
72   }
73
74   ml_timedout = FALSE;
75   ml_start = tutil_tvnow();
76
77   while(!done) {
78     fd_set rd, wr, exc;
79     int max_fd;
80     struct timeval interval;
81
82     interval.tv_sec = 1;
83     interval.tv_usec = 0;
84
85     if (tutil_tvdiff(tutil_tvnow(), ml_start) >
86         MAIN_LOOP_HANG_TIMEOUT) {
87       ml_timedout = TRUE;
88       break;
89     }
90     mp_timedout = FALSE;
91     mp_start = tutil_tvnow();
92
93     while (res == CURLM_CALL_MULTI_PERFORM) {
94       res = (int)curl_multi_perform(m, &running);
95       if (tutil_tvdiff(tutil_tvnow(), mp_start) >
96           MULTI_PERFORM_HANG_TIMEOUT) {
97         mp_timedout = TRUE;
98         break;
99       }
100       if (running <= 0) {
101         done = TRUE;
102         break;
103       }
104     }
105     if (mp_timedout || done)
106       break;
107
108     if (res != CURLM_OK) {
109       fprintf(stderr, "not okay???\n");
110       break;
111     }
112
113     FD_ZERO(&rd);
114     FD_ZERO(&wr);
115     FD_ZERO(&exc);
116     max_fd = 0;
117
118     if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
119       fprintf(stderr, "unexpected failured of fdset.\n");
120       res = 89;
121       break;
122     }
123
124     if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
125       fprintf(stderr, "bad select??\n");
126       res = 95;
127       break;
128     }
129
130     res = CURLM_CALL_MULTI_PERFORM;
131   }
132
133   if (ml_timedout || mp_timedout) {
134     if (ml_timedout) fprintf(stderr, "ml_timedout\n");
135     if (mp_timedout) fprintf(stderr, "mp_timedout\n");
136     fprintf(stderr, "ABORTING TEST, since it seems "
137             "that it would have run forever.\n");
138     res = TEST_ERR_RUNS_FOREVER;
139   }
140
141 test_cleanup:
142
143   if(m) {
144     curl_multi_remove_handle(m, c);
145     curl_multi_cleanup(m);
146   }
147   curl_easy_cleanup(c);
148   curl_global_cleanup();
149
150   return res;
151 }
152