simplepost.c 5.4 KB

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