libmicrohttpd

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

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 }