Procházet zdrojové kódy

Merge branch 'bugfix/fix_httpd_req_cleanup' into 'master'

esp_http_server: fix wrong context pointer in httpd_req_cleanup function

Closes IDFGH-8842

See merge request espressif/esp-idf!21320
Mahavir Jain před 3 roky
rodič
revize
35d2a825c4

+ 1 - 1
components/esp_http_server/src/httpd_parse.c

@@ -695,7 +695,7 @@ static void httpd_req_cleanup(httpd_req_t *r)
 
     /* 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);
+        httpd_sess_free_ctx(&ra->sd->ctx, ra->sd->free_ctx);
     }
 
 #if CONFIG_HTTPD_WS_SUPPORT

+ 9 - 0
examples/protocols/http_server/persistent_sockets/main/Kconfig.projbuild

@@ -0,0 +1,9 @@
+menu "Example Configuration"
+
+    config EXAMPLE_SESSION_CTX_HANDLERS
+        bool "Update session ctx from another handler"
+        default n
+        help
+            Feature to show how session ctx can be manipulated by other handlers.
+
+endmenu

+ 61 - 0
examples/protocols/http_server/persistent_sockets/main/main.c

@@ -99,6 +99,47 @@ static esp_err_t adder_get_handler(httpd_req_t *req)
     return ESP_OK;
 }
 
+#if CONFIG_EXAMPLE_SESSION_CTX_HANDLERS
+// login and logout handler are created to test the server functionality to delete the older sess_ctx if it is changed from another handler.
+// login handler creates a new sess_ctx
+static esp_err_t login_handler(httpd_req_t *req)
+{
+    /* Log total visitors */
+    unsigned *visitors = (unsigned *)req->user_ctx;
+    ESP_LOGI(TAG, "/login visitor count = %d", ++(*visitors));
+
+    char outbuf[50];
+
+    /* Create session's context if not already available */
+    if (! req->sess_ctx) {
+        ESP_LOGI(TAG, "/login GET allocating new session");
+        req->sess_ctx = malloc(sizeof(int));
+        if (!req->sess_ctx) {
+            return ESP_ERR_NO_MEM;
+        }
+        *(int *)req->sess_ctx = 1;
+    }
+    ESP_LOGI(TAG, "/login GET handler send %d", *(int *)req->sess_ctx);
+
+    /* Respond with the accumulated value */
+    snprintf(outbuf, sizeof(outbuf),"%d", *((int *)req->sess_ctx));
+    httpd_resp_send(req, outbuf, HTTPD_RESP_USE_STRLEN);
+    return ESP_OK;
+}
+
+// This handler sets sess_ctx to NULL.
+static esp_err_t logout_handler(httpd_req_t *req)
+{
+    ESP_LOGI(TAG, "Logging out");
+    // Setting sess_ctx to NULL here. This is done to test the server functionality to free the older sesss_ctx if it is changed by some handler.
+    req->sess_ctx = NULL;
+    char outbuf[50];
+    snprintf(outbuf, sizeof(outbuf),"%d", 1);
+    httpd_resp_send(req, outbuf, HTTPD_RESP_USE_STRLEN);
+    return ESP_OK;
+}
+#endif // CONFIG_EXAMPLE_SESSION_CTX_HANDLERS
+
 /* This handler resets the value of the accumulator */
 static esp_err_t adder_put_handler(httpd_req_t *req)
 {
@@ -155,6 +196,22 @@ static const httpd_uri_t adder_get = {
     .user_ctx = &visitors
 };
 
+#if CONFIG_EXAMPLE_SESSION_CTX_HANDLERS
+static const httpd_uri_t login = {
+    .uri      = "/login",
+    .method   = HTTP_GET,
+    .handler  = login_handler,
+    .user_ctx = &visitors
+};
+
+static const httpd_uri_t logout = {
+    .uri      = "/logout",
+    .method   = HTTP_GET,
+    .handler  = logout_handler,
+    .user_ctx = &visitors
+};
+#endif // CONFIG_EXAMPLE_SESSION_CTX_HANDLERS
+
 static const httpd_uri_t adder_put = {
     .uri      = "/adder",
     .method   = HTTP_PUT,
@@ -173,6 +230,10 @@ static httpd_handle_t start_webserver(void)
         // Set URI handlers
         ESP_LOGI(TAG, "Registering URI handlers");
         httpd_register_uri_handler(server, &adder_get);
+#if CONFIG_EXAMPLE_SESSION_CTX_HANDLERS
+        httpd_register_uri_handler(server, &login);
+        httpd_register_uri_handler(server, &logout);
+#endif // CONFIG_EXAMPLE_SESSION_CTX_HANDLERS
         httpd_register_uri_handler(server, &adder_put);
         httpd_register_uri_handler(server, &adder_post);
         return server;

+ 10 - 0
examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py

@@ -60,6 +60,16 @@ def test_examples_protocol_http_server_persistence(dut: Dut) -> None:
     visitor = 0
     adder = 0
 
+    # Test login and logout
+    if client.getreq(conn, '/login').decode() != str(1):
+        raise RuntimeError
+    visitor += 1
+    dut.expect('/login visitor count = ' + str(visitor), timeout=30)
+    dut.expect('/login GET handler send ' + str(1), timeout=30)
+    if client.getreq(conn, '/logout').decode() != str(1):
+        raise RuntimeError
+    dut.expect('Logging out', timeout=30)
+
     # Test PUT request and initialize session context
     num = random.randint(0,100)
     client.putreq(conn, '/adder', str(num))

+ 1 - 0
examples/protocols/http_server/persistent_sockets/sdkconfig.ci

@@ -1 +1,2 @@
 CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y
+CONFIG_EXAMPLE_SESSION_CTX_HANDLERS=y