test_https_multi_daemon.c (5608B)
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 /* Turn any MHD_PANIC() or failing mhd_assert() reached from this 41 test into a marked, classifiable test error (TESTING.md, P5). */ 42 #include "mhd_panic_tripwire.h" 43 44 /* 45 * assert initiating two separate daemons and having one shut down 46 * doesn't affect the other 47 */ 48 static unsigned int 49 test_concurent_daemon_pair (void *cls, 50 const char *cipher_suite, 51 int proto_version) 52 { 53 unsigned int ret; 54 enum test_get_result res; 55 struct MHD_Daemon *d1; 56 struct MHD_Daemon *d2; 57 uint16_t port1, port2; 58 (void) cls; /* Unused. Silent compiler warning. */ 59 60 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) 61 port1 = port2 = 0; 62 else 63 { 64 port1 = 3050; 65 port2 = 3051; 66 } 67 68 d1 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION 69 | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS 70 | MHD_USE_ERROR_LOG, port1, 71 NULL, NULL, &http_ahc, NULL, 72 MHD_OPTION_HTTPS_MEM_KEY, srv_self_signed_key_pem, 73 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 74 MHD_OPTION_END); 75 76 if (d1 == NULL) 77 { 78 fprintf (stderr, MHD_E_SERVER_INIT); 79 return 1; 80 } 81 if (0 == port1) 82 { 83 const union MHD_DaemonInfo *dinfo; 84 dinfo = MHD_get_daemon_info (d1, MHD_DAEMON_INFO_BIND_PORT); 85 if ((NULL == dinfo) || (0 == dinfo->port) ) 86 { 87 fprintf (stderr, "Cannot detect daemon bind port.\n"); 88 MHD_stop_daemon (d1); 89 return 1; 90 } 91 port1 = dinfo->port; 92 } 93 94 d2 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION 95 | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS 96 | MHD_USE_ERROR_LOG, port2, 97 NULL, NULL, &http_ahc, NULL, 98 MHD_OPTION_HTTPS_MEM_KEY, srv_self_signed_key_pem, 99 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 100 MHD_OPTION_END); 101 102 if (d2 == NULL) 103 { 104 MHD_stop_daemon (d1); 105 fprintf (stderr, MHD_E_SERVER_INIT); 106 return 1; 107 } 108 if (0 == port2) 109 { 110 const union MHD_DaemonInfo *dinfo; 111 dinfo = MHD_get_daemon_info (d2, MHD_DAEMON_INFO_BIND_PORT); 112 if ((NULL == dinfo) || (0 == dinfo->port) ) 113 { 114 fprintf (stderr, "Cannot detect daemon bind port.\n"); 115 MHD_stop_daemon (d1); 116 MHD_stop_daemon (d2); 117 return 1; 118 } 119 port2 = dinfo->port; 120 } 121 122 res = 123 test_daemon_get (NULL, cipher_suite, proto_version, port1, 0); 124 ret = (unsigned int) res; 125 if ((TEST_GET_HARD_ERROR == res) || 126 (TEST_GET_CURL_GEN_ERROR == res)) 127 { 128 fprintf (stderr, "libcurl error.\nTest aborted.\n"); 129 MHD_stop_daemon (d2); 130 MHD_stop_daemon (d1); 131 return 99; 132 } 133 134 res = 135 test_daemon_get (NULL, cipher_suite, proto_version, 136 port2, 0); 137 ret += (unsigned int) res; 138 if ((TEST_GET_HARD_ERROR == res) || 139 (TEST_GET_CURL_GEN_ERROR == res)) 140 { 141 fprintf (stderr, "libcurl error.\nTest aborted.\n"); 142 MHD_stop_daemon (d2); 143 MHD_stop_daemon (d1); 144 return 99; 145 } 146 147 MHD_stop_daemon (d2); 148 res = 149 test_daemon_get (NULL, cipher_suite, proto_version, port1, 0); 150 ret += (unsigned int) res; 151 if ((TEST_GET_HARD_ERROR == res) || 152 (TEST_GET_CURL_GEN_ERROR == res)) 153 { 154 fprintf (stderr, "libcurl error.\nTest aborted.\n"); 155 MHD_stop_daemon (d1); 156 return 99; 157 } 158 MHD_stop_daemon (d1); 159 return ret; 160 } 161 162 163 int 164 main (int argc, char *const *argv) 165 { 166 unsigned int errorCount; 167 (void) argc; (void) argv; /* Unused. Silent compiler warning. */ 168 169 #ifdef MHD_HTTPS_REQUIRE_GCRYPT 170 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); 171 #ifdef GCRYCTL_INITIALIZATION_FINISHED 172 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); 173 #endif 174 #endif /* MHD_HTTPS_REQUIRE_GCRYPT */ 175 if (! testsuite_curl_global_init ()) 176 return 99; 177 if (NULL == curl_version_info (CURLVERSION_NOW)->ssl_version) 178 { 179 fprintf (stderr, "Curl does not support SSL. Cannot run the test.\n"); 180 curl_global_cleanup (); 181 return 77; 182 } 183 184 errorCount = 185 test_concurent_daemon_pair (NULL, NULL, CURL_SSLVERSION_DEFAULT); 186 187 print_test_result (errorCount, "concurent_daemon_pair"); 188 189 curl_global_cleanup (); 190 if (99 == errorCount) 191 return 99; 192 193 return errorCount != 0 ? 1 : 0; 194 }