33static const char * TAG = "HTTP_SERVER" ;
44extern const char * SPIFFS_MOUNTPOINT ;
55static char CSS_PATH [128 ];
6+ static char JS_PATH [128 ];
67
8+ /// @brief Serve a file from the SPIFFS filesystem
9+ /// @param req httpd_req_t
10+ /// @param file_path const char*
11+ /// @param content_type const char*
12+ /// @return esp_err_t
13+ static esp_err_t serve_file (httpd_req_t * req , const char * file_path , const char * content_type ) {
14+ FILE * file = fopen (file_path , "r" );
15+ if (file == NULL ) {
16+ ESP_LOGE (TAG , "Failed to open file: %s" , file_path );
17+ return httpd_resp_send_err (req , HTTPD_500_INTERNAL_SERVER_ERROR , "Failed to open file" );
18+ }
19+
20+ httpd_resp_set_type (req , content_type );
21+ char buffer [1024 ];
22+ size_t bytes_read ;
23+ while ((bytes_read = fread (buffer , 1 , sizeof (buffer ), file )) > 0 ) {
24+ esp_err_t send_status = httpd_resp_send_chunk (req , buffer , bytes_read );
25+ if (send_status != ESP_OK ) {
26+ fclose (file );
27+ ESP_LOGE (TAG , "Error sending chunk from file: %s" , file_path );
28+ return send_status ;
29+ }
30+ }
31+ fclose (file );
32+ return httpd_resp_send_chunk (req , NULL , 0 );
33+ }
34+
35+ /// @brief Log the request URI and status
36+ /// @param req httpd_req_t
37+ /// @param status esp_err_t
38+ /// @return esp_err_t
739static esp_err_t log_request (httpd_req_t * req , esp_err_t status ) {
840 ESP_LOGI (TAG , "Request URI : %s | Status : %d" , req -> uri , status );
941 return status ;
1042}
1143
44+ /// @brief setup page handler
45+ /// @param req httpd_req_t
46+ /// @return esp_err_t
47+ static esp_err_t setup_handler (httpd_req_t * req ) {
48+ esp_err_t status = serve_file (req , "/spiffs/index.html" , "text/html" );
49+ return log_request (req , status );
50+ }
51+
52+ /// @brief Handler for milligram CSS
53+ /// @param req httpd_req_t
54+ /// @return esp_err_t
1255static esp_err_t milligram_handler (httpd_req_t * req ) {
13- char resp [1024 ];
14- FILE * file = fopen (CSS_PATH , "r" );
15- if (file == NULL ) {
16- ESP_LOGE (TAG , "Failed to open %s" , CSS_PATH );
17- return log_request (req , ESP_FAIL );
18- }
19- size_t read_bytes = fread (resp , 1 , sizeof (resp ) - 1 , file );
20- fclose (file );
21- if (read_bytes == 0 ) {
22- ESP_LOGE (TAG , "Failed to read %s" , CSS_PATH );
23- return log_request (req , ESP_FAIL );
24- }
25- resp [read_bytes ] = '\0' ;
26- httpd_resp_set_type (req , "text/css" );
27- esp_err_t status = httpd_resp_send (req , resp , HTTPD_RESP_USE_STRLEN );
56+ esp_err_t status = serve_file (req , CSS_PATH , "text/css" );
2857 return log_request (req , status );
2958}
3059
31- static esp_err_t setup (httpd_req_t * req ) {
32- char resp [1024 ];
33- FILE * file = fopen ("/spiffs/index.html" , "r" );
34- if (file == NULL ) {
35- ESP_LOGE (TAG , "Failed to open /spiffs/index.html" );
36- return log_request (req , ESP_FAIL );
37- }
38- size_t read_bytes = fread (resp , 1 , sizeof (resp ) - 1 , file );
39- fclose (file );
40- if (read_bytes == 0 ) {
41- ESP_LOGE (TAG , "Failed to read /spiffs/index.html" );
42- return log_request (req , ESP_FAIL );
43- }
44- resp [read_bytes ] = '\0' ;
45- esp_err_t status = httpd_resp_send (req , resp , HTTPD_RESP_USE_STRLEN );
60+ /// @brief Handler for milligram CSS
61+ /// @param req httpd_req_t
62+ /// @return esp_err_t
63+ static esp_err_t umbrella_handler (httpd_req_t * req ) {
64+ esp_err_t status = serve_file (req , JS_PATH , "text/javascript" );
4665 return log_request (req , status );
4766}
4867
68+ /// @brief Connectivity check handler (captive portal)
69+ /// @param req httpd_req_t
70+ /// @return esp_err_t
4971static esp_err_t connectivity_check (httpd_req_t * req ) {
50- httpd_resp_set_hdr (req , "Location" , "http://smartclimate.local /setup" );
72+ httpd_resp_set_hdr (req , "Location" , "http://smartclimate/setup" );
5173 httpd_resp_set_status (req , "301 Moved Permanently" );
52- return log_request (req , httpd_resp_send (req , "" , HTTPD_RESP_USE_STRLEN ));
74+ esp_err_t status = httpd_resp_send (req , "" , HTTPD_RESP_USE_STRLEN );
75+ return log_request (req , status );
5376}
5477
78+ /// @brief Default request handler for undefined URIs
79+ /// @param req httpd_req_t
80+ /// @param err httpd_err_code_t
81+ /// @return esp_err_t
5582static esp_err_t default_handler (httpd_req_t * req , httpd_err_code_t err ) {
56- ESP_LOGW (TAG , "Undefined URI requested : %s | Error code : %d" , req -> uri , err );
83+ ESP_LOGW (TAG , "Undefined URI requested: %s | Error code: %d" , req -> uri , err );
5784 const char resp [] = "404 Not Found" ;
5885 esp_err_t status = httpd_resp_set_status (req , "404 Not Found" );
5986 if (status == ESP_OK ) {
@@ -62,39 +89,41 @@ static esp_err_t default_handler(httpd_req_t *req, httpd_err_code_t err) {
6289 return log_request (req , status );
6390}
6491
65- httpd_uri_t setup_uri = {.uri = "/setup" , .method = HTTP_GET , .handler = setup , .user_ctx = NULL };
66- static httpd_uri_t connectivity_uris [] = {
67- {.uri = "/generate_204" , .method = HTTP_GET , .handler = connectivity_check , .user_ctx = NULL },
68- {.uri = "/library/test/success.html" , .method = HTTP_GET , .handler = connectivity_check , .user_ctx = NULL },
69- {.uri = "/hotspot-detect.html" , .method = HTTP_GET , .handler = connectivity_check , .user_ctx = NULL },
70- {.uri = "/" , .method = HTTP_GET , .handler = connectivity_check , .user_ctx = NULL },
71- };
72- httpd_uri_t css_uri = {
73- .uri = "/css/milligram.min.css" , .method = HTTP_GET , .handler = milligram_handler , .user_ctx = NULL };
74-
92+ /// @brief Start the webserver
93+ /// @param void
94+ /// @return httpd_handle_t
7595httpd_handle_t webserver_start (void ) {
7696 snprintf (CSS_PATH , sizeof (CSS_PATH ), "%s/css/milligram.min.css" , SPIFFS_MOUNTPOINT );
97+ snprintf (JS_PATH , sizeof (JS_PATH ), "%s/js/umbrella.min.js" , SPIFFS_MOUNTPOINT );
98+
7799 httpd_handle_t server = NULL ;
78100 httpd_config_t config = HTTPD_DEFAULT_CONFIG ();
79101
80- ESP_ERROR_CHECK ( mdns_init ()) ;
102+ httpd_uri_t setup_uri = {. uri = "/setup" , . method = HTTP_GET , . handler = setup_handler , . user_ctx = NULL } ;
81103
82- mdns_hostname_set (APP_NAME );
83- mdns_instance_name_set ("esp device" );
104+ static httpd_uri_t connectivity_uris [] = {
105+ {.uri = "/generate_204" , .method = HTTP_GET , .handler = connectivity_check , .user_ctx = NULL },
106+ {.uri = "/library/test/success.html" , .method = HTTP_GET , .handler = connectivity_check , .user_ctx = NULL },
107+ {.uri = "/hotspot-detect.html" , .method = HTTP_GET , .handler = connectivity_check , .user_ctx = NULL },
108+ {.uri = "/" , .method = HTTP_GET , .handler = connectivity_check , .user_ctx = NULL },
109+ };
84110
85- ESP_LOGI (TAG , "Webserver started on port : %d" , config .server_port );
111+ httpd_uri_t css_uri = {
112+ .uri = "/css/milligram.min.css" , .method = HTTP_GET , .handler = milligram_handler , .user_ctx = NULL };
113+ httpd_uri_t js_uri = {
114+ .uri = "/js/umbrella.min.js" , .method = HTTP_GET , .handler = umbrella_handler , .user_ctx = NULL };
115+
116+ ESP_LOGI (TAG , "Webserver starting on port: %d" , config .server_port );
86117 if (httpd_start (& server , & config ) == ESP_OK ) {
87118 httpd_register_uri_handler (server , & setup_uri );
88119 httpd_register_uri_handler (server , & css_uri );
120+ httpd_register_uri_handler (server , & js_uri );
89121
90122 for (size_t i = 0 ; i < sizeof (connectivity_uris ) / sizeof (connectivity_uris [0 ]); i ++ ) {
91123 httpd_register_uri_handler (server , & connectivity_uris [i ]);
92124 }
93125
94126 httpd_register_err_handler (server , HTTPD_404_NOT_FOUND , default_handler );
95-
96- mdns_service_add ("HTTP webserver" , "_http" , "_tcp" , 80 , NULL , 0 );
97-
98127 return server ;
99128 }
100129 ESP_LOGE (TAG , "Error on webserver boot" );
0 commit comments