From d3de814d75dbe7f457eff1e9e8002913058797c3 Mon Sep 17 00:00:00 2001 From: arne Date: Mon, 6 Oct 2025 21:36:03 +0200 Subject: [PATCH] Send `index.html` to browser when visiting `/` --- main/inkpot.c | 71 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/main/inkpot.c b/main/inkpot.c index b149c6f..3c70111 100644 --- a/main/inkpot.c +++ b/main/inkpot.c @@ -24,6 +24,14 @@ #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif +/* Scratch buffer size for sending files to HTTP clients */ +#define SCRATCH_BUFSIZE 8192 + +struct file_server_data { + /* Scratch buffer for temporary storage during file transfer */ + char scratch[SCRATCH_BUFSIZE]; +}; + static const char *TAG = "inkpot"; // Function to log memory usage with the message at the end @@ -184,16 +192,37 @@ void scan_wifi_networks(void) { // HTTP Server -#define WRITE_HEADER(req, buffer, name, format, src) \ - sprintf(buffer, format, src); \ - ESP_ERROR_CHECK(httpd_resp_set_hdr(req, name, buffer)); - static esp_err_t http_index(httpd_req_t* req) { - // TODO: Serve HTML file with form POSTing to `/draw` - const char* response = "Hello world!\n"; - httpd_resp_set_type(req, "text/plain"); - httpd_resp_set_status(req, "200"); - httpd_resp_send(req, response, HTTPD_RESP_USE_STRLEN); + char index_path[128]; + strcpy(index_path, LFS_PATH); + strcat(index_path, "/http/index.html"); + + FILE *fd = fopen(index_path, "r"); + char *chunk = ((struct file_server_data *)req->user_ctx)->scratch; + size_t chunksize; + do { + /* Read file in chunks into the scratch buffer */ + chunksize = fread(chunk, 1, SCRATCH_BUFSIZE, fd); + + if (chunksize > 0) { + /* Send the buffer contents as HTTP response chunk */ + if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) { + fclose(fd); + ESP_LOGE(TAG, "File sending failed!"); + /* Abort sending file */ + httpd_resp_sendstr_chunk(req, NULL); + /* Respond with 500 Internal Server Error */ + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to send file"); + return ESP_FAIL; + } + } + + /* Keep looping till the whole file is sent */ + } while (chunksize != 0); + fclose(fd); + httpd_resp_set_hdr(req, "Connection", "close"); + httpd_resp_send_chunk(req, NULL, 0); + ESP_LOGI(TAG, "Sent index.html"); return ESP_OK; } @@ -252,17 +281,33 @@ esp_err_t http_draw(httpd_req_t* req) { return ESP_OK; } -void register_http_routes(httpd_handle_t server) { +esp_err_t register_http_routes(httpd_handle_t server) { + static struct file_server_data *server_data = NULL; + + if (server_data) { + ESP_LOGE(TAG, "File server already started"); + return ESP_ERR_INVALID_STATE; + } + + // Allocate memory for server data + server_data = calloc(1, sizeof(struct file_server_data)); + if (!server_data) { + ESP_LOGE(TAG, "Failed to allocate memory for server data"); + return ESP_ERR_NO_MEM; + } + { httpd_uri_t uri - = { .uri = "/", .method = HTTP_GET, .handler = http_index, .user_ctx = NULL }; + = { .uri = "/", .method = HTTP_GET, .handler = http_index, .user_ctx = server_data }; httpd_register_uri_handler(server, &uri); } { httpd_uri_t uri - = { .uri = "/draw", .method = HTTP_POST, .handler = http_draw, .user_ctx = NULL }; + = { .uri = "/draw", .method = HTTP_POST, .handler = http_draw, .user_ctx = server_data }; httpd_register_uri_handler(server, &uri); } + + return ESP_OK; } // init @@ -279,8 +324,6 @@ void app_main(void) { } ESP_ERROR_CHECK(ret); - // FIXME: Wifi server causes some crash, failing to yield to watchdog in time - // Set up HTTP server httpd_handle_t server = get_server(); if (server != NULL) { register_http_routes(server);