2
0

simplepost.c 5.8 KB

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