simplepost.c 5.4 KB

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