test_https_multi_daemon.c (5441B)
1 /* 2 This file is part of libmicrohttpd 3 Copyright (C) 2007 Christian Grothoff 4 Copyright (C) 2016-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_multi_daemon.c 24 * @brief Testcase for libmicrohttpd multiple HTTPS daemon scenario 25 * @author Sagie Amir 26 * @author Karlson2k (Evgeny Grin) 27 */ 28 29 #include "platform.h" 30 #include "microhttpd.h" 31 #include <curl/curl.h> 32 #include <limits.h> 33 #include <sys/stat.h> 34 #ifdef MHD_HTTPS_REQUIRE_GCRYPT 35 #include <gcrypt.h> 36 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ 37 #include "tls_test_common.h" 38 #include "tls_test_keys.h" 39 40 /* 41 * assert initiating two separate daemons and having one shut down 42 * doesn't affect the other 43 */ 44 static unsigned int 45 test_concurent_daemon_pair (void *cls, 46 const char *cipher_suite, 47 int proto_version) 48 { 49 unsigned int ret; 50 enum test_get_result res; 51 struct MHD_Daemon *d1; 52 struct MHD_Daemon *d2; 53 uint16_t port1, port2; 54 (void) cls; /* Unused. Silent compiler warning. */ 55 56 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) 57 port1 = port2 = 0; 58 else 59 { 60 port1 = 3050; 61 port2 = 3051; 62 } 63 64 d1 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION 65 | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS 66 | MHD_USE_ERROR_LOG, port1, 67 NULL, NULL, &http_ahc, NULL, 68 MHD_OPTION_HTTPS_MEM_KEY, srv_self_signed_key_pem, 69 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 70 MHD_OPTION_END); 71 72 if (d1 == NULL) 73 { 74 fprintf (stderr, MHD_E_SERVER_INIT); 75 return 1; 76 } 77 if (0 == port1) 78 { 79 const union MHD_DaemonInfo *dinfo; 80 dinfo = MHD_get_daemon_info (d1, MHD_DAEMON_INFO_BIND_PORT); 81 if ((NULL == dinfo) || (0 == dinfo->port) ) 82 { 83 fprintf (stderr, "Cannot detect daemon bind port.\n"); 84 MHD_stop_daemon (d1); 85 return 1; 86 } 87 port1 = dinfo->port; 88 } 89 90 d2 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION 91 | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS 92 | MHD_USE_ERROR_LOG, port2, 93 NULL, NULL, &http_ahc, NULL, 94 MHD_OPTION_HTTPS_MEM_KEY, srv_self_signed_key_pem, 95 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 96 MHD_OPTION_END); 97 98 if (d2 == NULL) 99 { 100 MHD_stop_daemon (d1); 101 fprintf (stderr, MHD_E_SERVER_INIT); 102 return 1; 103 } 104 if (0 == port2) 105 { 106 const union MHD_DaemonInfo *dinfo; 107 dinfo = MHD_get_daemon_info (d2, MHD_DAEMON_INFO_BIND_PORT); 108 if ((NULL == dinfo) || (0 == dinfo->port) ) 109 { 110 fprintf (stderr, "Cannot detect daemon bind port.\n"); 111 MHD_stop_daemon (d1); 112 MHD_stop_daemon (d2); 113 return 1; 114 } 115 port2 = dinfo->port; 116 } 117 118 res = 119 test_daemon_get (NULL, cipher_suite, proto_version, port1, 0); 120 ret = (unsigned int) res; 121 if ((TEST_GET_HARD_ERROR == res) || 122 (TEST_GET_CURL_GEN_ERROR == res)) 123 { 124 fprintf (stderr, "libcurl error.\nTest aborted.\n"); 125 MHD_stop_daemon (d2); 126 MHD_stop_daemon (d1); 127 return 99; 128 } 129 130 res = 131 test_daemon_get (NULL, cipher_suite, proto_version, 132 port2, 0); 133 ret += (unsigned int) res; 134 if ((TEST_GET_HARD_ERROR == res) || 135 (TEST_GET_CURL_GEN_ERROR == res)) 136 { 137 fprintf (stderr, "libcurl error.\nTest aborted.\n"); 138 MHD_stop_daemon (d2); 139 MHD_stop_daemon (d1); 140 return 99; 141 } 142 143 MHD_stop_daemon (d2); 144 res = 145 test_daemon_get (NULL, cipher_suite, proto_version, port1, 0); 146 ret += (unsigned int) res; 147 if ((TEST_GET_HARD_ERROR == res) || 148 (TEST_GET_CURL_GEN_ERROR == res)) 149 { 150 fprintf (stderr, "libcurl error.\nTest aborted.\n"); 151 MHD_stop_daemon (d1); 152 return 99; 153 } 154 MHD_stop_daemon (d1); 155 return ret; 156 } 157 158 159 int 160 main (int argc, char *const *argv) 161 { 162 unsigned int errorCount; 163 (void) argc; (void) argv; /* Unused. Silent compiler warning. */ 164 165 #ifdef MHD_HTTPS_REQUIRE_GCRYPT 166 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); 167 #ifdef GCRYCTL_INITIALIZATION_FINISHED 168 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); 169 #endif 170 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ 171 if (! testsuite_curl_global_init ()) 172 return 99; 173 if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version) 174 { 175 fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n"); 176 curl_global_cleanup (); 177 return 77; 178 } 179 180 errorCount = 181 test_concurent_daemon_pair (NULL, NULL, CURL_SSLVERSION_DEFAULT); 182 183 print_test_result (errorCount, "concurent_daemon_pair"); 184 185 curl_global_cleanup (); 186 if (99 == errorCount) 187 return 99; 188 189 return errorCount != 0 ? 1 : 0; 190 }