Blame src/testcurl/https/test_https_get_parallel_threads.c

Packit 875988
/*
Packit 875988
  This file is part of libmicrohttpd
Packit 875988
  Copyright (C) 2007 Christian Grothoff
Packit 875988
Packit 875988
  libmicrohttpd is free software; you can redistribute it and/or modify
Packit 875988
  it under the terms of the GNU General Public License as published
Packit 875988
  by the Free Software Foundation; either version 2, or (at your
Packit 875988
  option) any later version.
Packit 875988
Packit 875988
  libmicrohttpd is distributed in the hope that it will be useful, but
Packit 875988
  WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 875988
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 875988
  General Public License for more details.
Packit 875988
Packit 875988
  You should have received a copy of the GNU General Public License
Packit 875988
  along with libmicrohttpd; see the file COPYING.  If not, write to the
Packit 875988
  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit 875988
  Boston, MA 02110-1301, USA.
Packit 875988
*/
Packit 875988
Packit 875988
/**
Packit 875988
 * @file tls_thread_mode_test.c
Packit 875988
 * @brief  Testcase for libmicrohttpd HTTPS GET operations
Packit 875988
 * @author Sagie Amir
Packit 875988
 * @author Christian Grothoff
Packit 875988
 *
Packit 875988
 * TODO: add test for external select!
Packit 875988
 */
Packit 875988
Packit 875988
#include "platform.h"
Packit 875988
#include "microhttpd.h"
Packit 875988
#include <sys/stat.h>
Packit 875988
#include <limits.h>
Packit 875988
#include <curl/curl.h>
Packit 875988
#include <pthread.h>
Packit 875988
#ifdef MHD_HTTPS_REQUIRE_GRYPT
Packit 875988
#include <gcrypt.h>
Packit 875988
#endif /* MHD_HTTPS_REQUIRE_GRYPT */
Packit 875988
#include "tls_test_common.h"
Packit 875988
Packit 875988
#if defined(CPU_COUNT) && (CPU_COUNT+0) < 4
Packit 875988
#undef CPU_COUNT
Packit 875988
#endif
Packit 875988
#if !defined(CPU_COUNT)
Packit 875988
#define CPU_COUNT 4
Packit 875988
#endif
Packit 875988
Packit 875988
extern const char srv_key_pem[];
Packit 875988
extern const char srv_self_signed_cert_pem[];
Packit 875988
Packit 875988
int curl_check_version (const char *req_version, ...);
Packit 875988
Packit 875988
/**
Packit 875988
 * used when spawning multiple threads executing curl server requests
Packit 875988
 *
Packit 875988
 */
Packit 875988
static void *
Packit 875988
https_transfer_thread_adapter (void *args)
Packit 875988
{
Packit 875988
  static int nonnull;
Packit 875988
  struct https_test_data *cargs = args;
Packit 875988
  int ret;
Packit 875988
Packit 875988
  /* time spread incomming requests */
Packit 875988
  usleep ((useconds_t) 10.0 * ((double) rand ()) / ((double) RAND_MAX));
Packit 875988
  ret = test_https_transfer (cargs->cls, cargs->port,
Packit 875988
                             cargs->cipher_suite, cargs->proto_version);
Packit 875988
  if (ret == 0)
Packit 875988
    return NULL;
Packit 875988
  return &nonnull;
Packit 875988
}
Packit 875988
Packit 875988
/**
Packit 875988
 * Test non-parallel requests.
Packit 875988
 *
Packit 875988
 * @return: 0 upon all client requests returning '0', -1 otherwise.
Packit 875988
 *
Packit 875988
 * TODO : make client_count a parameter - numver of curl client threads to spawn
Packit 875988
 */
Packit 875988
static int
Packit 875988
test_single_client (void *cls, int port, const char *cipher_suite,
Packit 875988
                    int curl_proto_version)
Packit 875988
{
Packit 875988
  void *client_thread_ret;
Packit 875988
  struct https_test_data client_args =
Packit 875988
    { NULL, port, cipher_suite, curl_proto_version };
Packit 875988
  (void)cls;    /* Unused. Silent compiler warning. */
Packit 875988
Packit 875988
  client_thread_ret = https_transfer_thread_adapter (&client_args);
Packit 875988
  if (client_thread_ret != NULL)
Packit 875988
    return -1;
Packit 875988
  return 0;
Packit 875988
}
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Test parallel request handling.
Packit 875988
 *
Packit 875988
 * @return: 0 upon all client requests returning '0', -1 otherwise.
Packit 875988
 *
Packit 875988
 * TODO : make client_count a parameter - numver of curl client threads to spawn
Packit 875988
 */
Packit 875988
static int
Packit 875988
test_parallel_clients (void *cls, int port, const char *cipher_suite,
Packit 875988
                       int curl_proto_version)
Packit 875988
{
Packit 875988
  int i;
Packit 875988
  int client_count = (CPU_COUNT - 1);
Packit 875988
  void *client_thread_ret;
Packit 875988
  pthread_t client_arr[client_count];
Packit 875988
  struct https_test_data client_args =
Packit 875988
    { NULL, port, cipher_suite, curl_proto_version };
Packit 875988
  (void)cls;    /* Unused. Silent compiler warning. */
Packit 875988
Packit 875988
  for (i = 0; i < client_count; ++i)
Packit 875988
    {
Packit 875988
      if (pthread_create (&client_arr[i], NULL,
Packit 875988
                          &https_transfer_thread_adapter, &client_args) != 0)
Packit 875988
        {
Packit 875988
          fprintf (stderr, "Error: failed to spawn test client threads.\n");
Packit 875988
Packit 875988
          return -1;
Packit 875988
        }
Packit 875988
    }
Packit 875988
Packit 875988
  /* check all client requests fulfilled correctly */
Packit 875988
  for (i = 0; i < client_count; ++i)
Packit 875988
    {
Packit 875988
      if ((pthread_join (client_arr[i], &client_thread_ret) != 0) ||
Packit 875988
          (client_thread_ret != NULL))
Packit 875988
        return -1;
Packit 875988
    }
Packit 875988
Packit 875988
  return 0;
Packit 875988
}
Packit 875988
Packit 875988
Packit 875988
int
Packit 875988
main (int argc, char *const *argv)
Packit 875988
{
Packit 875988
  unsigned int errorCount = 0;
Packit 875988
  const char *ssl_version;
Packit 875988
  int port;
Packit 875988
  (void)argc;   /* Unused. Silent compiler warning. */
Packit 875988
Packit 875988
  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
Packit 875988
    port = 0;
Packit 875988
  else
Packit 875988
    port = 3010;
Packit 875988
Packit 875988
  /* initialize random seed used by curl clients */
Packit 875988
  unsigned int iseed = (unsigned int) time (NULL);
Packit 875988
Packit 875988
#ifdef MHD_HTTPS_REQUIRE_GRYPT
Packit 875988
#ifdef GCRYCTL_INITIALIZATION_FINISHED
Packit 875988
  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
Packit 875988
#endif
Packit 875988
#endif /* MHD_HTTPS_REQUIRE_GRYPT */
Packit 875988
  srand (iseed);
Packit 875988
  if (!testsuite_curl_global_init ())
Packit 875988
    return 99;
Packit 875988
  ssl_version = curl_version_info (CURLVERSION_NOW)->ssl_version;
Packit 875988
  if (NULL == ssl_version)
Packit 875988
    {
Packit 875988
      fprintf (stderr, "Curl does not support SSL.  Cannot run the test.\n");
Packit 875988
      curl_global_cleanup ();
Packit 875988
      return 77;
Packit 875988
    }
Packit 875988
  if (0 != strncmp (ssl_version, "GnuTLS", 6))
Packit 875988
    {
Packit 875988
      fprintf (stderr, "This test can be run only with libcurl-gnutls.\n");
Packit 875988
      curl_global_cleanup ();
Packit 875988
      return 77;
Packit 875988
    }
Packit 875988
Packit 875988
  char *aes256_sha = "AES256-SHA";
Packit 875988
  if (curl_uses_nss_ssl() == 0)
Packit 875988
    {
Packit 875988
      aes256_sha = "rsa_aes_256_sha";
Packit 875988
    }
Packit 875988
Packit 875988
  errorCount +=
Packit 875988
    test_wrap ("multi threaded daemon, single client", &test_single_client,
Packit 875988
               NULL, port,
Packit 875988
               MHD_USE_TLS | MHD_USE_ERROR_LOG | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD,
Packit 875988
               aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
Packit 875988
               srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
Packit 875988
               srv_self_signed_cert_pem, MHD_OPTION_END);
Packit 875988
Packit 875988
  errorCount +=
Packit 875988
    test_wrap ("multi threaded daemon, parallel client",
Packit 875988
               &test_parallel_clients, NULL, port,
Packit 875988
               MHD_USE_TLS | MHD_USE_ERROR_LOG | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD,
Packit 875988
               aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
Packit 875988
               srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
Packit 875988
               srv_self_signed_cert_pem, MHD_OPTION_END);
Packit 875988
Packit 875988
  if (errorCount != 0)
Packit 875988
    fprintf (stderr, "Failed test: %s, error: %u.\n", argv[0], errorCount);
Packit 875988
Packit 875988
  curl_global_cleanup ();
Packit 875988
  return errorCount != 0 ? 1 : 0;
Packit 875988
}