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