lib579.c (4783B)
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 #include "memdebug.h" 27 28 struct t579_WriteThis { 29 int counter; 30 }; 31 32 static bool started = FALSE; 33 static size_t last_ul = 0; 34 static size_t last_ul_total = 0; 35 36 static void progress_final_report(void) 37 { 38 FILE *moo = fopen(libtest_arg2, "ab"); 39 curl_mfprintf(moo ? moo : stderr, "Progress: end UL %zu/%zu\n", 40 last_ul, last_ul_total); 41 if(moo) 42 fclose(moo); 43 else 44 curl_mfprintf(stderr, "Progress: end UL, can't open %s\n", libtest_arg2); 45 started = FALSE; 46 } 47 48 static int t579_progress_callback(void *clientp, double dltotal, double dlnow, 49 double ultotal, double ulnow) 50 { 51 (void)clientp; /* UNUSED */ 52 (void)dltotal; /* UNUSED */ 53 (void)dlnow; /* UNUSED */ 54 55 if(started && ulnow <= 0.0 && last_ul) { 56 progress_final_report(); 57 } 58 59 last_ul = (size_t)ulnow; 60 last_ul_total = (size_t)ultotal; 61 if(!started) { 62 FILE *moo = fopen(libtest_arg2, "ab"); 63 curl_mfprintf(moo ? moo : stderr, "Progress: start UL %zu/%zu\n", 64 last_ul, last_ul_total); 65 if(moo) 66 fclose(moo); 67 else 68 curl_mfprintf(stderr, "Progress: start UL, can't open %s\n", 69 libtest_arg2); 70 started = TRUE; 71 } 72 73 return 0; 74 } 75 76 static size_t t579_read_cb(char *ptr, size_t size, size_t nmemb, void *userp) 77 { 78 static const char * const testpost[] = { 79 "one", 80 "two", 81 "three", 82 "and a final longer crap: four", 83 NULL 84 }; 85 86 struct t579_WriteThis *pooh = (struct t579_WriteThis *)userp; 87 const char *data; 88 89 if(size*nmemb < 1) 90 return 0; 91 92 data = testpost[pooh->counter]; 93 94 if(data) { 95 size_t len = strlen(data); 96 memcpy(ptr, data, len); 97 pooh->counter++; /* advance pointer */ 98 return len; 99 } 100 return 0; /* no more data left to deliver */ 101 } 102 103 static CURLcode test_lib579(char *URL) 104 { 105 CURL *curl; 106 CURLcode res = CURLE_OK; 107 struct curl_slist *slist = NULL; 108 struct t579_WriteThis pooh; 109 pooh.counter = 0; 110 111 if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { 112 curl_mfprintf(stderr, "curl_global_init() failed\n"); 113 return TEST_ERR_MAJOR_BAD; 114 } 115 116 curl = curl_easy_init(); 117 if(!curl) { 118 curl_mfprintf(stderr, "curl_easy_init() failed\n"); 119 curl_global_cleanup(); 120 return TEST_ERR_MAJOR_BAD; 121 } 122 123 slist = curl_slist_append(slist, "Transfer-Encoding: chunked"); 124 if(!slist) { 125 curl_mfprintf(stderr, "curl_slist_append() failed\n"); 126 curl_easy_cleanup(curl); 127 curl_global_cleanup(); 128 return TEST_ERR_MAJOR_BAD; 129 } 130 131 /* First set the URL that is about to receive our POST. */ 132 test_setopt(curl, CURLOPT_URL, URL); 133 134 /* Now specify we want to POST data */ 135 test_setopt(curl, CURLOPT_POST, 1L); 136 137 /* we want to use our own read function */ 138 test_setopt(curl, CURLOPT_READFUNCTION, t579_read_cb); 139 140 /* pointer to pass to our read function */ 141 test_setopt(curl, CURLOPT_READDATA, &pooh); 142 143 /* get verbose debug output please */ 144 test_setopt(curl, CURLOPT_VERBOSE, 1L); 145 146 /* include headers in the output */ 147 test_setopt(curl, CURLOPT_HEADER, 1L); 148 149 /* enforce chunked transfer by setting the header */ 150 test_setopt(curl, CURLOPT_HTTPHEADER, slist); 151 152 test_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST); 153 test_setopt(curl, CURLOPT_USERPWD, "foo:bar"); 154 155 /* we want to use our own progress function */ 156 test_setopt(curl, CURLOPT_NOPROGRESS, 0L); 157 test_setopt(curl, CURLOPT_PROGRESSFUNCTION, t579_progress_callback); 158 159 /* Perform the request, res will get the return code */ 160 res = curl_easy_perform(curl); 161 162 progress_final_report(); 163 164 test_cleanup: 165 166 /* clean up the headers list */ 167 if(slist) 168 curl_slist_free_all(slist); 169 170 /* always cleanup */ 171 curl_easy_cleanup(curl); 172 curl_global_cleanup(); 173 174 return res; 175 }