1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2011, 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 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/* Example source code to show how the callback function can be used to 23 * download data into a chunk of memory instead of storing it in a file. 24 * After successful download we use curl_easy_getinfo() calls to get the 25 * amount of downloaded bytes, the time used for the whole download, and 26 * the average download speed. 27 * On Linux you can create the download test files with: 28 * dd if=/dev/urandom of=file_1M.bin bs=1M count=1 29 * 30 */ 31 32#include <stdio.h> 33#include <stdlib.h> 34#include <string.h> 35#include <time.h> 36 37#include <curl/curl.h> 38 39#define URL_BASE "http://speedtest.your.domain/" 40#define URL_1M URL_BASE "file_1M.bin" 41#define URL_2M URL_BASE "file_2M.bin" 42#define URL_5M URL_BASE "file_5M.bin" 43#define URL_10M URL_BASE "file_10M.bin" 44#define URL_20M URL_BASE "file_20M.bin" 45#define URL_50M URL_BASE "file_50M.bin" 46#define URL_100M URL_BASE "file_100M.bin" 47 48#define CHKSPEED_VERSION "1.0" 49 50static size_t WriteCallback(void *ptr, size_t size, size_t nmemb, void *data) 51{ 52 /* we are not interested in the downloaded bytes itself, 53 so we only return the size we would have saved ... */ 54 (void)ptr; /* unused */ 55 (void)data; /* unused */ 56 return (size_t)(size * nmemb); 57} 58 59int main(int argc, char *argv[]) 60{ 61 CURL *curl_handle; 62 CURLcode res; 63 int prtsep = 0, prttime = 0; 64 const char *url = URL_1M; 65 char *appname = argv[0]; 66 67 if (argc > 1) { 68 /* parse input parameters */ 69 for (argc--, argv++; *argv; argc--, argv++) { 70 if (strncasecmp(*argv, "-", 1) == 0) { 71 if (strncasecmp(*argv, "-H", 2) == 0) { 72 fprintf(stderr, 73 "\rUsage: %s [-m=1|2|5|10|20|50|100] [-t] [-x] [url]\n", 74 appname); 75 exit(1); 76 } else if (strncasecmp(*argv, "-V", 2) == 0) { 77 fprintf(stderr, "\r%s %s - %s\n", 78 appname, CHKSPEED_VERSION, curl_version()); 79 exit(1); 80 } else if (strncasecmp(*argv, "-X", 2) == 0) { 81 prtsep = 1; 82 } else if (strncasecmp(*argv, "-T", 2) == 0) { 83 prttime = 1; 84 } else if (strncasecmp(*argv, "-M=", 3) == 0) { 85 long m = strtol((*argv)+3, NULL, 10); 86 switch(m) { 87 case 1: url = URL_1M; 88 break; 89 case 2: url = URL_2M; 90 break; 91 case 5: url = URL_5M; 92 break; 93 case 10: url = URL_10M; 94 break; 95 case 20: url = URL_20M; 96 break; 97 case 50: url = URL_50M; 98 break; 99 case 100: url = URL_100M; 100 break; 101 default: fprintf(stderr, "\r%s: invalid parameter %s\n", 102 appname, *argv + 3); 103 exit(1); 104 } 105 } else { 106 fprintf(stderr, "\r%s: invalid or unknown option %s\n", 107 appname, *argv); 108 exit(1); 109 } 110 } else { 111 url = *argv; 112 } 113 } 114 } 115 116 /* print separator line */ 117 if (prtsep) { 118 printf("-------------------------------------------------\n"); 119 } 120 /* print localtime */ 121 if (prttime) { 122 time_t t = time(NULL); 123 printf("Localtime: %s", ctime(&t)); 124 } 125 126 /* init libcurl */ 127 curl_global_init(CURL_GLOBAL_ALL); 128 129 /* init the curl session */ 130 curl_handle = curl_easy_init(); 131 132 /* specify URL to get */ 133 curl_easy_setopt(curl_handle, CURLOPT_URL, url); 134 135 /* send all data to this function */ 136 curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteCallback); 137 138 /* some servers don't like requests that are made without a user-agent 139 field, so we provide one */ 140 curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, 141 "libcurl-speedchecker/" CHKSPEED_VERSION); 142 143 /* get it! */ 144 res = curl_easy_perform(curl_handle); 145 146 if(CURLE_OK == res) { 147 double val; 148 149 /* check for bytes downloaded */ 150 res = curl_easy_getinfo(curl_handle, CURLINFO_SIZE_DOWNLOAD, &val); 151 if((CURLE_OK == res) && (val>0)) 152 printf("Data downloaded: %0.0f bytes.\n", val); 153 154 /* check for total download time */ 155 res = curl_easy_getinfo(curl_handle, CURLINFO_TOTAL_TIME, &val); 156 if((CURLE_OK == res) && (val>0)) 157 printf("Total download time: %0.3f sec.\n", val); 158 159 /* check for average download speed */ 160 res = curl_easy_getinfo(curl_handle, CURLINFO_SPEED_DOWNLOAD, &val); 161 if((CURLE_OK == res) && (val>0)) 162 printf("Average download speed: %0.3f kbyte/sec.\n", val / 1024); 163 164 } else { 165 fprintf(stderr, "Error while fetching '%s' : %s\n", 166 url, curl_easy_strerror(res)); 167 } 168 169 /* cleanup curl stuff */ 170 curl_easy_cleanup(curl_handle); 171 172 /* we're done with libcurl, so clean it up */ 173 curl_global_cleanup(); 174 175 return 0; 176} 177