113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci/* <DESC> 2513498266Sopenharmony_ci * Show transfer timing info after download completes. 2613498266Sopenharmony_ci * </DESC> 2713498266Sopenharmony_ci */ 2813498266Sopenharmony_ci/* Example source code to show how the callback function can be used to 2913498266Sopenharmony_ci * download data into a chunk of memory instead of storing it in a file. 3013498266Sopenharmony_ci * After successful download we use curl_easy_getinfo() calls to get the 3113498266Sopenharmony_ci * amount of downloaded bytes, the time used for the whole download, and 3213498266Sopenharmony_ci * the average download speed. 3313498266Sopenharmony_ci * On Linux you can create the download test files with: 3413498266Sopenharmony_ci * dd if=/dev/urandom of=file_1M.bin bs=1M count=1 3513498266Sopenharmony_ci * 3613498266Sopenharmony_ci */ 3713498266Sopenharmony_ci 3813498266Sopenharmony_ci#include <stdio.h> 3913498266Sopenharmony_ci#include <stdlib.h> 4013498266Sopenharmony_ci#include <time.h> 4113498266Sopenharmony_ci 4213498266Sopenharmony_ci#include <curl/curl.h> 4313498266Sopenharmony_ci 4413498266Sopenharmony_ci#define URL_BASE "http://speedtest.your.domain/" 4513498266Sopenharmony_ci#define URL_1M URL_BASE "file_1M.bin" 4613498266Sopenharmony_ci#define URL_2M URL_BASE "file_2M.bin" 4713498266Sopenharmony_ci#define URL_5M URL_BASE "file_5M.bin" 4813498266Sopenharmony_ci#define URL_10M URL_BASE "file_10M.bin" 4913498266Sopenharmony_ci#define URL_20M URL_BASE "file_20M.bin" 5013498266Sopenharmony_ci#define URL_50M URL_BASE "file_50M.bin" 5113498266Sopenharmony_ci#define URL_100M URL_BASE "file_100M.bin" 5213498266Sopenharmony_ci 5313498266Sopenharmony_ci#define CHKSPEED_VERSION "1.0" 5413498266Sopenharmony_ci 5513498266Sopenharmony_cistatic size_t WriteCallback(void *ptr, size_t size, size_t nmemb, void *data) 5613498266Sopenharmony_ci{ 5713498266Sopenharmony_ci /* we are not interested in the downloaded bytes itself, 5813498266Sopenharmony_ci so we only return the size we would have saved ... */ 5913498266Sopenharmony_ci (void)ptr; /* unused */ 6013498266Sopenharmony_ci (void)data; /* unused */ 6113498266Sopenharmony_ci return (size_t)(size * nmemb); 6213498266Sopenharmony_ci} 6313498266Sopenharmony_ci 6413498266Sopenharmony_ciint main(int argc, char *argv[]) 6513498266Sopenharmony_ci{ 6613498266Sopenharmony_ci CURL *curl_handle; 6713498266Sopenharmony_ci CURLcode res; 6813498266Sopenharmony_ci int prtall = 0, prtsep = 0, prttime = 0; 6913498266Sopenharmony_ci const char *url = URL_1M; 7013498266Sopenharmony_ci char *appname = argv[0]; 7113498266Sopenharmony_ci 7213498266Sopenharmony_ci if(argc > 1) { 7313498266Sopenharmony_ci /* parse input parameters */ 7413498266Sopenharmony_ci for(argc--, argv++; *argv; argc--, argv++) { 7513498266Sopenharmony_ci if(argv[0][0] == '-') { 7613498266Sopenharmony_ci switch(argv[0][1]) { 7713498266Sopenharmony_ci case 'h': 7813498266Sopenharmony_ci case 'H': 7913498266Sopenharmony_ci fprintf(stderr, 8013498266Sopenharmony_ci "\rUsage: %s [-m=1|2|5|10|20|50|100] [-t] [-x] [url]\n", 8113498266Sopenharmony_ci appname); 8213498266Sopenharmony_ci exit(1); 8313498266Sopenharmony_ci case 'v': 8413498266Sopenharmony_ci case 'V': 8513498266Sopenharmony_ci fprintf(stderr, "\r%s %s - %s\n", 8613498266Sopenharmony_ci appname, CHKSPEED_VERSION, curl_version()); 8713498266Sopenharmony_ci exit(1); 8813498266Sopenharmony_ci case 'a': 8913498266Sopenharmony_ci case 'A': 9013498266Sopenharmony_ci prtall = 1; 9113498266Sopenharmony_ci break; 9213498266Sopenharmony_ci case 'x': 9313498266Sopenharmony_ci case 'X': 9413498266Sopenharmony_ci prtsep = 1; 9513498266Sopenharmony_ci break; 9613498266Sopenharmony_ci case 't': 9713498266Sopenharmony_ci case 'T': 9813498266Sopenharmony_ci prttime = 1; 9913498266Sopenharmony_ci break; 10013498266Sopenharmony_ci case 'm': 10113498266Sopenharmony_ci case 'M': 10213498266Sopenharmony_ci if(argv[0][2] == '=') { 10313498266Sopenharmony_ci long m = strtol((*argv) + 3, NULL, 10); 10413498266Sopenharmony_ci switch(m) { 10513498266Sopenharmony_ci case 1: 10613498266Sopenharmony_ci url = URL_1M; 10713498266Sopenharmony_ci break; 10813498266Sopenharmony_ci case 2: 10913498266Sopenharmony_ci url = URL_2M; 11013498266Sopenharmony_ci break; 11113498266Sopenharmony_ci case 5: 11213498266Sopenharmony_ci url = URL_5M; 11313498266Sopenharmony_ci break; 11413498266Sopenharmony_ci case 10: 11513498266Sopenharmony_ci url = URL_10M; 11613498266Sopenharmony_ci break; 11713498266Sopenharmony_ci case 20: 11813498266Sopenharmony_ci url = URL_20M; 11913498266Sopenharmony_ci break; 12013498266Sopenharmony_ci case 50: 12113498266Sopenharmony_ci url = URL_50M; 12213498266Sopenharmony_ci break; 12313498266Sopenharmony_ci case 100: 12413498266Sopenharmony_ci url = URL_100M; 12513498266Sopenharmony_ci break; 12613498266Sopenharmony_ci default: 12713498266Sopenharmony_ci fprintf(stderr, "\r%s: invalid parameter %s\n", 12813498266Sopenharmony_ci appname, *argv + 3); 12913498266Sopenharmony_ci return 1; 13013498266Sopenharmony_ci } 13113498266Sopenharmony_ci break; 13213498266Sopenharmony_ci } 13313498266Sopenharmony_ci fprintf(stderr, "\r%s: invalid or unknown option %s\n", 13413498266Sopenharmony_ci appname, *argv); 13513498266Sopenharmony_ci return 1; 13613498266Sopenharmony_ci default: 13713498266Sopenharmony_ci fprintf(stderr, "\r%s: invalid or unknown option %s\n", 13813498266Sopenharmony_ci appname, *argv); 13913498266Sopenharmony_ci return 1; 14013498266Sopenharmony_ci } 14113498266Sopenharmony_ci } 14213498266Sopenharmony_ci else { 14313498266Sopenharmony_ci url = *argv; 14413498266Sopenharmony_ci } 14513498266Sopenharmony_ci } 14613498266Sopenharmony_ci } 14713498266Sopenharmony_ci 14813498266Sopenharmony_ci /* print separator line */ 14913498266Sopenharmony_ci if(prtsep) { 15013498266Sopenharmony_ci printf("-------------------------------------------------\n"); 15113498266Sopenharmony_ci } 15213498266Sopenharmony_ci /* print localtime */ 15313498266Sopenharmony_ci if(prttime) { 15413498266Sopenharmony_ci time_t t = time(NULL); 15513498266Sopenharmony_ci printf("Localtime: %s", ctime(&t)); 15613498266Sopenharmony_ci } 15713498266Sopenharmony_ci 15813498266Sopenharmony_ci /* init libcurl */ 15913498266Sopenharmony_ci curl_global_init(CURL_GLOBAL_ALL); 16013498266Sopenharmony_ci 16113498266Sopenharmony_ci /* init the curl session */ 16213498266Sopenharmony_ci curl_handle = curl_easy_init(); 16313498266Sopenharmony_ci 16413498266Sopenharmony_ci /* specify URL to get */ 16513498266Sopenharmony_ci curl_easy_setopt(curl_handle, CURLOPT_URL, url); 16613498266Sopenharmony_ci 16713498266Sopenharmony_ci /* send all data to this function */ 16813498266Sopenharmony_ci curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteCallback); 16913498266Sopenharmony_ci 17013498266Sopenharmony_ci /* some servers do not like requests that are made without a user-agent 17113498266Sopenharmony_ci field, so we provide one */ 17213498266Sopenharmony_ci curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, 17313498266Sopenharmony_ci "libcurl-speedchecker/" CHKSPEED_VERSION); 17413498266Sopenharmony_ci 17513498266Sopenharmony_ci /* get it! */ 17613498266Sopenharmony_ci res = curl_easy_perform(curl_handle); 17713498266Sopenharmony_ci 17813498266Sopenharmony_ci if(CURLE_OK == res) { 17913498266Sopenharmony_ci curl_off_t val; 18013498266Sopenharmony_ci 18113498266Sopenharmony_ci /* check for bytes downloaded */ 18213498266Sopenharmony_ci res = curl_easy_getinfo(curl_handle, CURLINFO_SIZE_DOWNLOAD_T, &val); 18313498266Sopenharmony_ci if((CURLE_OK == res) && (val>0)) 18413498266Sopenharmony_ci printf("Data downloaded: %lu bytes.\n", (unsigned long)val); 18513498266Sopenharmony_ci 18613498266Sopenharmony_ci /* check for total download time */ 18713498266Sopenharmony_ci res = curl_easy_getinfo(curl_handle, CURLINFO_TOTAL_TIME_T, &val); 18813498266Sopenharmony_ci if((CURLE_OK == res) && (val>0)) 18913498266Sopenharmony_ci printf("Total download time: %lu.%06lu sec.\n", 19013498266Sopenharmony_ci (unsigned long)(val / 1000000), (unsigned long)(val % 1000000)); 19113498266Sopenharmony_ci 19213498266Sopenharmony_ci /* check for average download speed */ 19313498266Sopenharmony_ci res = curl_easy_getinfo(curl_handle, CURLINFO_SPEED_DOWNLOAD_T, &val); 19413498266Sopenharmony_ci if((CURLE_OK == res) && (val>0)) 19513498266Sopenharmony_ci printf("Average download speed: %lu kbyte/sec.\n", 19613498266Sopenharmony_ci (unsigned long)(val / 1024)); 19713498266Sopenharmony_ci 19813498266Sopenharmony_ci if(prtall) { 19913498266Sopenharmony_ci /* check for name resolution time */ 20013498266Sopenharmony_ci res = curl_easy_getinfo(curl_handle, CURLINFO_NAMELOOKUP_TIME_T, &val); 20113498266Sopenharmony_ci if((CURLE_OK == res) && (val>0)) 20213498266Sopenharmony_ci printf("Name lookup time: %lu.%06lu sec.\n", 20313498266Sopenharmony_ci (unsigned long)(val / 1000000), (unsigned long)(val % 1000000)); 20413498266Sopenharmony_ci 20513498266Sopenharmony_ci /* check for connect time */ 20613498266Sopenharmony_ci res = curl_easy_getinfo(curl_handle, CURLINFO_CONNECT_TIME_T, &val); 20713498266Sopenharmony_ci if((CURLE_OK == res) && (val>0)) 20813498266Sopenharmony_ci printf("Connect time: %lu.%06lu sec.\n", 20913498266Sopenharmony_ci (unsigned long)(val / 1000000), (unsigned long)(val % 1000000)); 21013498266Sopenharmony_ci } 21113498266Sopenharmony_ci } 21213498266Sopenharmony_ci else { 21313498266Sopenharmony_ci fprintf(stderr, "Error while fetching '%s' : %s\n", 21413498266Sopenharmony_ci url, curl_easy_strerror(res)); 21513498266Sopenharmony_ci } 21613498266Sopenharmony_ci 21713498266Sopenharmony_ci /* cleanup curl stuff */ 21813498266Sopenharmony_ci curl_easy_cleanup(curl_handle); 21913498266Sopenharmony_ci 22013498266Sopenharmony_ci /* we are done with libcurl, so clean it up */ 22113498266Sopenharmony_ci curl_global_cleanup(); 22213498266Sopenharmony_ci 22313498266Sopenharmony_ci return 0; 22413498266Sopenharmony_ci} 225