Skip to content

Commit 3e8de3a

Browse files
authored
Merge pull request espressif#371 from gabsuren/feat/ws_client_multiheader_api
feat(websocket): Added new API `esp_websocket_client_append_header` (IDF-7893)
2 parents 9e3c53c + 39e9725 commit 3e8de3a

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

components/esp_websocket_client/esp_websocket_client.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,51 @@ esp_err_t esp_websocket_client_set_headers(esp_websocket_client_handle_t client,
792792
return ret;
793793
}
794794

795+
esp_err_t esp_websocket_client_append_header(esp_websocket_client_handle_t client, const char *key, const char *value)
796+
{
797+
// Validate the input parameters
798+
if (client == NULL || key == NULL || value == NULL) {
799+
return ESP_ERR_INVALID_ARG;
800+
}
801+
802+
websocket_config_storage_t *cfg = client->config;
803+
804+
// Calculate the length for "key: value\r\n"
805+
size_t len = strlen(key) + strlen(value) + 5; // 5 accounts for ": \r\n" and null-terminator
806+
807+
// If no previous headers exist
808+
if (cfg->headers == NULL) {
809+
cfg->headers = (char *)malloc(len);
810+
if (cfg->headers == NULL) {
811+
ESP_LOGE(TAG, "Failed to allocate...");
812+
return ESP_ERR_NO_MEM;
813+
}
814+
snprintf(cfg->headers, len, "%s: %s\r\n", key, value);
815+
return ESP_OK;
816+
}
817+
818+
// Extend the current headers to accommodate the new key-value pair
819+
size_t current_len = strlen(cfg->headers);
820+
size_t new_len = current_len + len;
821+
822+
// Allocate memory for new headers
823+
char *new_headers = (char *)malloc(new_len);
824+
if (new_headers == NULL) {
825+
ESP_LOGE(TAG, "Failed to allocate...");
826+
return ESP_ERR_NO_MEM;
827+
}
828+
829+
// Copy old headers and append the new header
830+
strcpy(new_headers, cfg->headers);
831+
snprintf(new_headers + current_len, len, "%s: %s\r\n", key, value);
832+
833+
// Free old headers and assign the new header pointer to cfg->headers
834+
free(cfg->headers);
835+
cfg->headers = new_headers;
836+
837+
return ESP_OK;
838+
}
839+
795840
static esp_err_t esp_websocket_client_recv(esp_websocket_client_handle_t client)
796841
{
797842
int rlen;

components/esp_websocket_client/examples/linux/main/main.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ static void websocket_app_start(void)
7979
ESP_LOGI(TAG, "Connecting to %s...", websocket_cfg.uri);
8080

8181
esp_websocket_client_handle_t client = esp_websocket_client_init(&websocket_cfg);
82+
// This call demonstrates adding another header; it's called to increase code coverage
83+
esp_websocket_client_append_header(client, "HeaderNewKey", "value");
84+
8285
esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, websocket_event_handler, (void *)client);
8386

8487
esp_websocket_client_start(client);
@@ -93,6 +96,14 @@ static void websocket_app_start(void)
9396
vTaskDelay(1000 / portTICK_PERIOD_MS);
9497
}
9598

99+
ESP_LOGI(TAG, "Sending fragmented message");
100+
vTaskDelay(1000 / portTICK_PERIOD_MS);
101+
memset(data, 'a', sizeof(data));
102+
esp_websocket_client_send_text_partial(client, data, sizeof(data), portMAX_DELAY);
103+
memset(data, 'b', sizeof(data));
104+
esp_websocket_client_send_cont_msg(client, data, sizeof(data), portMAX_DELAY);
105+
esp_websocket_client_send_fin(client, portMAX_DELAY);
106+
96107
esp_websocket_client_destroy(client);
97108
}
98109

components/esp_websocket_client/include/esp_websocket_client.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,31 @@ esp_err_t esp_websocket_client_set_uri(esp_websocket_client_handle_t client, con
158158
* @brief Set additional websocket headers for the client, when performing this behavior, the headers will replace the old ones
159159
* @pre Must stop the WebSocket client before set headers if the client has been connected
160160
*
161-
* @param[in] client The client
162-
* @param headers additional header strings each terminated with \r\n
161+
* - This API should be used after the WebSocket client connection has succeeded (i.e., once the transport layer is initialized).
162+
* - If you wish to set or append headers before the WebSocket client connection is established(before handshake), consider the following options:
163+
* 1. Input headers directly into the config options, terminating each item with [CR][LF]. This approach will replace any previous headers.
164+
* Example: websocket_cfg.headers = "Sec-WebSocket-Key: my_key\r\nPassword: my_pass\r\n";
165+
* 2. Use the `esp_websocket_client_append_header` API to append a single header to the current set.
166+
*
167+
* @param[in] client The WebSocket client handle
168+
* @param[in] headers Additional header strings each terminated with [CR][LF]
163169
*
164170
* @return esp_err_t
165171
*/
166172
esp_err_t esp_websocket_client_set_headers(esp_websocket_client_handle_t client, const char *headers);
167173

174+
/**
175+
* @brief Appends a new key-value pair to the headers of a WebSocket client.
176+
* @pre Ensure that this function is called before starting the WebSocket client.
177+
*
178+
* @param[in] client The WebSocket client handle
179+
* @param[in] key The header key to append
180+
* @param[in] value The associated value for the given key
181+
*
182+
* @return esp_err_t
183+
*/
184+
esp_err_t esp_websocket_client_append_header(esp_websocket_client_handle_t client, const char *key, const char *value);
185+
168186
/**
169187
* @brief Open the WebSocket connection
170188
*

0 commit comments

Comments
 (0)