fix(esp_http_server): Add support for custom HTTP status codes

Closes https://github.com/espressif/esp-idf/issues/12399
This commit is contained in:
Harshit Malpani 2023-11-27 14:29:37 +05:30
parent 3140fcadf2
commit ae71e1ddb9
No known key found for this signature in database
GPG Key ID: 441A8ACC7853D493
2 changed files with 63 additions and 0 deletions

View File

@ -1293,6 +1293,30 @@ esp_err_t httpd_resp_set_hdr(httpd_req_t *r, const char *field, const char *valu
*/
esp_err_t httpd_resp_send_err(httpd_req_t *req, httpd_err_code_t error, const char *msg);
/**
* @brief For sending out custom error code in response to HTTP request.
*
* @note
* - This API is supposed to be called only from the context of
* a URI handler where httpd_req_t* request pointer is valid.
* - Once this API is called, all request headers are purged, so
* request headers need be copied into separate buffers if
* they are required later.
* - If you wish to send additional data in the body of the
* response, please use the lower-level functions directly.
*
* @param[in] req Pointer to the HTTP request for which the response needs to be sent
* @param[in] status Error status to send
* @param[in] msg Error message string
*
* @return
* - ESP_OK : On successfully sending the response packet
* - ESP_ERR_INVALID_ARG : Null arguments
* - ESP_ERR_HTTPD_RESP_SEND : Error in raw send
* - ESP_ERR_HTTPD_INVALID_REQ : Invalid request pointer
*/
esp_err_t httpd_resp_send_custom_err(httpd_req_t *req, const char *status, const char *msg);
/**
* @brief Helper function for HTTP 404
*

View File

@ -483,6 +483,45 @@ esp_err_t httpd_resp_send_err(httpd_req_t *req, httpd_err_code_t error, const ch
return ret;
}
esp_err_t httpd_resp_send_custom_err(httpd_req_t *req, const char *status, const char *msg)
{
ESP_LOGW(TAG, LOG_FMT("%s - %s"), status, msg);
/* Set error code in HTTP response */
httpd_resp_set_status(req, status);
httpd_resp_set_type(req, HTTPD_TYPE_TEXT);
#ifdef CONFIG_HTTPD_ERR_RESP_NO_DELAY
/* Use TCP_NODELAY option to force socket to send data in buffer
* This ensures that the error message is sent before the socket
* is closed */
struct httpd_req_aux *ra = req->aux;
int nodelay = 1;
if (setsockopt(ra->sd->fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)) < 0) {
/* If failed to turn on TCP_NODELAY, throw warning and continue */
ESP_LOGW(TAG, LOG_FMT("error calling setsockopt : %d"), errno);
nodelay = 0;
}
#endif
/* Send HTTP error message */
esp_err_t ret = httpd_resp_send(req, msg, HTTPD_RESP_USE_STRLEN);
#ifdef CONFIG_HTTPD_ERR_RESP_NO_DELAY
/* If TCP_NODELAY was set successfully above, time to disable it */
if (nodelay == 1) {
nodelay = 0;
if (setsockopt(ra->sd->fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)) < 0) {
/* If failed to turn off TCP_NODELAY, throw error and
* return failure to signal for socket closure */
ESP_LOGE(TAG, LOG_FMT("error calling setsockopt : %d"), errno);
return ESP_ERR_INVALID_STATE;
}
}
#endif
return ret;
}
esp_err_t httpd_register_err_handler(httpd_handle_t handle,
httpd_err_code_t error,
httpd_err_handler_func_t err_handler_fn)