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