1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel (at) 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 /* 23 * This code sets up multiple easy handles that transfer a single file from 24 * the same URL, in a serial manner after each other. Due to the connection 25 * sharing within the multi handle all transfers are performed on the same 26 * persistent connection. 27 * 28 * This source code is used for lib526, lib527 and lib532 with only #ifdefs 29 * controlling the small differences. 30 * 31 * - lib526 closes all easy handles after 32 * they all have transfered the file over the single connection 33 * - lib527 closes each easy handle after each single transfer. 34 * - lib532 uses only a single easy handle that is removed, reset and then 35 * re-added for each transfer 36 * 37 * Test case 526, 527 and 532 use FTP, while test 528 uses the lib526 tool but 38 * with HTTP. 39 */ 40 41 #include "test.h" 42 43 #include <fcntl.h> 44 45 #include "testutil.h" 46 #include "warnless.h" 47 #include "memdebug.h" 48 49 #define TEST_HANG_TIMEOUT 60 * 1000 50 51 #define NUM_HANDLES 4 52 53 int test(char *URL) 54 { 55 int res = 0; 56 CURL *curl[NUM_HANDLES]; 57 int running; 58 CURLM *m = NULL; 59 int current = 0; 60 int i; 61 62 for(i=0; i < NUM_HANDLES; i++) 63 curl[i] = NULL; 64 65 start_test_timing(); 66 67 global_init(CURL_GLOBAL_ALL); 68 69 /* get NUM_HANDLES easy handles */ 70 for(i=0; i < NUM_HANDLES; i++) { 71 easy_init(curl[i]); 72 /* specify target */ 73 easy_setopt(curl[i], CURLOPT_URL, URL); 74 /* go verbose */ 75 easy_setopt(curl[i], CURLOPT_VERBOSE, 1L); 76 } 77 78 multi_init(m); 79 80 multi_add_handle(m, curl[current]); 81 82 fprintf(stderr, "Start at URL 0\n"); 83 84 for(;;) { 85 struct timeval interval; 86 fd_set rd, wr, exc; 87 int maxfd = -99; 88 89 interval.tv_sec = 1; 90 interval.tv_usec = 0; 91 92 multi_perform(m, &running); 93 94 abort_on_test_timeout(); 95 96 if(!running) { 97 #ifdef LIB527 98 /* NOTE: this code does not remove the handle from the multi handle 99 here, which would be the nice, sane and documented way of working. 100 This however tests that the API survives this abuse gracefully. */ 101 curl_easy_cleanup(curl[current]); 102 curl[current] = NULL; 103 #endif 104 if(++current < NUM_HANDLES) { 105 fprintf(stderr, "Advancing to URL %d\n", current); 106 #ifdef LIB532 107 /* first remove the only handle we use */ 108 curl_multi_remove_handle(m, curl[0]); 109 110 /* make us re-use the same handle all the time, and try resetting 111 the handle first too */ 112 curl_easy_reset(curl[0]); 113 easy_setopt(curl[0], CURLOPT_URL, URL); 114 /* go verbose */ 115 easy_setopt(curl[0], CURLOPT_VERBOSE, 1L); 116 117 /* re-add it */ 118 multi_add_handle(m, curl[0]); 119 #else 120 multi_add_handle(m, curl[current]); 121 #endif 122 } 123 else { 124 break; /* done */ 125 } 126 } 127 128 FD_ZERO(&rd); 129 FD_ZERO(&wr); 130 FD_ZERO(&exc); 131 132 multi_fdset(m, &rd, &wr, &exc, &maxfd); 133 134 /* At this point, maxfd is guaranteed to be greater or equal than -1. */ 135 136 select_test(maxfd+1, &rd, &wr, &exc, &interval); 137 138 abort_on_test_timeout(); 139 } 140 141 test_cleanup: 142 143 #if defined(LIB526) 144 145 /* test 526 and 528 */ 146 /* proper cleanup sequence - type PB */ 147 148 for(i=0; i < NUM_HANDLES; i++) { 149 curl_multi_remove_handle(m, curl[i]); 150 curl_easy_cleanup(curl[i]); 151 } 152 curl_multi_cleanup(m); 153 curl_global_cleanup(); 154 155 #elif defined(LIB527) 156 157 /* test 527 */ 158 159 /* Upon non-failure test flow the easy's have already been cleanup'ed. In 160 case there is a failure we arrive here with easy's that have not been 161 cleanup'ed yet, in this case we have to cleanup them or otherwise these 162 will be leaked, let's use undocumented cleanup sequence - type UB */ 163 164 if(res) 165 for(i=0; i < NUM_HANDLES; i++) 166 curl_easy_cleanup(curl[i]); 167 168 curl_multi_cleanup(m); 169 curl_global_cleanup(); 170 171 #elif defined(LIB532) 172 173 /* test 532 */ 174 /* undocumented cleanup sequence - type UB */ 175 176 for(i=0; i < NUM_HANDLES; i++) 177 curl_easy_cleanup(curl[i]); 178 curl_multi_cleanup(m); 179 curl_global_cleanup(); 180 181 #endif 182 183 return res; 184 } 185