diff --git a/components/esp_websocket_client/esp_websocket_client.c b/components/esp_websocket_client/esp_websocket_client.c index 27adc5ce26..8c2b84eb90 100644 --- a/components/esp_websocket_client/esp_websocket_client.c +++ b/components/esp_websocket_client/esp_websocket_client.c @@ -792,6 +792,51 @@ esp_err_t esp_websocket_client_set_headers(esp_websocket_client_handle_t client, return ret; } +esp_err_t esp_websocket_client_append_header(esp_websocket_client_handle_t client, const char *key, const char *value) +{ + // Validate the input parameters + if (client == NULL || key == NULL || value == NULL) { + return ESP_ERR_INVALID_ARG; + } + + websocket_config_storage_t *cfg = client->config; + + // Calculate the length for "key: value\r\n" + size_t len = strlen(key) + strlen(value) + 5; // 5 accounts for ": \r\n" and null-terminator + + // If no previous headers exist + if (cfg->headers == NULL) { + cfg->headers = (char *)malloc(len); + if (cfg->headers == NULL) { + ESP_LOGE(TAG, "Failed to allocate..."); + return ESP_ERR_NO_MEM; + } + snprintf(cfg->headers, len, "%s: %s\r\n", key, value); + return ESP_OK; + } + + // Extend the current headers to accommodate the new key-value pair + size_t current_len = strlen(cfg->headers); + size_t new_len = current_len + len; + + // Allocate memory for new headers + char *new_headers = (char *)malloc(new_len); + if (new_headers == NULL) { + ESP_LOGE(TAG, "Failed to allocate..."); + return ESP_ERR_NO_MEM; + } + + // Copy old headers and append the new header + strcpy(new_headers, cfg->headers); + snprintf(new_headers + current_len, len, "%s: %s\r\n", key, value); + + // Free old headers and assign the new header pointer to cfg->headers + free(cfg->headers); + cfg->headers = new_headers; + + return ESP_OK; +} + static esp_err_t esp_websocket_client_recv(esp_websocket_client_handle_t client) { int rlen; diff --git a/components/esp_websocket_client/examples/linux/main/main.c b/components/esp_websocket_client/examples/linux/main/main.c index e89495bb64..e52dd42fd3 100644 --- a/components/esp_websocket_client/examples/linux/main/main.c +++ b/components/esp_websocket_client/examples/linux/main/main.c @@ -79,6 +79,9 @@ static void websocket_app_start(void) ESP_LOGI(TAG, "Connecting to %s...", websocket_cfg.uri); esp_websocket_client_handle_t client = esp_websocket_client_init(&websocket_cfg); + // This call demonstrates adding another header; it's called to increase code coverage + esp_websocket_client_append_header(client, "HeaderNewKey", "value"); + esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, websocket_event_handler, (void *)client); esp_websocket_client_start(client); @@ -93,6 +96,14 @@ static void websocket_app_start(void) vTaskDelay(1000 / portTICK_PERIOD_MS); } + ESP_LOGI(TAG, "Sending fragmented message"); + vTaskDelay(1000 / portTICK_PERIOD_MS); + memset(data, 'a', sizeof(data)); + esp_websocket_client_send_text_partial(client, data, sizeof(data), portMAX_DELAY); + memset(data, 'b', sizeof(data)); + esp_websocket_client_send_cont_msg(client, data, sizeof(data), portMAX_DELAY); + esp_websocket_client_send_fin(client, portMAX_DELAY); + esp_websocket_client_destroy(client); } diff --git a/components/esp_websocket_client/include/esp_websocket_client.h b/components/esp_websocket_client/include/esp_websocket_client.h index 0f7af07f44..db7e8cdb8a 100644 --- a/components/esp_websocket_client/include/esp_websocket_client.h +++ b/components/esp_websocket_client/include/esp_websocket_client.h @@ -158,13 +158,31 @@ esp_err_t esp_websocket_client_set_uri(esp_websocket_client_handle_t client, con * @brief Set additional websocket headers for the client, when performing this behavior, the headers will replace the old ones * @pre Must stop the WebSocket client before set headers if the client has been connected * - * @param[in] client The client - * @param headers additional header strings each terminated with \r\n + * - This API should be used after the WebSocket client connection has succeeded (i.e., once the transport layer is initialized). + * - If you wish to set or append headers before the WebSocket client connection is established(before handshake), consider the following options: + * 1. Input headers directly into the config options, terminating each item with [CR][LF]. This approach will replace any previous headers. + * Example: websocket_cfg.headers = "Sec-WebSocket-Key: my_key\r\nPassword: my_pass\r\n"; + * 2. Use the `esp_websocket_client_append_header` API to append a single header to the current set. + * + * @param[in] client The WebSocket client handle + * @param[in] headers Additional header strings each terminated with [CR][LF] * * @return esp_err_t */ esp_err_t esp_websocket_client_set_headers(esp_websocket_client_handle_t client, const char *headers); +/** + * @brief Appends a new key-value pair to the headers of a WebSocket client. + * @pre Ensure that this function is called before starting the WebSocket client. + * + * @param[in] client The WebSocket client handle + * @param[in] key The header key to append + * @param[in] value The associated value for the given key + * + * @return esp_err_t + */ +esp_err_t esp_websocket_client_append_header(esp_websocket_client_handle_t client, const char *key, const char *value); + /** * @brief Open the WebSocket connection *