From 864c59c091f0711d0f7062be919d1e8aae5ec13e Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Thu, 24 Mar 2022 12:36:00 +0530 Subject: [PATCH 1/4] esp_tls: Remove deprecated API - Removed deprecated esp_tls_conn_new() viz. duplicated by esp_tls_conn_new_sync() - Removed deprecated esp_tls_conn_delete() - Marked esp_tls_conn_http_new() as deprecated, added alternative esp_tls_conn_http_new_sync() (similar to esp_tls_conn_http_new_async()) --- components/esp-tls/esp_tls.c | 53 +++++++++-------------------- components/esp-tls/esp_tls.h | 64 +++++++++++++++--------------------- 2 files changed, 42 insertions(+), 75 deletions(-) diff --git a/components/esp-tls/esp_tls.c b/components/esp-tls/esp_tls.c index ee57e0c792..386ecb0883 100644 --- a/components/esp-tls/esp_tls.c +++ b/components/esp-tls/esp_tls.c @@ -441,43 +441,8 @@ esp_err_t esp_tls_plain_tcp_connect(const char *host, int hostlen, int port, con return tcp_connect(host, hostlen, port, cfg, error_handle, sockfd); } -/** - * @brief Create a new TLS/SSL connection - */ -esp_tls_t *esp_tls_conn_new(const char *hostname, int hostlen, int port, const esp_tls_cfg_t *cfg) -{ - esp_tls_t *tls = esp_tls_init(); - if (!tls) { - return NULL; - } - /* esp_tls_conn_new() API establishes connection in a blocking manner thus this loop ensures that esp_tls_conn_new() - API returns only after connection is established unless there is an error*/ - size_t start = xTaskGetTickCount(); - while (1) { - int ret = esp_tls_low_level_conn(hostname, hostlen, port, cfg, tls); - if (ret == 1) { - return tls; - } else if (ret == -1) { - esp_tls_conn_destroy(tls); - ESP_LOGE(TAG, "Failed to open new connection"); - return NULL; - } else if (ret == 0 && cfg->timeout_ms >= 0) { - size_t timeout_ticks = pdMS_TO_TICKS(cfg->timeout_ms); - uint32_t expired = xTaskGetTickCount() - start; - if (expired >= timeout_ticks) { - esp_tls_conn_destroy(tls); - ESP_LOGE(TAG, "Failed to open new connection in specified timeout"); - return NULL; - } - } - } - return NULL; -} - int esp_tls_conn_new_sync(const char *hostname, int hostlen, int port, const esp_tls_cfg_t *cfg, esp_tls_t *tls) { - /* esp_tls_conn_new_sync() is a sync alternative to esp_tls_conn_new_async() with symmetric function prototype - it is an alternative to esp_tls_conn_new() which is left for compatibility reasons */ size_t start = xTaskGetTickCount(); while (1) { int ret = esp_tls_low_level_conn(hostname, hostlen, port, cfg, tls); @@ -521,9 +486,6 @@ static int get_port(const char *url, struct http_parser_url *u) return 0; } -/** - * @brief Create a new TLS/SSL connection with a given "HTTP" url - */ esp_tls_t *esp_tls_conn_http_new(const char *url, const esp_tls_cfg_t *cfg) { /* Parse URI */ @@ -543,6 +505,21 @@ esp_tls_t *esp_tls_conn_http_new(const char *url, const esp_tls_cfg_t *cfg) return NULL; } +/** + * @brief Create a new TLS/SSL connection with a given "HTTP" url + */ +int esp_tls_conn_http_new_sync(const char *url, const esp_tls_cfg_t *cfg, esp_tls_t *tls) +{ + /* Parse URI */ + struct http_parser_url u; + http_parser_url_init(&u); + http_parser_parse_url(url, strlen(url), 0, &u); + + /* Connect to host */ + return esp_tls_conn_new_sync(&url[u.field_data[UF_HOST].off], u.field_data[UF_HOST].len, + get_port(url, &u), cfg, tls); +} + /** * @brief Create a new non-blocking TLS/SSL connection with a given "HTTP" url */ diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index c147619804..a4bbf8e2f2 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -351,7 +351,6 @@ typedef struct esp_tls { } esp_tls_t; - /** * @brief Create TLS connection * @@ -362,29 +361,21 @@ typedef struct esp_tls { */ esp_tls_t *esp_tls_init(void); - - - /** - * @brief Create a new blocking TLS/SSL connection - * - * This function establishes a TLS/SSL connection with the specified host in blocking manner. + * @brief Create a new blocking TLS/SSL connection with a given "HTTP" url * * Note: This API is present for backward compatibility reasons. Alternative function - * with the same functionality is `esp_tls_conn_new_sync` (and its asynchronous version - * `esp_tls_conn_new_async`) - * - * @param[in] hostname Hostname of the host. - * @param[in] hostlen Length of hostname. - * @param[in] port Port number of the host. - * @param[in] cfg TLS configuration as esp_tls_cfg_t. If you wish to open - * non-TLS connection, keep this NULL. For TLS connection, - * a pass pointer to esp_tls_cfg_t. At a minimum, this - * structure should be zero-initialized. + * with the same functionality is `esp_tls_conn_http_new_sync` (and its asynchronous version + * `esp_tls_conn_http_new_async`) * + * @param[in] url url of host. + * @param[in] cfg TLS configuration as esp_tls_cfg_t. If you wish to open + * non-TLS connection, keep this NULL. For TLS connection, + * a pass pointer to 'esp_tls_cfg_t'. At a minimum, this + * structure should be zero-initialized. * @return pointer to esp_tls_t, or NULL if connection couldn't be opened. */ -esp_tls_t *esp_tls_conn_new(const char *hostname, int hostlen, int port, const esp_tls_cfg_t *cfg) __attribute__ ((deprecated)); +esp_tls_t *esp_tls_conn_http_new(const char *url, const esp_tls_cfg_t *cfg) __attribute__((deprecated("Please use esp_tls_conn_http_new_sync (or its asynchronous version esp_tls_conn_http_new_async) instead"))); /** * @brief Create a new blocking TLS/SSL connection @@ -410,16 +401,21 @@ int esp_tls_conn_new_sync(const char *hostname, int hostlen, int port, const esp /** * @brief Create a new blocking TLS/SSL connection with a given "HTTP" url * - * The behaviour is same as esp_tls_conn_new() API. However this API accepts host's url. + * The behaviour is same as esp_tls_conn_new_sync() API. However this API accepts host's url. * - * @param[in] url url of host. - * @param[in] cfg TLS configuration as esp_tls_cfg_t. If you wish to open - * non-TLS connection, keep this NULL. For TLS connection, - * a pass pointer to 'esp_tls_cfg_t'. At a minimum, this - * structure should be zero-initialized. - * @return pointer to esp_tls_t, or NULL if connection couldn't be opened. + * @param[in] url url of host. + * @param[in] cfg TLS configuration as esp_tls_cfg_t. If you wish to open + * non-TLS connection, keep this NULL. For TLS connection, + * a pass pointer to 'esp_tls_cfg_t'. At a minimum, this + * structure should be zero-initialized. + * @param[in] tls Pointer to esp-tls as esp-tls handle. + * + * @return + * - -1 If connection establishment fails. + * - 1 If connection establishment is successful. + * - 0 If connection state is in progress. */ -esp_tls_t *esp_tls_conn_http_new(const char *url, const esp_tls_cfg_t *cfg); +int esp_tls_conn_http_new_sync(const char *url, const esp_tls_cfg_t *cfg, esp_tls_t *tls); /** * @brief Create a new non-blocking TLS/SSL connection @@ -444,7 +440,7 @@ int esp_tls_conn_new_async(const char *hostname, int hostlen, int port, const es /** * @brief Create a new non-blocking TLS/SSL connection with a given "HTTP" url * - * The behaviour is same as esp_tls_conn_new() API. However this API accepts host's url. + * The behaviour is same as esp_tls_conn_new_async() API. However this API accepts host's url. * * @param[in] url url of host. * @param[in] cfg TLS configuration as esp_tls_cfg_t. @@ -499,18 +495,12 @@ static inline ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t data return tls->read(tls, (char *)data, datalen); } -/** - * @brief Compatible version of esp_tls_conn_destroy() to close the TLS/SSL connection - * - * @param[in] tls pointer to esp-tls as esp-tls handle. - */ -void esp_tls_conn_delete(esp_tls_t *tls) __attribute__((deprecated("Please use esp_tls_conn_destroy() instead"))); - /** * @brief Close the TLS/SSL connection and free any allocated resources. * - * This function should be called to close each tls connection opened with esp_tls_conn_new() or - * esp_tls_conn_http_new() APIs. + * This function should be called to close each tls connection opened with + * esp_tls_conn_new_sync() (or esp_tls_conn_http_new_sync()) and + * esp_tls_conn_new_async() (or esp_tls_conn_http_new_async()) APIs. * * @param[in] tls pointer to esp-tls as esp-tls handle. * @@ -681,7 +671,7 @@ esp_err_t esp_tls_plain_tcp_connect(const char *host, int hostlen, int port, con * @brief Obtain the client session ticket * * This function should be called when the TLS connection is already established. - * This can be passed again in the esp_tls_cfg_t structure, to appropriate tls session create (e.g. esp_tls_conn_http_new) API for session resumption. + * This can be passed again in the esp_tls_cfg_t structure, to appropriate tls session create (e.g. esp_tls_conn_http_new_sync) API for session resumption. * * @param[in] esp_tls context as esp_tls_t * @return From 728a686b8a7309d16fc6293f7aec69fc9442442f Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Thu, 24 Mar 2022 13:57:52 +0530 Subject: [PATCH 2/4] protocols: Updated examples to use correct API - `http_request` and `https_x509_bundle` --- .../main/https_request_example_main.c | 38 ++++++++++--------- .../main/https_x509_bundle_example_main.c | 15 +++++--- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/examples/protocols/https_request/main/https_request_example_main.c b/examples/protocols/https_request/main/https_request_example_main.c index 86ba9ff464..01c40c04c1 100644 --- a/examples/protocols/https_request/main/https_request_example_main.c +++ b/examples/protocols/https_request/main/https_request_example_main.c @@ -1,11 +1,12 @@ -/* HTTPS GET Example using plain mbedTLS sockets +/* + * HTTPS GET Example using plain Mbed TLS sockets * * Contacts the howsmyssl.com API via TLS v1.2 and reads a JSON * response. * - * Adapted from the ssl_client1 example in mbedtls. + * Adapted from the ssl_client1 example in Mbed TLS. * - * SPDX-FileCopyrightText: 2006-2016 ARM Limited, All Rights Reserved + * SPDX-FileCopyrightText: The Mbed TLS Contributors * * SPDX-License-Identifier: Apache-2.0 * @@ -91,13 +92,17 @@ static void https_get_request(esp_tls_cfg_t cfg, const char *WEB_SERVER_URL, con char buf[512]; int ret, len; - struct esp_tls *tls = esp_tls_conn_http_new(WEB_SERVER_URL, &cfg); + esp_tls_t *tls = esp_tls_init(); + if (!tls) { + ESP_LOGE(TAG, "Failed to allocate esp_tls handle!"); + goto exit; + } - if (tls != NULL) { + if (esp_tls_conn_http_new_sync(WEB_SERVER_URL, &cfg, tls) == 1) { ESP_LOGI(TAG, "Connection established..."); } else { ESP_LOGE(TAG, "Connection failed..."); - goto exit; + goto cleanup; } #ifdef CONFIG_EXAMPLE_CLIENT_SESSION_TICKETS @@ -107,6 +112,7 @@ static void https_get_request(esp_tls_cfg_t cfg, const char *WEB_SERVER_URL, con tls_client_session = esp_tls_get_client_session(tls); } #endif + size_t written_bytes = 0; do { ret = esp_tls_conn_write(tls, @@ -117,27 +123,22 @@ static void https_get_request(esp_tls_cfg_t cfg, const char *WEB_SERVER_URL, con written_bytes += ret; } else if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE) { ESP_LOGE(TAG, "esp_tls_conn_write returned: [0x%02X](%s)", ret, esp_err_to_name(ret)); - goto exit; + goto cleanup; } } while (written_bytes < strlen(REQUEST)); ESP_LOGI(TAG, "Reading HTTP response..."); - do { len = sizeof(buf) - 1; - bzero(buf, sizeof(buf)); + memset(buf, 0x00, sizeof(buf)); ret = esp_tls_conn_read(tls, (char *)buf, len); if (ret == ESP_TLS_ERR_SSL_WANT_WRITE || ret == ESP_TLS_ERR_SSL_WANT_READ) { continue; - } - - if (ret < 0) { + } else if (ret < 0) { ESP_LOGE(TAG, "esp_tls_conn_read returned [-0x%02X](%s)", -ret, esp_err_to_name(ret)); break; - } - - if (ret == 0) { + } else if (ret == 0) { ESP_LOGI(TAG, "connection closed"); break; } @@ -151,8 +152,9 @@ static void https_get_request(esp_tls_cfg_t cfg, const char *WEB_SERVER_URL, con putchar('\n'); // JSON output doesn't have a newline at end } while (1); -exit: +cleanup: esp_tls_conn_destroy(tls); +exit: for (int countdown = 10; countdown >= 0; countdown--) { ESP_LOGI(TAG, "%d...", countdown); vTaskDelay(1000 / portTICK_PERIOD_MS); @@ -251,7 +253,7 @@ static void https_request_task(void *pvparameters) #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE https_get_request_using_crt_bundle(); #endif - printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size()); + ESP_LOGI(TAG, "Minimum free heap size: %d bytes", esp_get_minimum_free_heap_size()); https_get_request_using_cacert_buf(); https_get_request_using_global_ca_store(); ESP_LOGI(TAG, "Finish https_request example"); @@ -260,7 +262,7 @@ static void https_request_task(void *pvparameters) void app_main(void) { - ESP_ERROR_CHECK( nvs_flash_init() ); + ESP_ERROR_CHECK(nvs_flash_init()); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); diff --git a/examples/protocols/https_x509_bundle/main/https_x509_bundle_example_main.c b/examples/protocols/https_x509_bundle/main/https_x509_bundle_example_main.c index 7521f30638..966aa8173e 100644 --- a/examples/protocols/https_x509_bundle/main/https_x509_bundle_example_main.c +++ b/examples/protocols/https_x509_bundle/main/https_x509_bundle_example_main.c @@ -56,16 +56,20 @@ static void https_get_task(void *pvParameters) { while (1) { int conn_count = 0; - ESP_LOGI(TAG, "Connecting to %d URLs", MAX_URLS); + for (int i = 0; i < MAX_URLS; i++) { esp_tls_cfg_t cfg = { .crt_bundle_attach = esp_crt_bundle_attach, }; - struct esp_tls *tls = esp_tls_conn_http_new(web_urls[i], &cfg); + esp_tls_t *tls = esp_tls_init(); + if (!tls) { + ESP_LOGE(TAG, "Failed to allocate esp_tls handle!"); + goto end; + } - if (tls != NULL) { + if (esp_tls_conn_http_new_sync(web_urls[i], &cfg, tls) == 1) { ESP_LOGI(TAG, "Connection established to %s", web_urls[i]); conn_count++; } else { @@ -73,6 +77,7 @@ static void https_get_task(void *pvParameters) } esp_tls_conn_destroy(tls); +end: vTaskDelay(1000 / portTICK_PERIOD_MS); } @@ -83,8 +88,8 @@ static void https_get_task(void *pvParameters) void app_main(void) { - ESP_ERROR_CHECK( nvs_flash_init() ); - esp_netif_init(); + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. From 25b20922191d3581dced33fee3643b6891d91ce0 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Thu, 24 Mar 2022 14:31:44 +0530 Subject: [PATCH 3/4] docs: Added breaking changes for ESP-TLS to migration guide --- docs/en/api-reference/protocols/esp_tls.rst | 4 +++- docs/en/migration-guides/protocols.rst | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/docs/en/api-reference/protocols/esp_tls.rst b/docs/en/api-reference/protocols/esp_tls.rst index 1dac78860f..7cfe243e09 100644 --- a/docs/en/api-reference/protocols/esp_tls.rst +++ b/docs/en/api-reference/protocols/esp_tls.rst @@ -8,7 +8,9 @@ The ESP-TLS component provides a simplified API interface for accessing the comm It supports common scenarios like CA certification validation, SNI, ALPN negotiation, non-blocking connection among others. All the configuration can be specified in the ``esp_tls_cfg_t`` data structure. Once done, TLS communication can be conducted using the following APIs: - * :cpp:func:`esp_tls_conn_new`: for opening a new TLS connection. + * :cpp:func:`esp_tls_init`: for initializing the TLS connection handle. + * :cpp:func:`esp_tls_conn_new_sync`: for opening a new blocking TLS connection. + * :cpp:func:`esp_tls_conn_new_async`: for opening a new non-blocking TLS connection. * :cpp:func:`esp_tls_conn_read`: for reading from the connection. * :cpp:func:`esp_tls_conn_write`: for writing into the connection. * :cpp:func:`esp_tls_conn_destroy`: for freeing up the connection. diff --git a/docs/en/migration-guides/protocols.rst b/docs/en/migration-guides/protocols.rst index 1ddead369a..b7e3359bed 100644 --- a/docs/en/migration-guides/protocols.rst +++ b/docs/en/migration-guides/protocols.rst @@ -93,4 +93,23 @@ ESP HTTPS OTA Breaking Changes (Summary) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- The function :cpp:func:`esp_https_ota()` now requires pointer to :cpp:type:`esp_https_ota_config_t` as argument instead of pointer to :cpp:type:`esp_http_client_config_t`. +- The function :cpp:func:`esp_https_ota` now requires pointer to :cpp:type:`esp_https_ota_config_t` as argument instead of pointer to :cpp:type:`esp_http_client_config_t`. + + +ESP-TLS +-------------- + +Breaking Changes (Summary) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Following table summarizes the deprecated functions removed and their alternatives to be used from ESP-IDF v5.0 onwards. + ++-----------------------------------+----------------------------------------+ +| Function | Alternative | ++===================================+========================================+ +| :cpp:func:`esp_tls_conn_new` | :cpp:func:`esp_tls_conn_new_sync` | ++-----------------------------------+----------------------------------------+ +| :cpp:func:`esp_tls_conn_delete` | :cpp:func:`esp_tls_conn_destroy` | ++-----------------------------------+----------------------------------------+ + +- The function :cpp:func:`esp_tls_conn_http_new` has now been termed as deprecated. Please use the alternative function :cpp:func:`esp_tls_conn_http_new_sync` (or its asynchronous :cpp:func:`esp_tls_conn_http_new_async`). Note that the alternatives need an additional parameter :cpp:type:`esp_tls_t` which has to be initialized using the :cpp:func:`esp_tls_init` function. From 88c33b52bf2348096dfd697e9773ce1026de610f Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Mon, 18 Apr 2022 10:03:06 +0530 Subject: [PATCH 4/4] http2_request: Disable build in CI - Tracked by IDF-4916 --- examples/protocols/http2_request/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/protocols/http2_request/README.md b/examples/protocols/http2_request/README.md index e7be3a83ef..6a5836d80a 100644 --- a/examples/protocols/http2_request/README.md +++ b/examples/protocols/http2_request/README.md @@ -1,3 +1,6 @@ +| Supported Targets | Linux | +| ----------------- | ----- | + # HTTP/2 Request Example Establish an HTTP/2 connection with https://http2.github.io