Home | History | Annotate | Download | only in testcurl
      1 /*
      2      This file is part of libmicrohttpd
      3      Copyright (C) 2007 Christian Grothoff
      4 
      5      libmicrohttpd is free software; you can redistribute it and/or modify
      6      it under the terms of the GNU General Public License as published
      7      by the Free Software Foundation; either version 2, or (at your
      8      option) any later version.
      9 
     10      libmicrohttpd is distributed in the hope that it will be useful, but
     11      WITHOUT ANY WARRANTY; without even the implied warranty of
     12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13      General Public License for more details.
     14 
     15      You should have received a copy of the GNU General Public License
     16      along with libmicrohttpd; see the file COPYING.  If not, write to the
     17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     18      Boston, MA 02111-1307, USA.
     19 */
     20 
     21 /**
     22  * @file curl_version_check.c
     23  * @brief  verify required cURL version is available to run tests
     24  * @author Sagie Amir
     25  */
     26 
     27 #include "MHD_config.h"
     28 #include "platform.h"
     29 #include <curl/curl.h>
     30 
     31 #ifndef WINDOWS
     32 #include <unistd.h>
     33 #endif
     34 
     35 static int
     36 parse_version_number (const char **s)
     37 {
     38   int i = 0;
     39   char num[17];
     40 
     41   while (i < 16 && ((**s >= '0') & (**s <= '9')))
     42     {
     43       num[i] = **s;
     44       (*s)++;
     45       i++;
     46     }
     47 
     48   num[i] = '\0';
     49 
     50   return atoi (num);
     51 }
     52 
     53 const char *
     54 parse_version_string (const char *s, int *major, int *minor, int *micro)
     55 {
     56   if (!s)
     57     return NULL;
     58   *major = parse_version_number (&s);
     59   if (*s != '.')
     60     return NULL;
     61   s++;
     62   *minor = parse_version_number (&s);
     63   if (*s != '.')
     64     return NULL;
     65   s++;
     66   *micro = parse_version_number (&s);
     67   return s;
     68 }
     69 
     70 #if HTTPS_SUPPORT
     71 int
     72 curl_uses_nss_ssl()
     73 {
     74   return (strstr(curl_version(), " NSS/") != NULL) ? 0 : -1;
     75 }
     76 #endif
     77 
     78 /*
     79  * check local libcurl version matches required version
     80  */
     81 int
     82 curl_check_version (const char *req_version)
     83 {
     84   const char *ver;
     85   const char *curl_ver;
     86 #if HTTPS_SUPPORT
     87   const char *ssl_ver;
     88   const char *req_ssl_ver;
     89 #endif
     90 
     91   int loc_major, loc_minor, loc_micro;
     92   int rq_major, rq_minor, rq_micro;
     93 
     94   ver = curl_version ();
     95 #if HAVE_MESSAGES
     96   fprintf (stderr, "curl version: %s\n", ver);
     97 #endif
     98   /*
     99    * this call relies on the cURL string to be of the exact following format :
    100    * 'libcurl/7.16.4 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/0.6.5' OR
    101    * 'libcurl/7.18.2 GnuTLS/2.4.0 zlib/1.2.3.3 libidn/0.6.5'
    102    */
    103   curl_ver = strchr (ver, '/');
    104   if (curl_ver == NULL)
    105     return -1;
    106   curl_ver++;
    107   /* Parse version numbers */
    108   if ( (NULL == parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro)) ||
    109        (NULL == parse_version_string (curl_ver, &loc_major, &loc_minor, &loc_micro)) )
    110     return -1;
    111 
    112   /* Compare version numbers.  */
    113   if ((loc_major > rq_major
    114        || (loc_major == rq_major && loc_minor > rq_minor)
    115        || (loc_major == rq_major && loc_minor == rq_minor
    116            && loc_micro > rq_micro) || (loc_major == rq_major
    117                                         && loc_minor == rq_minor
    118                                         && loc_micro == rq_micro)) == 0)
    119     {
    120       fprintf (stderr,
    121                "Error: running curl test depends on local libcurl version > %s\n",
    122                req_version);
    123       return -1;
    124     }
    125 
    126   /*
    127    * enforce required gnutls/openssl version.
    128    * TODO use curl version string to assert use of gnutls
    129    */
    130 #if HTTPS_SUPPORT
    131   ssl_ver = strchr (curl_ver, ' ');
    132   if (ssl_ver == NULL)
    133     return -1;
    134   ssl_ver++;
    135   if (strncmp ("GnuTLS", ssl_ver, strlen ("GNUtls")) == 0)
    136     {
    137       ssl_ver = strchr (ssl_ver, '/');
    138       req_ssl_ver = MHD_REQ_CURL_GNUTLS_VERSION;
    139     }
    140   else if (strncmp ("OpenSSL", ssl_ver, strlen ("OpenSSL")) == 0)
    141     {
    142       ssl_ver = strchr (ssl_ver, '/');
    143       req_ssl_ver = MHD_REQ_CURL_OPENSSL_VERSION;
    144     }
    145   else if (strncmp ("NSS", ssl_ver, strlen ("NSS")) == 0)
    146     {
    147       ssl_ver = strchr (ssl_ver, '/');
    148       req_ssl_ver = MHD_REQ_CURL_NSS_VERSION;
    149     }
    150   else
    151     {
    152       fprintf (stderr, "Error: unrecognized curl ssl library\n");
    153       return -1;
    154     }
    155   if (ssl_ver == NULL)
    156     return -1;
    157   ssl_ver++;
    158   if ( (NULL == parse_version_string (req_ssl_ver, &rq_major, &rq_minor, &rq_micro)) ||
    159        (NULL == parse_version_string (ssl_ver, &loc_major, &loc_minor, &loc_micro)) )
    160     return -1;
    161 
    162   if ((loc_major > rq_major
    163        || (loc_major == rq_major && loc_minor > rq_minor)
    164        || (loc_major == rq_major && loc_minor == rq_minor
    165            && loc_micro > rq_micro) || (loc_major == rq_major
    166                                         && loc_minor == rq_minor
    167                                         && loc_micro == rq_micro)) == 0)
    168     {
    169       fprintf (stderr,
    170                "Error: running curl test depends on local libcurl SSL version > %s\n",
    171                req_ssl_ver);
    172       return -1;
    173     }
    174 #endif
    175   return 0;
    176 }
    177