Skip to content

Commit

Permalink
feat(websocket): Added new API esp_websocket_client_append_header
Browse files Browse the repository at this point in the history
  • Loading branch information
suren-gabrielyan-espressif committed Oct 10, 2023
1 parent ea14e15 commit 3e37746
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 3 deletions.
45 changes: 45 additions & 0 deletions components/esp_websocket_client/esp_websocket_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions components/esp_websocket_client/examples/linux/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ static void websocket_app_start(void)
}

ESP_LOGI(TAG, "Sending fragmented message");
vTaskDelay(1000 / portTICK_PERIOD_MS);
vTaskDelay(2000 / 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));
Expand Down
22 changes: 20 additions & 2 deletions components/esp_websocket_client/include/esp_websocket_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 specific header to the current set.
*
* @param[in] client The WebSocket client handle
* @param[in] headers Additional header strings each terminated with \r\n
*
* @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
*
Expand Down

0 comments on commit 3e37746

Please sign in to comment.