rest.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * Copyright (c) 2018 the CivetWeb developers
  3. * MIT License
  4. */
  5. /* Simple demo of a REST callback. */
  6. #ifdef _WIN32
  7. #include <windows.h>
  8. #else
  9. #include <unistd.h>
  10. #endif
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <time.h>
  14. #include "civetweb.h"
  15. #include "cJSON.h"
  16. #ifdef NO_SSL
  17. #ifdef USE_IPV6
  18. #define PORT "[::]:8888,8884"
  19. #else
  20. #define PORT "8888,8884"
  21. #endif
  22. #else
  23. #ifdef USE_IPV6
  24. #define PORT "[::]:8888r,[::]:8843s,8884"
  25. #else
  26. #define PORT "8888r,8843s,8884"
  27. #endif
  28. #endif
  29. #define EXAMPLE_URI "/example"
  30. #define EXIT_URI "/exit"
  31. int exitNow = 0;
  32. static int
  33. SendJSON(struct mg_connection *conn, cJSON *json_obj)
  34. {
  35. char *json_str = cJSON_PrintUnformatted(json_obj);
  36. size_t json_str_len = strlen(json_str);
  37. /* Send HTTP message header */
  38. mg_send_http_ok(conn, "application/json; charset=utf-8", json_str_len);
  39. /* Send HTTP message content */
  40. mg_write(conn, json_str, json_str_len);
  41. /* Free string allocated by cJSON_Print* */
  42. cJSON_free(json_str);
  43. return (int)json_str_len;
  44. }
  45. int
  46. ExampleHandler(struct mg_connection *conn, void *cbdata)
  47. {
  48. static unsigned request = 0;
  49. const struct mg_request_info *ri = mg_get_request_info(conn);
  50. cJSON *obj;
  51. if (0 != strcmp(ri->request_method, "GET")) {
  52. /* this is not a GET request */
  53. mg_send_http_error(conn, 405, "Only GET method supported");
  54. return 405;
  55. }
  56. obj = cJSON_CreateObject();
  57. if (!obj) {
  58. /* insufficient memory? */
  59. mg_send_http_error(conn, 500, "Server error");
  60. return 500;
  61. }
  62. cJSON_AddStringToObject(obj, "version", CIVETWEB_VERSION);
  63. cJSON_AddNumberToObject(obj, "request", ++request);
  64. SendJSON(conn, obj);
  65. cJSON_Delete(obj);
  66. return 200;
  67. }
  68. int
  69. ExitHandler(struct mg_connection *conn, void *cbdata)
  70. {
  71. mg_printf(conn,
  72. "HTTP/1.1 200 OK\r\nContent-Type: "
  73. "text/plain\r\nConnection: close\r\n\r\n");
  74. mg_printf(conn, "Server will shut down.\n");
  75. mg_printf(conn, "Bye!\n");
  76. exitNow = 1;
  77. return 1;
  78. }
  79. int
  80. log_message(const struct mg_connection *conn, const char *message)
  81. {
  82. puts(message);
  83. return 1;
  84. }
  85. int
  86. main(int argc, char *argv[])
  87. {
  88. const char *options[] = {"listening_ports",
  89. PORT,
  90. "request_timeout_ms",
  91. "10000",
  92. "error_log_file",
  93. "error.log",
  94. #ifndef NO_SSL
  95. "ssl_certificate",
  96. "../../resources/cert/server.pem",
  97. "ssl_protocol_version",
  98. "3",
  99. "ssl_cipher_list",
  100. "DES-CBC3-SHA:AES128-SHA:AES128-GCM-SHA256",
  101. #endif
  102. "enable_auth_domain_check",
  103. "no",
  104. 0};
  105. struct mg_callbacks callbacks;
  106. struct mg_context *ctx;
  107. int err = 0;
  108. /* Check if libcivetweb has been built with all required features. */
  109. #ifndef NO_SSL
  110. if (!mg_check_feature(2)) {
  111. fprintf(stderr,
  112. "Error: Embedded example built with SSL support, "
  113. "but civetweb library build without.\n");
  114. err = 1;
  115. }
  116. mg_init_library(MG_FEATURES_SSL);
  117. #else
  118. mg_init_library(0);
  119. #endif
  120. if (err) {
  121. fprintf(stderr, "Cannot start CivetWeb - inconsistent build.\n");
  122. return EXIT_FAILURE;
  123. }
  124. /* Callback will print error messages to console */
  125. memset(&callbacks, 0, sizeof(callbacks));
  126. callbacks.log_message = log_message;
  127. /* Start CivetWeb web server */
  128. ctx = mg_start(&callbacks, 0, options);
  129. /* Check return value: */
  130. if (ctx == NULL) {
  131. fprintf(stderr, "Cannot start CivetWeb - mg_start failed.\n");
  132. return EXIT_FAILURE;
  133. }
  134. /* Add handler EXAMPLE_URI, to explain the example */
  135. mg_set_request_handler(ctx, EXAMPLE_URI, ExampleHandler, 0);
  136. mg_set_request_handler(ctx, EXIT_URI, ExitHandler, 0);
  137. /* Wait until the server should be closed */
  138. while (!exitNow) {
  139. #ifdef _WIN32
  140. Sleep(1000);
  141. #else
  142. sleep(1);
  143. #endif
  144. }
  145. /* Stop the server */
  146. mg_stop(ctx);
  147. printf("Server stopped.\n");
  148. printf("Bye!\n");
  149. return EXIT_SUCCESS;
  150. }