libmicrohttpd

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

simplepost.c (5964B)


      1 /* Feel free to use this example code in any way
      2    you see fit (Public Domain) */
      3 
      4 #include <sys/types.h>
      5 #ifndef _WIN32
      6 #include <sys/select.h>
      7 #include <sys/socket.h>
      8 #else
      9 #include <winsock2.h>
     10 #endif
     11 #include <microhttpd.h>
     12 #include <stdio.h>
     13 #include <string.h>
     14 #include <stdlib.h>
     15 
     16 #if defined(_MSC_VER) && _MSC_VER + 0 <= 1800
     17 /* Substitution is OK while return value is not used */
     18 #define snprintf _snprintf
     19 #endif
     20 
     21 #define PORT            8888
     22 #define POSTBUFFERSIZE  512
     23 #define MAXNAMESIZE     20
     24 #define MAXANSWERSIZE   512
     25 
     26 struct connection_info_struct
     27 {
     28   enum { GET, POST } connectiontype;
     29   char *answerstring;
     30   struct MHD_PostProcessor *postprocessor;
     31 };
     32 
     33 static const char *askpage =
     34   "<html><body>\n"
     35   "What's your name, Sir?<br>\n"
     36   "<form action=\"/namepost\" method=\"post\">\n"
     37   "<input name=\"name\" type=\"text\">\n"
     38   "<input type=\"submit\" value=\" Send \"></form>\n"
     39   "</body></html>";
     40 
     41 #define GREETINGPAGE \
     42         "<html><body><h1>Welcome, %s!</center></h1></body></html>"
     43 
     44 static const char *errorpage =
     45   "<html><body>This doesn't seem to be right.</body></html>";
     46 
     47 
     48 static enum MHD_Result
     49 send_page (struct MHD_Connection *connection,
     50            const char *page)
     51 {
     52   enum MHD_Result ret;
     53   struct MHD_Response *response;
     54 
     55   response = MHD_create_response_from_buffer_static (strlen (page),
     56                                                      page);
     57   if (! response)
     58     return MHD_NO;
     59   ret = MHD_queue_response (connection,
     60                             MHD_HTTP_OK,
     61                             response);
     62   MHD_destroy_response (response);
     63   return ret;
     64 }
     65 
     66 
     67 static enum MHD_Result
     68 iterate_post (void *coninfo_cls,
     69               enum MHD_ValueKind kind,
     70               const char *key,
     71               const char *filename,
     72               const char *content_type,
     73               const char *transfer_encoding,
     74               const char *data,
     75               uint64_t off,
     76               size_t size)
     77 {
     78   struct connection_info_struct *con_info = coninfo_cls;
     79 
     80   (void) kind;               /* Unused. Silent compiler warning. */
     81   (void) filename;           /* Unused. Silent compiler warning. */
     82   (void) content_type;       /* Unused. Silent compiler warning. */
     83   (void) transfer_encoding;  /* Unused. Silent compiler warning. */
     84   (void) off;                /* Unused. Silent compiler warning. */
     85   if (0 != strcmp (key,
     86                    "name"))
     87     return MHD_YES;
     88   if ( (size > 0) &&
     89        (size <= MAXNAMESIZE) )
     90   {
     91     char *answerstring;
     92 
     93     answerstring = malloc (MAXANSWERSIZE);
     94     if (! answerstring)
     95       return MHD_NO;
     96     snprintf (answerstring,
     97               MAXANSWERSIZE,
     98               GREETINGPAGE,
     99               data);
    100     con_info->answerstring = answerstring;
    101   }
    102   else
    103   {
    104     con_info->answerstring = NULL;
    105   }
    106   return MHD_YES;
    107 }
    108 
    109 
    110 static void
    111 request_completed (void *cls,
    112                    struct MHD_Connection *connection,
    113                    void **req_cls,
    114                    enum MHD_RequestTerminationCode toe)
    115 {
    116   struct connection_info_struct *con_info = *req_cls;
    117 
    118   (void) cls;         /* Unused. Silent compiler warning. */
    119   (void) connection;  /* Unused. Silent compiler warning. */
    120   (void) toe;         /* Unused. Silent compiler warning. */
    121   if (NULL == con_info)
    122     return;
    123   if (POST == con_info->connectiontype)
    124   {
    125     MHD_destroy_post_processor (con_info->postprocessor);
    126     if (con_info->answerstring)
    127       free (con_info->answerstring);
    128   }
    129   free (con_info);
    130   *req_cls = NULL;
    131 }
    132 
    133 
    134 static enum MHD_Result
    135 answer_to_connection (void *cls,
    136                       struct MHD_Connection *connection,
    137                       const char *url,
    138                       const char *method,
    139                       const char *version,
    140                       const char *upload_data,
    141                       size_t *upload_data_size,
    142                       void **req_cls)
    143 {
    144   struct connection_info_struct *con_info = *req_cls;
    145 
    146   (void) cls;               /* Unused. Silent compiler warning. */
    147   (void) url;               /* Unused. Silent compiler warning. */
    148   (void) version;           /* Unused. Silent compiler warning. */
    149   if (NULL == con_info)
    150   {
    151     con_info = malloc (sizeof (struct connection_info_struct));
    152     *req_cls = (void *) con_info;
    153     if (NULL == con_info)
    154       return MHD_NO;
    155     con_info->answerstring = NULL;
    156 
    157     if (0 == strcmp (method, "POST"))
    158     {
    159       con_info->postprocessor =
    160         MHD_create_post_processor (connection,
    161                                    POSTBUFFERSIZE,
    162                                    iterate_post,
    163                                    (void *) con_info);
    164       if (NULL == con_info->postprocessor)
    165       {
    166         free (con_info);
    167         return MHD_NO;
    168       }
    169       con_info->connectiontype = POST;
    170     }
    171     else
    172     {
    173       con_info->connectiontype = GET;
    174     }
    175     return MHD_YES;
    176   }
    177   if (GET == con_info->connectiontype)
    178   {
    179     return send_page (connection,
    180                       askpage);
    181   }
    182   if (POST == con_info->connectiontype)
    183   {
    184     if (0 != *upload_data_size)
    185     {
    186       if (MHD_YES !=
    187           MHD_post_process (con_info->postprocessor,
    188                             upload_data,
    189                             *upload_data_size))
    190         return MHD_NO;
    191       *upload_data_size = 0;
    192       return MHD_YES;
    193     }
    194     else if (NULL != con_info->answerstring)
    195       return send_page (connection,
    196                         con_info->answerstring);
    197   }
    198   return send_page (connection,
    199                     errorpage);
    200 }
    201 
    202 
    203 int
    204 main (void)
    205 {
    206   struct MHD_Daemon *daemon;
    207 
    208   daemon = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
    209                              PORT, NULL, NULL,
    210                              &answer_to_connection, NULL,
    211                              MHD_OPTION_NOTIFY_COMPLETED,
    212                              &request_completed, NULL,
    213                              MHD_OPTION_END);
    214   if (NULL == daemon)
    215     return 1;
    216   (void) getchar ();
    217   MHD_stop_daemon (daemon);
    218   return 0;
    219 }