1 /*****************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * $Id: lib526.c,v 1.14 2008-05-22 21:49:53 danf Exp $
12 * This code sets up multiple easy handles that transfer a single file from
13 * the same URL, in a serial manner after each other. Due to the connection
14 * sharing within the multi handle all transfers are performed on the same
15 * persistent connection.
17 * This source code is used for lib526, lib527 and lib532 with only #ifdefs
18 * controlling the small differences.
20 * - lib526 closes all easy handles after
21 * they all have transfered the file over the single connection
22 * - lib527 closes each easy handle after each single transfer.
23 * - lib532 uses only a single easy handle that is removed, reset and then
24 * re-added for each transfer
26 * Test case 526, 527 and 532 use FTP, while test 528 uses the lib526 tool but
32 #include <sys/types.h>
38 #define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
39 #define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
46 CURL
*curl
[NUM_HANDLES
];
52 struct timeval ml_start
;
53 struct timeval mp_start
;
54 char ml_timedout
= FALSE
;
55 char mp_timedout
= FALSE
;
57 if (curl_global_init(CURL_GLOBAL_ALL
) != CURLE_OK
) {
58 fprintf(stderr
, "curl_global_init() failed\n");
59 return TEST_ERR_MAJOR_BAD
;
62 /* get NUM_HANDLES easy handles */
63 for(i
=0; i
< NUM_HANDLES
; i
++) {
64 curl
[i
] = curl_easy_init();
66 fprintf(stderr
, "curl_easy_init() failed "
67 "on handle #%d\n", i
);
68 for (j
=i
-1; j
>= 0; j
--) {
69 curl_easy_cleanup(curl
[j
]);
71 curl_global_cleanup();
72 return TEST_ERR_MAJOR_BAD
+ i
;
74 curl_easy_setopt(curl
[i
], CURLOPT_URL
, URL
);
77 curl_easy_setopt(curl
[i
], CURLOPT_VERBOSE
, 1L);
80 if ((m
= curl_multi_init()) == NULL
) {
81 fprintf(stderr
, "curl_multi_init() failed\n");
82 for(i
=0; i
< NUM_HANDLES
; i
++) {
83 curl_easy_cleanup(curl
[i
]);
85 curl_global_cleanup();
86 return TEST_ERR_MAJOR_BAD
;
89 if ((res
= (int)curl_multi_add_handle(m
, curl
[current
])) != CURLM_OK
) {
90 fprintf(stderr
, "curl_multi_add_handle() failed, "
91 "with code %d\n", res
);
92 curl_multi_cleanup(m
);
93 for(i
=0; i
< NUM_HANDLES
; i
++) {
94 curl_easy_cleanup(curl
[i
]);
96 curl_global_cleanup();
97 return TEST_ERR_MAJOR_BAD
;
101 ml_start
= tutil_tvnow();
103 fprintf(stderr
, "Start at URL 0\n");
108 struct timeval interval
;
111 interval
.tv_usec
= 0;
113 if (tutil_tvdiff(tutil_tvnow(), ml_start
) >
114 MAIN_LOOP_HANG_TIMEOUT
) {
119 mp_start
= tutil_tvnow();
121 while (res
== CURLM_CALL_MULTI_PERFORM
) {
122 res
= (int)curl_multi_perform(m
, &running
);
123 if (tutil_tvdiff(tutil_tvnow(), mp_start
) >
124 MULTI_PERFORM_HANG_TIMEOUT
) {
130 /* NOTE: this code does not remove the handle from the multi handle
131 here, which would be the nice, sane and documented way of working.
132 This however tests that the API survives this abuse gracefully. */
133 curl_easy_cleanup(curl
[current
]);
135 if(++current
< NUM_HANDLES
) {
136 fprintf(stderr
, "Advancing to URL %d\n", current
);
138 /* first remove the only handle we use */
139 curl_multi_remove_handle(m
, curl
[0]);
141 /* make us re-use the same handle all the time, and try resetting
142 the handle first too */
143 curl_easy_reset(curl
[0]);
144 curl_easy_setopt(curl
[0], CURLOPT_URL
, URL
);
145 curl_easy_setopt(curl
[0], CURLOPT_VERBOSE
, 1L);
148 res
= (int)curl_multi_add_handle(m
, curl
[0]);
150 res
= (int)curl_multi_add_handle(m
, curl
[current
]);
153 fprintf(stderr
, "add handle failed: %d.\n", res
);
159 done
= TRUE
; /* bail out */
163 if (mp_timedout
|| done
)
166 if (res
!= CURLM_OK
) {
167 fprintf(stderr
, "not okay???\n");
176 if (curl_multi_fdset(m
, &rd
, &wr
, &exc
, &max_fd
) != CURLM_OK
) {
177 fprintf(stderr
, "unexpected failured of fdset.\n");
182 if (select_test(max_fd
+1, &rd
, &wr
, &exc
, &interval
) == -1) {
183 fprintf(stderr
, "bad select??\n");
188 res
= CURLM_CALL_MULTI_PERFORM
;
191 if (ml_timedout
|| mp_timedout
) {
192 if (ml_timedout
) fprintf(stderr
, "ml_timedout\n");
193 if (mp_timedout
) fprintf(stderr
, "mp_timedout\n");
194 fprintf(stderr
, "ABORTING TEST, since it seems "
195 "that it would have run forever.\n");
196 res
= TEST_ERR_RUNS_FOREVER
;
200 /* get NUM_HANDLES easy handles */
201 for(i
=0; i
< NUM_HANDLES
; i
++) {
203 curl_multi_remove_handle(m
, curl
[i
]);
205 curl_easy_cleanup(curl
[i
]);
208 curl_multi_cleanup(m
);
210 curl_global_cleanup();