mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-19 07:55:54 +00:00
esp_http_server improvements to allow adding transport layer encryption
Changes: - renamed `httpd_free_sess_ctx_fn_t` to `httpd_free_ctx_fn_t` - added a `httpd_handle_t` argument to `httpd_send_func_t` and `httpd_recv_func_t` - internal function `httpd_sess_get()` is no longer static, as it's used in other files besides httpd_sess.c Bug fixes: - removed a trailing semicolon from `HTTPD_DEFAULT_CONFIG()` - fixed issue with failed `select()`, now it automatically closes invalid sockets instead of shutting down the entire server New features: - `httpd_resp_send()` and `httpd_resp_send_chunk()` now accept -1 as length to use `strlen()` internally - added `httpd_sess_set_ctx()` to accompany `httpd_sess_get_ctx()` - added a "transport context" to the session structure (next to user context) - added `httpd_sess_{get,set}_transport_ctx()` to work with this transport context - added "global user context" and "global transport context" stored in the server config (and then the handle); supports a user-provided free_fn - added a "pending func" to e.g. check for data in the transport layer receive buffer - added functions `httpd_set_sess_{send,recv,pending}_override()` that target a session by ID (i.e. not using a request object) - added `httpd_set_pending_override()` - added a "open_fn" and "close_fn" - functions called when creating and closing a session. These may be used to set up transport layer encryption or some other session-wide feature
This commit is contained in:
@@ -22,6 +22,30 @@
|
||||
|
||||
static const char *TAG = "httpd_txrx";
|
||||
|
||||
esp_err_t httpd_set_sess_send_override(httpd_handle_t hd, int sockfd, httpd_send_func_t send_func)
|
||||
{
|
||||
struct sock_db *sess = httpd_sess_get(hd, sockfd);
|
||||
if (!sess) return ESP_ERR_INVALID_ARG;
|
||||
sess->send_fn = send_func;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t httpd_set_sess_recv_override(httpd_handle_t hd, int sockfd, httpd_recv_func_t recv_func)
|
||||
{
|
||||
struct sock_db *sess = httpd_sess_get(hd, sockfd);
|
||||
if (!sess) return ESP_ERR_INVALID_ARG;
|
||||
sess->recv_fn = recv_func;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t httpd_set_sess_pending_override(httpd_handle_t hd, int sockfd, httpd_pending_func_t pending_func)
|
||||
{
|
||||
struct sock_db *sess = httpd_sess_get(hd, sockfd);
|
||||
if (!sess) return ESP_ERR_INVALID_ARG;
|
||||
sess->pending_fn = pending_func;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t httpd_set_send_override(httpd_req_t *r, httpd_send_func_t send_func)
|
||||
{
|
||||
if (r == NULL || send_func == NULL) {
|
||||
@@ -52,6 +76,21 @@ esp_err_t httpd_set_recv_override(httpd_req_t *r, httpd_recv_func_t recv_func)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t httpd_set_pending_override(httpd_req_t *r, httpd_pending_func_t pending_func)
|
||||
{
|
||||
if (r == NULL || pending_func == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!httpd_valid_req(r)) {
|
||||
return ESP_ERR_HTTPD_INVALID_REQ;
|
||||
}
|
||||
|
||||
struct httpd_req_aux *ra = r->aux;
|
||||
ra->sd->pending_fn = pending_func;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int httpd_send(httpd_req_t *r, const char *buf, size_t buf_len)
|
||||
{
|
||||
if (r == NULL || buf == NULL) {
|
||||
@@ -63,7 +102,7 @@ int httpd_send(httpd_req_t *r, const char *buf, size_t buf_len)
|
||||
}
|
||||
|
||||
struct httpd_req_aux *ra = r->aux;
|
||||
int ret = ra->sd->send_fn(ra->sd->fd, buf, buf_len, 0);
|
||||
int ret = ra->sd->send_fn(ra->sd->handle, ra->sd->fd, buf, buf_len, 0);
|
||||
if (ret < 0) {
|
||||
ESP_LOGD(TAG, LOG_FMT("error in send_fn"));
|
||||
return ret;
|
||||
@@ -77,7 +116,7 @@ static esp_err_t httpd_send_all(httpd_req_t *r, const char *buf, size_t buf_len)
|
||||
int ret;
|
||||
|
||||
while (buf_len > 0) {
|
||||
ret = ra->sd->send_fn(ra->sd->fd, buf, buf_len, 0);
|
||||
ret = ra->sd->send_fn(ra->sd->handle, ra->sd->fd, buf, buf_len, 0);
|
||||
if (ret < 0) {
|
||||
ESP_LOGD(TAG, LOG_FMT("error in send_fn"));
|
||||
return ESP_FAIL;
|
||||
@@ -125,7 +164,7 @@ int httpd_recv_with_opt(httpd_req_t *r, char *buf, size_t buf_len, bool halt_aft
|
||||
}
|
||||
|
||||
/* Receive data of remaining length */
|
||||
int ret = ra->sd->recv_fn(ra->sd->fd, buf, buf_len, 0);
|
||||
int ret = ra->sd->recv_fn(ra->sd->handle, ra->sd->fd, buf, buf_len, 0);
|
||||
if (ret < 0) {
|
||||
ESP_LOGD(TAG, LOG_FMT("error in recv_fn"));
|
||||
if ((ret == HTTPD_SOCK_ERR_TIMEOUT) && (pending_len != 0)) {
|
||||
@@ -231,7 +270,7 @@ esp_err_t httpd_resp_set_type(httpd_req_t *r, const char *type)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, size_t buf_len)
|
||||
esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, ssize_t buf_len)
|
||||
{
|
||||
if (r == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -246,6 +285,8 @@ esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, size_t buf_len)
|
||||
const char *colon_separator = ": ";
|
||||
const char *cr_lf_seperator = "\r\n";
|
||||
|
||||
if (buf_len == -1) buf_len = strlen(buf);
|
||||
|
||||
/* Request headers are no longer available */
|
||||
ra->req_hdrs_count = 0;
|
||||
|
||||
@@ -294,7 +335,7 @@ esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, size_t buf_len)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t httpd_resp_send_chunk(httpd_req_t *r, const char *buf, size_t buf_len)
|
||||
esp_err_t httpd_resp_send_chunk(httpd_req_t *r, const char *buf, ssize_t buf_len)
|
||||
{
|
||||
if (r == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -304,6 +345,8 @@ esp_err_t httpd_resp_send_chunk(httpd_req_t *r, const char *buf, size_t buf_len)
|
||||
return ESP_ERR_HTTPD_INVALID_REQ;
|
||||
}
|
||||
|
||||
if (buf_len == -1) buf_len = strlen(buf);
|
||||
|
||||
struct httpd_req_aux *ra = r->aux;
|
||||
const char *httpd_chunked_hdr_str = "HTTP/1.1 %s\r\nContent-Type: %s\r\nTransfer-Encoding: chunked\r\n";
|
||||
const char *colon_separator = ": ";
|
||||
@@ -359,7 +402,7 @@ esp_err_t httpd_resp_send_chunk(httpd_req_t *r, const char *buf, size_t buf_len)
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
if (httpd_send_all(r, buf, buf_len) != ESP_OK) {
|
||||
if (httpd_send_all(r, buf, (size_t) buf_len) != ESP_OK) {
|
||||
return ESP_ERR_HTTPD_RESP_SEND;
|
||||
}
|
||||
}
|
||||
@@ -520,8 +563,9 @@ static int httpd_sock_err(const char *ctx, int sockfd)
|
||||
return errval;
|
||||
}
|
||||
|
||||
int httpd_default_send(int sockfd, const char *buf, size_t buf_len, int flags)
|
||||
int httpd_default_send(httpd_handle_t hd, int sockfd, const char *buf, size_t buf_len, int flags)
|
||||
{
|
||||
(void)hd;
|
||||
if (buf == NULL) {
|
||||
return HTTPD_SOCK_ERR_INVALID;
|
||||
}
|
||||
@@ -533,8 +577,9 @@ int httpd_default_send(int sockfd, const char *buf, size_t buf_len, int flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int httpd_default_recv(int sockfd, char *buf, size_t buf_len, int flags)
|
||||
int httpd_default_recv(httpd_handle_t hd, int sockfd, char *buf, size_t buf_len, int flags)
|
||||
{
|
||||
(void)hd;
|
||||
if (buf == NULL) {
|
||||
return HTTPD_SOCK_ERR_INVALID;
|
||||
}
|
||||
|
Reference in New Issue
Block a user