test_termination.c (4341B)
1 /* 2 This file is part of libmicrohttpd 3 Copyright (C) 2009 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 daemontest_termination.c 24 * @brief Testcase for libmicrohttpd tolerating client not closing immediately 25 * @author hollosig 26 * @author Karlson2k (Evgeny Grin) 27 */ 28 29 #include "platform.h" 30 #include <stdio.h> 31 #include <string.h> 32 #include <stdint.h> 33 #include <stdarg.h> 34 #include <stdlib.h> 35 #include <sys/types.h> 36 #include <microhttpd.h> 37 #include <unistd.h> 38 #include <curl/curl.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 #ifndef __MINGW32__ 45 #include <sys/select.h> 46 #include <sys/socket.h> 47 #endif 48 49 #ifdef _WIN32 50 #ifndef WIN32_LEAN_AND_MEAN 51 #define WIN32_LEAN_AND_MEAN 1 52 #endif /* !WIN32_LEAN_AND_MEAN */ 53 #include <windows.h> 54 #endif 55 56 static enum MHD_Result 57 connection_handler (void *cls, 58 struct MHD_Connection *connection, 59 const char *url, 60 const char *method, 61 const char *version, 62 const char *upload_data, size_t *upload_data_size, 63 void **req_cls) 64 { 65 static int i; 66 struct MHD_Response *response; 67 enum MHD_Result ret; 68 (void) cls; (void) url; /* Unused. Silent compiler warning. */ 69 (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */ 70 (void) upload_data_size; /* Unused. Silent compiler warning. */ 71 72 if (*req_cls == NULL) 73 { 74 *req_cls = &i; 75 return MHD_YES; 76 } 77 78 if (*upload_data_size != 0) 79 { 80 (*upload_data_size) = 0; 81 return MHD_YES; 82 } 83 84 response = 85 MHD_create_response_from_buffer_static (strlen ("Response"), "Response"); 86 ret = MHD_queue_response (connection, MHD_HTTP_OK, response); 87 MHD_destroy_response (response); 88 89 return ret; 90 } 91 92 93 static size_t 94 write_data (void *ptr, size_t size, size_t nmemb, void *stream) 95 { 96 (void) ptr; (void) stream; /* Unused. Silent compiler warning. */ 97 return size * nmemb; 98 } 99 100 101 int 102 main (void) 103 { 104 struct MHD_Daemon *daemon; 105 uint16_t port; 106 char url[255]; 107 CURL *curl; 108 CURLcode success; 109 110 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) 111 port = 0; 112 else 113 port = 1490; 114 115 116 daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION 117 | MHD_USE_INTERNAL_POLLING_THREAD 118 | MHD_USE_ERROR_LOG, 119 port, 120 NULL, 121 NULL, connection_handler, NULL, MHD_OPTION_END); 122 123 if (daemon == NULL) 124 { 125 fprintf (stderr, "Daemon cannot be started!"); 126 exit (1); 127 } 128 if (0 == port) 129 { 130 const union MHD_DaemonInfo *dinfo; 131 dinfo = MHD_get_daemon_info (daemon, MHD_DAEMON_INFO_BIND_PORT); 132 if ((NULL == dinfo) || (0 == dinfo->port) ) 133 { 134 MHD_stop_daemon (daemon); return 32; 135 } 136 port = dinfo->port; 137 } 138 139 curl = curl_easy_init (); 140 /* curl_easy_setopt(curl, CURLOPT_POST, 1L); */ 141 snprintf (url, 142 sizeof (url), 143 "http://127.0.0.1:%u", 144 (unsigned int) port); 145 curl_easy_setopt (curl, CURLOPT_URL, url); 146 curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data); 147 148 success = curl_easy_perform (curl); 149 if (success != 0) 150 { 151 fprintf (stderr, "CURL Error"); 152 exit (1); 153 } 154 /* CPU used to go crazy here */ 155 (void) sleep (1); 156 157 curl_easy_cleanup (curl); 158 MHD_stop_daemon (daemon); 159 160 return 0; 161 }