test_options.c (8131B)
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., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 21 /** 22 * @file test_options.c 23 * @brief Testcase for libmicrohttpd HTTPS GET operations 24 * @author Sagie Amir 25 */ 26 27 #include "platform.h" 28 #include "microhttpd.h" 29 #include "mhd_sockets.h" 30 31 /* Turn any MHD_PANIC() or failing mhd_assert() reached from this 32 test into a marked, classifiable test error (TESTING.md, P5). */ 33 #include "mhd_panic_tripwire.h" 34 35 static enum MHD_Result 36 ahc_echo (void *cls, 37 struct MHD_Connection *connection, 38 const char *url, 39 const char *method, 40 const char *version, 41 const char *upload_data, size_t *upload_data_size, 42 void **req_cls) 43 { 44 (void) cls; 45 (void) connection; 46 (void) url; 47 (void) method; 48 (void) version; 49 (void) upload_data; 50 (void) upload_data_size; 51 (void) req_cls; 52 53 return 0; 54 } 55 56 57 static unsigned int 58 test_wrap_loc (const char *test_name, unsigned int (*test)(void)) 59 { 60 unsigned int ret; 61 62 fprintf (stdout, "running test: %s ", test_name); 63 ret = test (); 64 if (ret == 0) 65 { 66 fprintf (stdout, "[pass]\n"); 67 } 68 else 69 { 70 fprintf (stdout, "[fail]\n"); 71 } 72 return ret; 73 } 74 75 76 /** 77 * Test daemon initialization with the MHD_OPTION_SOCK_ADDR or 78 * the MHD_OPTION_SOCK_ADDR_LEN options 79 */ 80 static unsigned int 81 test_ip_addr_option (void) 82 { 83 struct MHD_Daemon *d; 84 const union MHD_DaemonInfo *dinfo; 85 struct sockaddr_in daemon_ip_addr; 86 uint16_t port4; 87 #if defined(HAVE_INET6) && defined(USE_IPV6_TESTING) 88 struct sockaddr_in6 daemon_ip_addr6; 89 uint16_t port6; 90 #endif 91 unsigned int ret; 92 93 memset (&daemon_ip_addr, 0, sizeof (struct sockaddr_in)); 94 daemon_ip_addr.sin_family = AF_INET; 95 daemon_ip_addr.sin_port = 0; 96 daemon_ip_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); 97 port4 = 0; 98 99 #if defined(HAVE_INET6) && defined(USE_IPV6_TESTING) 100 memset (&daemon_ip_addr6, 0, sizeof (struct sockaddr_in6)); 101 daemon_ip_addr6.sin6_family = AF_INET6; 102 daemon_ip_addr6.sin6_port = 0; 103 daemon_ip_addr6.sin6_addr = in6addr_loopback; 104 port6 = 0; 105 #endif 106 107 ret = 0; 108 109 d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0, 110 NULL, NULL, &ahc_echo, NULL, 111 MHD_OPTION_SOCK_ADDR, &daemon_ip_addr, 112 MHD_OPTION_END); 113 114 if (d == 0) 115 return 1; 116 117 dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); 118 if (NULL == dinfo) 119 ret |= 1 << 1; 120 else 121 port4 = dinfo->port; 122 123 MHD_stop_daemon (d); 124 125 126 daemon_ip_addr.sin_port = htons (port4); 127 d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0, 128 NULL, NULL, &ahc_echo, NULL, 129 MHD_OPTION_SOCK_ADDR_LEN, 130 (socklen_t) sizeof(daemon_ip_addr), &daemon_ip_addr, 131 MHD_OPTION_END); 132 133 if (d == 0) 134 return 1; 135 136 dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); 137 if (NULL == dinfo) 138 ret |= 1 << 1; 139 else if (port4 != dinfo->port) 140 ret |= 1 << 2; 141 142 MHD_stop_daemon (d); 143 144 145 d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0, 146 NULL, NULL, &ahc_echo, NULL, 147 MHD_OPTION_SOCK_ADDR_LEN, 148 (socklen_t) (sizeof(daemon_ip_addr) / 2), 149 &daemon_ip_addr, 150 MHD_OPTION_END); 151 152 if (NULL != d) 153 { 154 MHD_stop_daemon (d); 155 return 1 << 3; 156 } 157 158 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 159 160 daemon_ip_addr.sin_len = (socklen_t) sizeof(daemon_ip_addr); 161 d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0, 162 NULL, NULL, &ahc_echo, NULL, 163 MHD_OPTION_SOCK_ADDR_LEN, 164 (socklen_t) sizeof(daemon_ip_addr), &daemon_ip_addr, 165 MHD_OPTION_END); 166 167 if (d == 0) 168 return 1; 169 170 dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); 171 if (NULL == dinfo) 172 ret |= 1 << 1; 173 else if (port4 != dinfo->port) 174 ret |= 1 << 2; 175 176 MHD_stop_daemon (d); 177 178 179 daemon_ip_addr.sin_len = (socklen_t) (sizeof(daemon_ip_addr) / 2); 180 d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0, 181 NULL, NULL, &ahc_echo, NULL, 182 MHD_OPTION_SOCK_ADDR_LEN, 183 (socklen_t) sizeof(daemon_ip_addr), &daemon_ip_addr, 184 MHD_OPTION_END); 185 186 if (NULL != d) 187 { 188 MHD_stop_daemon (d); 189 return 1 << 3; 190 } 191 192 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ 193 194 195 #if defined(HAVE_INET6) && defined(USE_IPV6_TESTING) 196 d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_IPv6 197 | MHD_USE_NO_THREAD_SAFETY, 0, 198 NULL, NULL, &ahc_echo, NULL, 199 MHD_OPTION_SOCK_ADDR, &daemon_ip_addr6, 200 MHD_OPTION_END); 201 202 if (d == 0) 203 return 1; 204 205 dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); 206 if (NULL == dinfo) 207 ret |= 1 << 1; 208 else 209 port6 = dinfo->port; 210 211 MHD_stop_daemon (d); 212 213 214 daemon_ip_addr6.sin6_port = htons (port6); 215 d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0, 216 NULL, NULL, &ahc_echo, NULL, 217 MHD_OPTION_SOCK_ADDR_LEN, 218 (socklen_t) sizeof(daemon_ip_addr6), &daemon_ip_addr6, 219 MHD_OPTION_END); 220 221 if (d == 0) 222 return 1; 223 224 dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); 225 if (NULL == dinfo) 226 ret |= 1 << 1; 227 else if (port6 != dinfo->port) 228 ret |= 1 << 2; 229 230 MHD_stop_daemon (d); 231 232 233 d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0, 234 NULL, NULL, &ahc_echo, NULL, 235 MHD_OPTION_SOCK_ADDR_LEN, 236 (socklen_t) (sizeof(daemon_ip_addr6) / 2), 237 &daemon_ip_addr6, 238 MHD_OPTION_END); 239 240 if (NULL != d) 241 { 242 MHD_stop_daemon (d); 243 return 1 << 3; 244 } 245 246 #if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN) 247 248 daemon_ip_addr6.sin6_len = (socklen_t) sizeof(daemon_ip_addr6); 249 d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0, 250 NULL, NULL, &ahc_echo, NULL, 251 MHD_OPTION_SOCK_ADDR_LEN, 252 (socklen_t) sizeof(daemon_ip_addr6), &daemon_ip_addr6, 253 MHD_OPTION_END); 254 255 if (d == 0) 256 return 1; 257 258 dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); 259 if (NULL == dinfo) 260 ret |= 1 << 1; 261 else if (port6 != dinfo->port) 262 ret |= 1 << 2; 263 264 MHD_stop_daemon (d); 265 266 267 daemon_ip_addr6.sin6_len = (socklen_t) (sizeof(daemon_ip_addr6) / 2); 268 d = MHD_start_daemon (MHD_USE_ERROR_LOG | MHD_USE_NO_THREAD_SAFETY, 0, 269 NULL, NULL, &ahc_echo, NULL, 270 MHD_OPTION_SOCK_ADDR_LEN, 271 (socklen_t) sizeof(daemon_ip_addr6), &daemon_ip_addr6, 272 MHD_OPTION_END); 273 274 if (NULL != d) 275 { 276 MHD_stop_daemon (d); 277 return 1 << 3; 278 } 279 280 #endif /* HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN */ 281 #endif /* HAVE_INET6 && USE_IPV6_TESTING */ 282 283 return ret; 284 } 285 286 287 /* setup a temporary transfer test file */ 288 int 289 main (int argc, char *const *argv) 290 { 291 unsigned int errorCount = 0; 292 (void) argc; (void) argv; /* Unused. Silent compiler warning. */ 293 294 errorCount += test_wrap_loc ("ip addr option", &test_ip_addr_option); 295 296 return errorCount != 0; 297 }