multiple-connection-handling (#3)
Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
@@ -28,11 +28,53 @@ constexpr uint8 kGZ_Extension_Length = sizeof(".gz") - 1;
|
||||
|
||||
#define FILE_PATH_MAX (ESP_VFS_PATH_MAX + 128)
|
||||
#define SCRATCH_BUFSIZE 4096
|
||||
#define MAX_SCRATCH_BUFFERS 10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char scratch[SCRATCH_BUFSIZE];
|
||||
} http_server_data_t;
|
||||
char *buffers[MAX_SCRATCH_BUFFERS];
|
||||
bool in_use[MAX_SCRATCH_BUFFERS];
|
||||
} scratch_pool_t;
|
||||
|
||||
static scratch_pool_t global_scratch_pool = {};
|
||||
|
||||
char *get_scratch_buffer()
|
||||
{
|
||||
for (int i = 0; i < MAX_SCRATCH_BUFFERS; i++)
|
||||
{
|
||||
if (!global_scratch_pool.in_use[i])
|
||||
{
|
||||
if (global_scratch_pool.buffers[i] == NULL)
|
||||
{
|
||||
global_scratch_pool.buffers[i] = (char *)malloc(SCRATCH_BUFSIZE);
|
||||
if (global_scratch_pool.buffers[i] == NULL)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to allocate scratch buffer from heap!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
global_scratch_pool.in_use[i] = true;
|
||||
return global_scratch_pool.buffers[i];
|
||||
}
|
||||
}
|
||||
ESP_LOGE(TAG, "All scratch buffers in use! Increase MAX_SCRATCH_BUFFERS");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_scratch_buffer(char *buffer)
|
||||
{
|
||||
if (buffer == NULL)
|
||||
return;
|
||||
for (int i = 0; i < MAX_SCRATCH_BUFFERS; i++)
|
||||
{
|
||||
if (global_scratch_pool.buffers[i] == buffer)
|
||||
{
|
||||
global_scratch_pool.in_use[i] = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ESP_LOGE(TAG, "Attempted to free unknown scratch buffer!");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CALENDINK_DEPLOY_WEB_PAGES
|
||||
// Set HTTP response content type according to file extension
|
||||
@@ -138,8 +180,14 @@ internal esp_err_t static_file_handler(httpd_req_t *req)
|
||||
|
||||
set_content_type_from_file(req, filepath);
|
||||
|
||||
http_server_data_t *rest_context = (http_server_data_t *)req->user_ctx;
|
||||
char *chunk = rest_context->scratch;
|
||||
char *chunk = get_scratch_buffer();
|
||||
if (chunk == NULL)
|
||||
{
|
||||
close(fd);
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Server busy");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ssize_t read_bytes;
|
||||
|
||||
do
|
||||
@@ -155,6 +203,7 @@ internal esp_err_t static_file_handler(httpd_req_t *req)
|
||||
{
|
||||
close(fd);
|
||||
ESP_LOGE(TAG, "File sending failed!");
|
||||
free_scratch_buffer(chunk);
|
||||
httpd_resp_sendstr_chunk(req, NULL); // Abort sending
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -162,6 +211,7 @@ internal esp_err_t static_file_handler(httpd_req_t *req)
|
||||
} while (read_bytes > 0);
|
||||
|
||||
close(fd);
|
||||
free_scratch_buffer(chunk);
|
||||
httpd_resp_send_chunk(req, NULL, 0); // End response
|
||||
|
||||
return ESP_OK;
|
||||
@@ -210,17 +260,12 @@ internal httpd_handle_t start_webserver(void)
|
||||
ESP_LOGI(TAG, "LittleFS mounted on /www");
|
||||
}
|
||||
#endif
|
||||
http_server_data_t *rest_context =
|
||||
(http_server_data_t *)calloc(1, sizeof(http_server_data_t));
|
||||
if (rest_context == NULL)
|
||||
{
|
||||
ESP_LOGE(TAG, "No memory for rest context");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
config.uri_match_fn = httpd_uri_match_wildcard;
|
||||
config.max_uri_handlers = 20;
|
||||
config.max_open_sockets = 24;
|
||||
config.lru_purge_enable = true;
|
||||
|
||||
httpd_handle_t server = NULL;
|
||||
ESP_LOGI(TAG, "Starting HTTP Server on port: '%d'", config.server_port);
|
||||
@@ -262,7 +307,7 @@ internal httpd_handle_t start_webserver(void)
|
||||
httpd_uri_t static_get_uri = {.uri = "/*",
|
||||
.method = HTTP_GET,
|
||||
.handler = static_file_handler,
|
||||
.user_ctx = rest_context};
|
||||
.user_ctx = NULL};
|
||||
httpd_register_uri_handler(server, &static_get_uri);
|
||||
#endif
|
||||
|
||||
@@ -270,7 +315,6 @@ internal httpd_handle_t start_webserver(void)
|
||||
}
|
||||
|
||||
ESP_LOGE(TAG, "Error starting server!");
|
||||
free(rest_context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user