http_server : Added feature for invoking user configurable handlers during server errors

Added APIs :
  * httpd_resp_send_err()        : for sending HTTP error responses for error codes given by httpd_err_code_t. It uses TCP_NODELAY option to ensure that HTTP error responses reach the client before socket is closed.
  * httpd_register_err_handler() : for registering HTTP error handler functions of type httpd_err_handler_func_t.

The default behavior, on encountering errors during processing of HTTP requests, is now to send HTTP error response (if possible) and close the underlying socket. User configurable handlers can be used to override this behavior for each error individually (except for 500 Internal Server Error).

Also fixed some typos.

Closes https://github.com/espressif/esp-idf/issues/3005
This commit is contained in:
Anurag Kar
2019-02-01 17:47:41 +05:30
committed by bot
parent 5ec58c316d
commit 28412d8cb6
7 changed files with 407 additions and 194 deletions

View File

@@ -288,31 +288,43 @@ static struct httpd_data *httpd_create(const httpd_config_t *config)
{
/* Allocate memory for httpd instance data */
struct httpd_data *hd = calloc(1, sizeof(struct httpd_data));
if (hd != NULL) {
hd->hd_calls = calloc(config->max_uri_handlers, sizeof(httpd_uri_t *));
if (hd->hd_calls == NULL) {
free(hd);
return NULL;
}
hd->hd_sd = calloc(config->max_open_sockets, sizeof(struct sock_db));
if (hd->hd_sd == NULL) {
free(hd->hd_calls);
free(hd);
return NULL;
}
struct httpd_req_aux *ra = &hd->hd_req_aux;
ra->resp_hdrs = calloc(config->max_resp_headers, sizeof(struct resp_hdr));
if (ra->resp_hdrs == NULL) {
free(hd->hd_sd);
free(hd->hd_calls);
free(hd);
return NULL;
}
/* Save the configuration for this instance */
hd->config = *config;
} else {
ESP_LOGE(TAG, "mem alloc failed");
if (!hd) {
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP server instance"));
return NULL;
}
hd->hd_calls = calloc(config->max_uri_handlers, sizeof(httpd_uri_t *));
if (!hd->hd_calls) {
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP URI handlers"));
free(hd);
return NULL;
}
hd->hd_sd = calloc(config->max_open_sockets, sizeof(struct sock_db));
if (!hd->hd_sd) {
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP session data"));
free(hd->hd_calls);
free(hd);
return NULL;
}
struct httpd_req_aux *ra = &hd->hd_req_aux;
ra->resp_hdrs = calloc(config->max_resp_headers, sizeof(struct resp_hdr));
if (!ra->resp_hdrs) {
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP response headers"));
free(hd->hd_sd);
free(hd->hd_calls);
free(hd);
return NULL;
}
hd->err_handler_fns = calloc(HTTPD_ERR_CODE_MAX, sizeof(httpd_err_handler_func_t));
if (!hd->err_handler_fns) {
ESP_LOGE(TAG, LOG_FMT("Failed to allocate memory for HTTP error handlers"));
free(ra->resp_hdrs);
free(hd->hd_sd);
free(hd->hd_calls);
free(hd);
return NULL;
}
/* Save the configuration for this instance */
hd->config = *config;
return hd;
}
@@ -320,6 +332,7 @@ static void httpd_delete(struct httpd_data *hd)
{
struct httpd_req_aux *ra = &hd->hd_req_aux;
/* Free memory of httpd instance data */
free(hd->err_handler_fns);
free(ra->resp_hdrs);
free(hd->hd_sd);