ESP32 only sends the first chunk
Posted: Mon Oct 23, 2023 8:19 am
I'm using esp-idf 4.4 and olimex ESP32-EVB-EA-IND. When sending a document, the controller says that everything has been sent, but the client correctly receives only the first chunk. If you set the chunk size to be larger than the file being sent, then the sending occurs successfully.
when I receive the ip the following code is executed:
when I receive the ip the following code is executed:
- #include "web_controller.h"
- #include "def_page.h"
- #include "esp_spiffs.h"
- static const char *TAG = "web_controller";
- #define WEB_MAX_HTTP_CHUNK (128)
- #define MAIN_CONTENT_RAM_SIZE (1024 * 52)
- static int main_content_length;
- uint32_t *main_content_ram_clone;
- esp_vfs_spiffs_conf_t config = {
- .base_path = "/spiffs",
- .partition_label = NULL,
- .max_files = 3,
- .format_if_mount_failed = true,
- };
- /**
- * @brief Set HTTP response content
- */
- static esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filepath)
- {
- const char *type = "text/plain";
- if (CHECK_FILE_EXTENSION(filepath, ".html"))
- {
- type = "text/html";
- }
- else if (CHECK_FILE_EXTENSION(filepath, ".js"))
- {
- type = "application/javascript";
- }
- else if (CHECK_FILE_EXTENSION(filepath, ".css"))
- {
- type = "text/css";
- }
- else if (CHECK_FILE_EXTENSION(filepath, ".png"))
- {
- type = "image/png";
- }
- else if (CHECK_FILE_EXTENSION(filepath, ".ico"))
- {
- type = "image/x-icon";
- }
- else if (CHECK_FILE_EXTENSION(filepath, ".svg"))
- {
- type = "text/xml";
- }
- else if (CHECK_FILE_EXTENSION(filepath, ".irz"))
- {
- type = "application/octet-stream";
- }
- return httpd_resp_set_type(req, type);
- }
- void start_web_controller(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
- {
- httpd_handle_t server = NULL;
- httpd_config_t config = HTTPD_DEFAULT_CONFIG();
- config.lru_purge_enable = true;
- config.uri_match_fn = httpd_uri_match_wildcard;
- config.stack_size = 1024 * 22;
- config.max_uri_handlers = 14;
- config.max_open_sockets = 10;
- config.backlog_conn = 0;
- ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
- if (httpd_start(&server, &config) == ESP_OK)
- {
- ESP_LOGI(TAG, "Registering URI handlers");
- httpd_register_uri_handler(server, &main_uri);
- httpd_register_uri_handler(server, &get_uri);
- }
- else
- {
- ESP_LOGE(TAG, "Error starting server!");
- }
- }
- esp_err_t http_404_error_handler(httpd_req_t *req, httpd_err_code_t err)
- {
- /* For any other URI send 404 and close socket */
- httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Some 404 error message");
- return ESP_FAIL;
- }
- /**
- * @brief обработчики запросов от клиента
- *
- * @param[in] filepath путь до файла
- * @param[in] content_clone указатель на начало файла
- * @param[in] content_length размерность файла
- * @param[out] status вернем 1, если смогли выделить память и считать файл
- */
- bool read_file(const char *filepath, uint32_t *content_clone, int *content_length, const esp_vfs_spiffs_conf_t *conf, uint32_t ram_content_size)
- {
- esp_vfs_spiffs_register(conf);
- *content_clone = calloc(ram_content_size, 1);
- int spiffs_file = open(filepath, O_RDONLY, 0);
- if (*content_clone == NULL)
- {
- ESP_LOGE(TAG, "Allocation failure!");
- }
- if (spiffs_file == -1)
- {
- ESP_LOGE(TAG, "File does not exist!");
- }
- if (*content_clone != NULL && spiffs_file)
- {
- *content_length = read(spiffs_file, *content_clone, ram_content_size);
- if (*content_length < ram_content_size)
- {
- ESP_LOGI(TAG, "File reading ok (%d bytes)", *content_length);
- esp_vfs_spiffs_unregister(NULL);
- close(spiffs_file);
- return true;
- }
- else
- {
- ESP_LOGE(TAG, "Allocation failure! (content_length < ram_content_size)");
- }
- }
- free(*content_clone);
- close(spiffs_file);
- esp_vfs_spiffs_unregister(NULL);
- return false;
- }
- bool send_file(httpd_req_t *req, uint32_t chunk_size, int content_length, uint32_t *content_clone)
- {
- httpd_resp_set_type(req, "text/html");
- httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
- uint32_t cur_pos = 0;
- uint32_t err_cnt = 0;
- while (1)
- {
- if (chunk_size > content_length - cur_pos)
- {
- ESP_LOGW(TAG, "Last package (%d bytes)", (content_length - cur_pos));
- httpd_resp_send_chunk(req, (const char *)(content_clone + cur_pos), content_length - cur_pos);
- ESP_LOGI(TAG, "File sent");
- httpd_resp_send_chunk(req, NULL, 0);
- return true;
- }
- else
- {
- if (httpd_resp_send_chunk(req, (const char *)(content_clone + cur_pos), chunk_size) != ESP_OK)
- {
- ESP_LOGE(TAG, "Chunk not sent");
- if (err_cnt++ >= 100)
- {
- free(content_clone);
- return false;
- }
- }
- else
- {
- cur_pos += chunk_size;
- }
- }
- }
- }
- static esp_err_t main_handler(httpd_req_t *req)
- {
- // if (read_file("/spiffs/img.png", &main_content_ram_clone, &main_content_length, &config, MAIN_CONTENT_RAM_SIZE))
- if (read_file("/spiffs/index.html.gz", &main_content_ram_clone, &main_content_length, &config, MAIN_CONTENT_RAM_SIZE))
- {
- if (send_file(req, WEB_MAX_HTTP_CHUNK, main_content_length, main_content_ram_clone))
- {
- free(main_content_ram_clone);
- return ESP_OK;
- }
- }
- httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, error_page_404);
- return ESP_FAIL;
- }
- static esp_err_t common_get_uri(httpd_req_t *req)
- {
- ESP_LOGW(TAG, "Request to receive: %s", req->uri);
- httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, error_page_404);
- return ESP_FAIL;
- }