diff --git a/components/esp_http_server/include/esp_http_server.h b/components/esp_http_server/include/esp_http_server.h index 842848c59..4094d9ef8 100644 --- a/components/esp_http_server/include/esp_http_server.h +++ b/components/esp_http_server/include/esp_http_server.h @@ -362,6 +362,18 @@ typedef struct httpd_req { * function for freeing the session context, please specify that here. */ httpd_free_ctx_fn_t free_ctx; + + /** + * Flag indicating if Session Context changes should be ignored + * + * By default, if you change the sess_ctx in some URI handler, the http server + * will internally free the earlier context (if non NULL), after the URI handler + * returns. If you want to manage the allocation/reallocation/freeing of + * sess_ctx yourself, set this flag to true, so that the server will not + * perform any checks on it. The context will be cleared by the server + * (by calling free_ctx or free()) only if the socket gets closed. + */ + bool ignore_sess_ctx_changes; } httpd_req_t; /** diff --git a/components/esp_http_server/src/esp_httpd_priv.h b/components/esp_http_server/src/esp_httpd_priv.h index 0a13361bb..d0cdfd0fd 100644 --- a/components/esp_http_server/src/esp_httpd_priv.h +++ b/components/esp_http_server/src/esp_httpd_priv.h @@ -60,6 +60,7 @@ struct thread_data { struct sock_db { int fd; /*!< The file descriptor for this socket */ void *ctx; /*!< A custom context for this socket */ + bool ignore_sess_ctx_changes; /*!< Flag indicating if session context changes should be ignored */ void *transport_ctx; /*!< A custom 'transport' context for this socket, to be used by send/recv/pending */ httpd_handle_t handle; /*!< Server handle */ httpd_free_ctx_fn_t free_ctx; /*!< Function for freeing the context */ diff --git a/components/esp_http_server/src/httpd_parse.c b/components/esp_http_server/src/httpd_parse.c index aa40809f1..2837778e0 100644 --- a/components/esp_http_server/src/httpd_parse.c +++ b/components/esp_http_server/src/httpd_parse.c @@ -588,6 +588,7 @@ static void init_req(httpd_req_t *r, httpd_config_t *config) r->user_ctx = 0; r->sess_ctx = 0; r->free_ctx = 0; + r->ignore_sess_ctx_changes = 0; } static void init_req_aux(struct httpd_req_aux *ra, httpd_config_t *config) @@ -607,13 +608,14 @@ static void httpd_req_cleanup(httpd_req_t *r) { struct httpd_req_aux *ra = r->aux; - /* Retrieve session info from the request into the socket database */ - if (ra->sd->ctx != r->sess_ctx) { - /* Free previous context */ + /* Check if the context has changed and needs to be cleared */ + if ((r->ignore_sess_ctx_changes == false) && (ra->sd->ctx != r->sess_ctx)) { httpd_sess_free_ctx(ra->sd->ctx, ra->sd->free_ctx); - ra->sd->ctx = r->sess_ctx; } + /* Retrieve session info from the request into the socket database. */ + ra->sd->ctx = r->sess_ctx; ra->sd->free_ctx = r->free_ctx; + ra->sd->ignore_sess_ctx_changes = r->ignore_sess_ctx_changes; /* Clear out the request and request_aux structures */ ra->sd = NULL; @@ -641,6 +643,7 @@ esp_err_t httpd_req_new(struct httpd_data *hd, struct sock_db *sd) /* Copy session info to the request */ r->sess_ctx = sd->ctx; r->free_ctx = sd->free_ctx; + r->ignore_sess_ctx_changes = sd->ignore_sess_ctx_changes; /* Parse request */ esp_err_t err = httpd_parse_req(hd); if (err != ESP_OK) {