server_main.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include "server_main.h"
  2. #include <string>
  3. #include "server_help.h"
  4. #include "time_sntp.h"
  5. httpd_handle_t server = NULL;
  6. std::string starttime = "";
  7. /* An HTTP GET handler */
  8. esp_err_t hello_get_handler(httpd_req_t *req)
  9. {
  10. char* buf;
  11. size_t buf_len;
  12. printf("req uri:\n");
  13. printf(req->uri);
  14. printf("\n");
  15. /* Get header value string length and allocate memory for length + 1,
  16. * extra byte for null termination */
  17. buf_len = httpd_req_get_hdr_value_len(req, "Host") + 1;
  18. if (buf_len > 1) {
  19. buf = (char*) malloc(buf_len);
  20. /* Copy null terminated value string into buffer */
  21. if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) {
  22. ESP_LOGI(TAG, "Found header => Host: %s", buf);
  23. }
  24. free(buf);
  25. }
  26. buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-2") + 1;
  27. if (buf_len > 1) {
  28. buf = (char*) malloc(buf_len);
  29. if (httpd_req_get_hdr_value_str(req, "Test-Header-2", buf, buf_len) == ESP_OK) {
  30. ESP_LOGI(TAG, "Found header => Test-Header-2: %s", buf);
  31. }
  32. free(buf);
  33. }
  34. buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-1") + 1;
  35. if (buf_len > 1) {
  36. buf = (char*) malloc(buf_len);
  37. if (httpd_req_get_hdr_value_str(req, "Test-Header-1", buf, buf_len) == ESP_OK) {
  38. ESP_LOGI(TAG, "Found header => Test-Header-1: %s", buf);
  39. }
  40. free(buf);
  41. }
  42. /* Read URL query string length and allocate memory for length + 1,
  43. * extra byte for null termination */
  44. buf_len = httpd_req_get_url_query_len(req) + 1;
  45. if (buf_len > 1) {
  46. buf = (char*) malloc(buf_len);
  47. if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
  48. ESP_LOGI(TAG, "Found URL query => %s", buf);
  49. char param[32];
  50. /* Get value of expected key from query string */
  51. if (httpd_query_key_value(buf, "query1", param, sizeof(param)) == ESP_OK) {
  52. ESP_LOGI(TAG, "Found URL query parameter => query1=%s", param);
  53. }
  54. if (httpd_query_key_value(buf, "query3", param, sizeof(param)) == ESP_OK) {
  55. ESP_LOGI(TAG, "Found URL query parameter => query3=%s", param);
  56. }
  57. if (httpd_query_key_value(buf, "query2", param, sizeof(param)) == ESP_OK) {
  58. ESP_LOGI(TAG, "Found URL query parameter => query2=%s", param);
  59. }
  60. }
  61. free(buf);
  62. }
  63. /* Set some custom headers */
  64. httpd_resp_set_hdr(req, "Custom-Header-1", "Custom-Value-1");
  65. httpd_resp_set_hdr(req, "Custom-Header-2", "Custom-Value-2");
  66. /* Send response with custom headers and body set as the
  67. * string passed in user context*/
  68. const char* resp_str = (const char*) req->user_ctx;
  69. httpd_resp_send(req, resp_str, strlen(resp_str));
  70. /* After sending the HTTP response the old HTTP request
  71. * headers are lost. Check if HTTP request headers can be read now. */
  72. if (httpd_req_get_hdr_value_len(req, "Host") == 0) {
  73. ESP_LOGI(TAG, "Request headers lost");
  74. }
  75. return ESP_OK;
  76. }
  77. esp_err_t starttime_get_handler(httpd_req_t *req)
  78. {
  79. httpd_resp_send(req, starttime.c_str(), strlen(starttime.c_str()));
  80. /* Respond with an empty chunk to signal HTTP response completion */
  81. httpd_resp_send_chunk(req, NULL, 0);
  82. return ESP_OK;
  83. }
  84. esp_err_t hello_main_handler(httpd_req_t *req)
  85. {
  86. char filepath[50];
  87. struct stat file_stat;
  88. printf("uri: %s\n", req->uri);
  89. char *base_path = (char*) req->user_ctx;
  90. std::string filetosend(base_path);
  91. const char *filename = get_path_from_uri(filepath, base_path,
  92. req->uri - 1, sizeof(filepath));
  93. printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
  94. if ((strcmp(req->uri, "/") == 0))
  95. {
  96. filetosend = filetosend + "/html/index.html";
  97. }
  98. else
  99. {
  100. filetosend = filetosend + "/html" + std::string(req->uri);
  101. }
  102. printf("File to upload: %s\n", filetosend.c_str());
  103. if (!filename) {
  104. ESP_LOGE(TAG, "Filename is too long");
  105. /* Respond with 500 Internal Server Error */
  106. httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
  107. return ESP_FAIL;
  108. }
  109. if (stat(filetosend.c_str(), &file_stat) == -1) {
  110. /* If file not present on SPIFFS check if URI
  111. * corresponds to one of the hardcoded paths */
  112. ESP_LOGE(TAG, "Failed to stat file : %s", filetosend.c_str());
  113. /* Respond with 404 Not Found */
  114. httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
  115. return ESP_FAIL;
  116. }
  117. esp_err_t res;
  118. res = httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
  119. if (res != ESP_OK)
  120. return res;
  121. res = send_file(req, filetosend, &file_stat);
  122. if (res != ESP_OK)
  123. return res;
  124. /* Respond with an empty chunk to signal HTTP response completion */
  125. httpd_resp_send_chunk(req, NULL, 0);
  126. return ESP_OK;
  127. }
  128. esp_err_t img_tmp_handler(httpd_req_t *req)
  129. {
  130. char filepath[50];
  131. struct stat file_stat;
  132. printf("uri: %s\n", req->uri);
  133. char *base_path = (char*) req->user_ctx;
  134. std::string filetosend(base_path);
  135. const char *filename = get_path_from_uri(filepath, base_path,
  136. req->uri + sizeof("/img_tmp") - 1, sizeof(filepath));
  137. printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
  138. filetosend = filetosend + "/img_tmp/" + std::string(filename);
  139. printf("File to upload: %s\n", filetosend.c_str());
  140. if (!filename) {
  141. ESP_LOGE(TAG, "Filename is too long");
  142. /* Respond with 500 Internal Server Error */
  143. httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
  144. return ESP_FAIL;
  145. }
  146. if (stat(filetosend.c_str(), &file_stat) == -1) {
  147. /* If file not present on SPIFFS check if URI
  148. * corresponds to one of the hardcoded paths */
  149. ESP_LOGE(TAG, "Failed to stat file : %s", filetosend.c_str());
  150. /* Respond with 404 Not Found */
  151. httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
  152. return ESP_FAIL;
  153. }
  154. esp_err_t res = send_file(req, filetosend, &file_stat);
  155. if (res != ESP_OK)
  156. return res;
  157. /* Respond with an empty chunk to signal HTTP response completion */
  158. httpd_resp_send_chunk(req, NULL, 0);
  159. return ESP_OK;
  160. }
  161. void register_server_main_uri(httpd_handle_t server, const char *base_path)
  162. {
  163. httpd_uri_t starttime_tmp_handle = {
  164. .uri = "/starttime", // Match all URIs of type /path/to/file
  165. .method = HTTP_GET,
  166. .handler = starttime_get_handler,
  167. .user_ctx = NULL // Pass server data as context
  168. };
  169. httpd_register_uri_handler(server, &starttime_tmp_handle);
  170. httpd_uri_t img_tmp_handle = {
  171. .uri = "/img_tmp/*", // Match all URIs of type /path/to/file
  172. .method = HTTP_GET,
  173. .handler = img_tmp_handler,
  174. .user_ctx = (void*) base_path // Pass server data as context
  175. };
  176. httpd_register_uri_handler(server, &img_tmp_handle);
  177. httpd_uri_t main_rest_handle = {
  178. .uri = "/*", // Match all URIs of type /path/to/file
  179. .method = HTTP_GET,
  180. .handler = hello_main_handler,
  181. .user_ctx = (void*) base_path // Pass server data as context
  182. };
  183. httpd_register_uri_handler(server, &main_rest_handle);
  184. }
  185. httpd_handle_t start_webserver(void)
  186. {
  187. httpd_handle_t server = NULL;
  188. httpd_config_t config = { };
  189. config.task_priority = tskIDLE_PRIORITY+5;
  190. config.stack_size = 16384; // bei 32k stürzt das Programm beim Bilderaufnehmen ab
  191. config.core_id = tskNO_AFFINITY;
  192. config.server_port = 80;
  193. config.ctrl_port = 32768;
  194. config.max_open_sockets = 7;
  195. config.max_uri_handlers = 24;
  196. config.max_resp_headers = 8;
  197. config.backlog_conn = 5;
  198. config.lru_purge_enable = false;
  199. config.recv_wait_timeout = 30; // default: 5
  200. config.send_wait_timeout = 30; // default: 5
  201. config.global_user_ctx = NULL;
  202. config.global_user_ctx_free_fn = NULL;
  203. config.global_transport_ctx = NULL;
  204. config.global_transport_ctx_free_fn = NULL;
  205. config.open_fn = NULL;
  206. config.close_fn = NULL;
  207. // config.uri_match_fn = NULL;
  208. config.uri_match_fn = httpd_uri_match_wildcard;
  209. httpd_uri_t hll = {};
  210. hll.uri = "/hello";
  211. hll.method = HTTP_GET;
  212. hll.handler = hello_get_handler;
  213. hll.user_ctx = (void*) "Hello World!";
  214. starttime = gettimestring("%Y%m%d-%H%M%S");
  215. // Start the httpd server
  216. ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
  217. if (httpd_start(&server, &config) == ESP_OK) {
  218. // Set URI handlers
  219. ESP_LOGI(TAG, "Registering URI handlers");
  220. httpd_register_uri_handler(server, &hll);
  221. return server;
  222. }
  223. ESP_LOGI(TAG, "Error starting server!");
  224. return NULL;
  225. }
  226. void stop_webserver(httpd_handle_t server)
  227. {
  228. httpd_stop(server);
  229. }
  230. void disconnect_handler(void* arg, esp_event_base_t event_base,
  231. int32_t event_id, void* event_data)
  232. {
  233. httpd_handle_t* server = (httpd_handle_t*) arg;
  234. if (*server) {
  235. ESP_LOGI(TAG, "Stopping webserver");
  236. stop_webserver(*server);
  237. *server = NULL;
  238. }
  239. }
  240. void connect_handler(void* arg, esp_event_base_t event_base,
  241. int32_t event_id, void* event_data)
  242. {
  243. httpd_handle_t* server = (httpd_handle_t*) arg;
  244. if (*server == NULL) {
  245. ESP_LOGI(TAG, "Starting webserver");
  246. *server = start_webserver();
  247. }
  248. }