libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

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 }