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 }