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