h2_upgrade_extreme.c (5341B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 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 https://curl.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 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 #include "first.h" 25 26 static size_t write_h2ue_cb(char *ptr, size_t size, size_t nmemb, void *opaque) 27 { 28 (void)ptr; 29 (void)opaque; 30 return size * nmemb; 31 } 32 33 static int test_h2_upgrade_extreme(int argc, char *argv[]) 34 { 35 const char *url; 36 CURLM *multi = NULL; 37 CURL *easy; 38 CURLMcode mc; 39 int running_handles = 0, start_count, numfds; 40 CURLMsg *msg; 41 int msgs_in_queue; 42 char range[128]; 43 int exitcode = 1; 44 45 if(argc != 2) { 46 curl_mfprintf(stderr, "%s URL\n", argv[0]); 47 return 2; 48 } 49 50 url = argv[1]; 51 multi = curl_multi_init(); 52 if(!multi) { 53 curl_mfprintf(stderr, "curl_multi_init failed\n"); 54 goto cleanup; 55 } 56 57 start_count = 200; 58 do { 59 if(start_count) { 60 easy = curl_easy_init(); 61 if(!easy) { 62 curl_mfprintf(stderr, "curl_easy_init failed\n"); 63 goto cleanup; 64 } 65 curl_easy_setopt(easy, CURLOPT_VERBOSE, 1L); 66 curl_easy_setopt(easy, CURLOPT_DEBUGFUNCTION, debug_cb); 67 curl_easy_setopt(easy, CURLOPT_URL, url); 68 curl_easy_setopt(easy, CURLOPT_NOSIGNAL, 1L); 69 curl_easy_setopt(easy, CURLOPT_AUTOREFERER, 1L); 70 curl_easy_setopt(easy, CURLOPT_FAILONERROR, 1L); 71 curl_easy_setopt(easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); 72 curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, write_h2ue_cb); 73 curl_easy_setopt(easy, CURLOPT_WRITEDATA, NULL); 74 curl_easy_setopt(easy, CURLOPT_HTTPGET, 1L); 75 curl_msnprintf(range, sizeof(range), 76 "%" CURL_FORMAT_CURL_OFF_TU "-" 77 "%" CURL_FORMAT_CURL_OFF_TU, 78 (curl_off_t)0, 79 (curl_off_t)16384); 80 curl_easy_setopt(easy, CURLOPT_RANGE, range); 81 82 mc = curl_multi_add_handle(multi, easy); 83 if(mc != CURLM_OK) { 84 curl_mfprintf(stderr, "curl_multi_add_handle: %s\n", 85 curl_multi_strerror(mc)); 86 curl_easy_cleanup(easy); 87 goto cleanup; 88 } 89 --start_count; 90 } 91 92 mc = curl_multi_perform(multi, &running_handles); 93 if(mc != CURLM_OK) { 94 curl_mfprintf(stderr, "curl_multi_perform: %s\n", 95 curl_multi_strerror(mc)); 96 goto cleanup; 97 } 98 99 if(running_handles) { 100 mc = curl_multi_poll(multi, NULL, 0, 1000000, &numfds); 101 if(mc != CURLM_OK) { 102 curl_mfprintf(stderr, "curl_multi_poll: %s\n", 103 curl_multi_strerror(mc)); 104 goto cleanup; 105 } 106 } 107 108 /* Check for finished handles and remove. */ 109 /* !checksrc! disable EQUALSNULL 1 */ 110 while((msg = curl_multi_info_read(multi, &msgs_in_queue)) != NULL) { 111 if(msg->msg == CURLMSG_DONE) { 112 long status = 0; 113 curl_off_t xfer_id; 114 curl_easy_getinfo(msg->easy_handle, CURLINFO_XFER_ID, &xfer_id); 115 curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &status); 116 if(msg->data.result == CURLE_SEND_ERROR || 117 msg->data.result == CURLE_RECV_ERROR) { 118 /* We get these if the server had a GOAWAY in transit on 119 * re-using a connection */ 120 } 121 else if(msg->data.result) { 122 curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T 123 ": failed with %d\n", xfer_id, msg->data.result); 124 goto cleanup; 125 } 126 else if(status != 206) { 127 curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T 128 ": wrong http status %ld (expected 206)\n", xfer_id, 129 status); 130 goto cleanup; 131 } 132 curl_multi_remove_handle(multi, msg->easy_handle); 133 curl_easy_cleanup(msg->easy_handle); 134 curl_mfprintf(stderr, "transfer #%" CURL_FORMAT_CURL_OFF_T" retiring " 135 "(%d now running)\n", xfer_id, running_handles); 136 } 137 } 138 139 curl_mfprintf(stderr, "running_handles=%d, yet_to_start=%d\n", 140 running_handles, start_count); 141 142 } while(running_handles > 0 || start_count); 143 144 curl_mfprintf(stderr, "exiting\n"); 145 exitcode = 0; 146 147 cleanup: 148 149 if(multi) { 150 CURL **list = curl_multi_get_handles(multi); 151 if(list) { 152 int i; 153 for(i = 0; list[i]; i++) { 154 curl_multi_remove_handle(multi, list[i]); 155 curl_easy_cleanup(list[i]); 156 } 157 curl_free(list); 158 } 159 curl_multi_cleanup(multi); 160 } 161 162 return exitcode; 163 }