libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

test_https_get_parallel.c (6417B)


      1 /*
      2   This file is part of libmicrohttpd
      3   Copyright (C) 2007 Christian Grothoff
      4   Copyright (C) 2014-2022 Evgeny Grin (Karlson2k)
      5 
      6   libmicrohttpd is free software; you can redistribute it and/or modify
      7   it under the terms of the GNU General Public License as published
      8   by the Free Software Foundation; either version 2, or (at your
      9   option) any later version.
     10 
     11   libmicrohttpd is distributed in the hope that it will be useful, but
     12   WITHOUT ANY WARRANTY; without even the implied warranty of
     13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14   General Public License for more details.
     15 
     16   You should have received a copy of the GNU General Public License
     17   along with libmicrohttpd; see the file COPYING.  If not, write to the
     18   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     19   Boston, MA 02110-1301, USA.
     20 */
     21 
     22 /**
     23  * @file test_https_get_parallel.c
     24  * @brief  Testcase for libmicrohttpd HTTPS GET operations with single-threaded
     25  *         MHD daemon and several clients working in parallel
     26  * @author Sagie Amir
     27  * @author Christian Grothoff
     28  * @author Karlson2k (Evgeny Grin)
     29  */
     30 
     31 #include "platform.h"
     32 #include "microhttpd.h"
     33 #include <sys/stat.h>
     34 #include <limits.h>
     35 #include <curl/curl.h>
     36 #include <pthread.h>
     37 #ifdef MHD_HTTPS_REQUIRE_GCRYPT
     38 #include <gcrypt.h>
     39 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */
     40 #include "tls_test_common.h"
     41 #include "tls_test_keys.h"
     42 
     43 /* Turn any MHD_PANIC() or failing mhd_assert() reached from this
     44    test into a marked, classifiable test error (TESTING.md, P5). */
     45 #include "mhd_panic_tripwire.h"
     46 
     47 #if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 4
     48 #undef MHD_CPU_COUNT
     49 #endif
     50 #if ! defined(MHD_CPU_COUNT)
     51 #define MHD_CPU_COUNT 4
     52 #endif
     53 
     54 
     55 /**
     56  * used when spawning multiple threads executing curl server requests
     57  *
     58  */
     59 static void *
     60 https_transfer_thread_adapter (void *args)
     61 {
     62   static int nonnull;
     63   struct https_test_data *cargs = args;
     64   unsigned int ret;
     65 
     66   ret = test_https_transfer (NULL, cargs->port,
     67                              cargs->cipher_suite, cargs->proto_version);
     68   if (ret == 0)
     69     return NULL;
     70   return &nonnull;
     71 }
     72 
     73 
     74 /**
     75  * Test non-parallel requests.
     76  *
     77  * @return: 0 upon all client requests returning '0', 1 otherwise.
     78  *
     79  * TODO : make client_count a parameter - number of curl client threads to spawn
     80  */
     81 static unsigned int
     82 test_single_client (void *cls, uint16_t port, const char *cipher_suite,
     83                     int curl_proto_version)
     84 {
     85   void *client_thread_ret;
     86   struct https_test_data client_args =
     87   { NULL, port, cipher_suite, curl_proto_version };
     88   (void) cls;    /* Unused. Silent compiler warning. */
     89 
     90   client_thread_ret = https_transfer_thread_adapter (&client_args);
     91   if (client_thread_ret != NULL)
     92     return 1;
     93   return 0;
     94 }
     95 
     96 
     97 /**
     98  * Test parallel request handling.
     99  *
    100  * @return: 0 upon all client requests returning '0', 1 otherwise.
    101  *
    102  * TODO : make client_count a parameter - number of curl client threads to spawn
    103  */
    104 static unsigned int
    105 test_parallel_clients (void *cls, uint16_t port, const char *cipher_suite,
    106                        int curl_proto_version)
    107 {
    108   int i;
    109   int client_count = (MHD_CPU_COUNT - 1);
    110   void *client_thread_ret;
    111   pthread_t client_arr[client_count];
    112   struct https_test_data client_args =
    113   { NULL, port, cipher_suite, curl_proto_version };
    114   (void) cls;    /* Unused. Silent compiler warning. */
    115 
    116   for (i = 0; i < client_count; ++i)
    117   {
    118     if (pthread_create (&client_arr[i], NULL,
    119                         &https_transfer_thread_adapter, &client_args) != 0)
    120     {
    121       fprintf (stderr, "Error: failed to spawn test client threads.\n");
    122       return 1;
    123     }
    124   }
    125 
    126   /* check all client requests fulfilled correctly */
    127   for (i = 0; i < client_count; ++i)
    128   {
    129     if ((pthread_join (client_arr[i], &client_thread_ret) != 0) ||
    130         (client_thread_ret != NULL))
    131       return 1;
    132   }
    133 
    134   return 0;
    135 }
    136 
    137 
    138 int
    139 main (int argc, char *const *argv)
    140 {
    141   unsigned int errorCount = 0;
    142   uint16_t port;
    143   unsigned int iseed;
    144   (void) argc;   /* Unused. Silent compiler warning. */
    145 
    146   if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    147     port = 0;
    148   else
    149     port = 3020;
    150 
    151   /* initialize random seed used by curl clients */
    152   iseed = (unsigned int) time (NULL);
    153   srand (iseed);
    154   if (! testsuite_curl_global_init ())
    155     return 99;
    156 
    157   if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version)
    158   {
    159     fprintf (stderr, "Curl does not support SSL.  Cannot run the test.\n");
    160     return 77;
    161   }
    162 #ifdef EPOLL_SUPPORT
    163   errorCount +=
    164     test_wrap ("single threaded daemon, single client, epoll",
    165                &test_single_client,
    166                NULL, port,
    167                MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
    168                | MHD_USE_ERROR_LOG | MHD_USE_EPOLL,
    169                NULL, CURL_SSLVERSION_DEFAULT, MHD_OPTION_HTTPS_MEM_KEY,
    170                srv_self_signed_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
    171                srv_self_signed_cert_pem, MHD_OPTION_END);
    172 #endif
    173   errorCount +=
    174     test_wrap ("single threaded daemon, single client", &test_single_client,
    175                NULL, port,
    176                MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
    177                | MHD_USE_ERROR_LOG,
    178                NULL, CURL_SSLVERSION_DEFAULT, MHD_OPTION_HTTPS_MEM_KEY,
    179                srv_self_signed_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
    180                srv_self_signed_cert_pem, MHD_OPTION_END);
    181 #ifdef EPOLL_SUPPORT
    182   errorCount +=
    183     test_wrap ("single threaded daemon, parallel clients, epoll",
    184                &test_parallel_clients, NULL, port,
    185                MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
    186                | MHD_USE_ERROR_LOG | MHD_USE_EPOLL,
    187                NULL, CURL_SSLVERSION_DEFAULT, MHD_OPTION_HTTPS_MEM_KEY,
    188                srv_self_signed_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
    189                srv_self_signed_cert_pem, MHD_OPTION_END);
    190 #endif
    191   errorCount +=
    192     test_wrap ("single threaded daemon, parallel clients",
    193                &test_parallel_clients, NULL, port,
    194                MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
    195                | MHD_USE_ERROR_LOG,
    196                NULL, CURL_SSLVERSION_DEFAULT, MHD_OPTION_HTTPS_MEM_KEY,
    197                srv_self_signed_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
    198                srv_self_signed_cert_pem, MHD_OPTION_END);
    199 
    200   curl_global_cleanup ();
    201   if (errorCount != 0)
    202     fprintf (stderr, "Failed test: %s, error: %u.\n", argv[0], errorCount);
    203   return errorCount != 0 ? 1 : 0;
    204 }