Skip to content

Commit 5058b75

Browse files
committed
Merge branch 'feature/partial_download_over_single_connection_v5.5' into 'release/v5.5'
feat(esp_https_ota): Support partial downloading of OTA over single connection (v5.5) See merge request espressif/esp-idf!42678
2 parents d56618c + 534b4be commit 5058b75

File tree

3 files changed

+79
-5
lines changed

3 files changed

+79
-5
lines changed

components/esp_http_client/esp_http_client.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ static const char *HTTP_METHOD_MAPPING[] = {
191191
"REPORT"
192192
};
193193

194-
static esp_err_t esp_http_client_request_send(esp_http_client_handle_t client, int write_len);
194+
esp_err_t esp_http_client_request_send(esp_http_client_handle_t client, int write_len);
195195
static esp_err_t esp_http_client_connect(esp_http_client_handle_t client);
196196
static esp_err_t esp_http_client_send_post_data(esp_http_client_handle_t client);
197197

@@ -667,8 +667,12 @@ static esp_err_t esp_http_client_prepare_digest_auth(esp_http_client_handle_t cl
667667
}
668668
#endif
669669

670-
static esp_err_t esp_http_client_prepare(esp_http_client_handle_t client)
670+
esp_err_t esp_http_client_prepare(esp_http_client_handle_t client)
671671
{
672+
if (client == NULL) {
673+
return ESP_FAIL;
674+
}
675+
672676
esp_err_t ret = ESP_OK;
673677
client->process_again = 0;
674678
client->response->data_process = 0;
@@ -1668,8 +1672,12 @@ static int http_client_prepare_first_line(esp_http_client_handle_t client, int w
16681672
return first_line_len;
16691673
}
16701674

1671-
static esp_err_t esp_http_client_request_send(esp_http_client_handle_t client, int write_len)
1675+
esp_err_t esp_http_client_request_send(esp_http_client_handle_t client, int write_len)
16721676
{
1677+
if (client == NULL) {
1678+
return ESP_FAIL;
1679+
}
1680+
16731681
int first_line_len = 0;
16741682
if (!client->first_line_prepared) {
16751683
if ((first_line_len = http_client_prepare_first_line(client, write_len)) < 0) {
@@ -2007,3 +2015,15 @@ esp_err_t esp_http_client_get_chunk_length(esp_http_client_handle_t client, int
20072015
}
20082016
return ESP_OK;
20092017
}
2018+
2019+
bool esp_http_client_is_persistent_connection(esp_http_client_handle_t client)
2020+
{
2021+
if (client == NULL) {
2022+
return false;
2023+
}
2024+
2025+
if (http_should_keep_alive(client->parser)) {
2026+
return true;
2027+
}
2028+
return false;
2029+
}

components/esp_http_client/include/esp_http_client.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,33 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
311311
*/
312312
esp_err_t esp_http_client_perform(esp_http_client_handle_t client);
313313

314+
/**
315+
* @brief Prepare HTTP client for a new request
316+
* This function initializes the client state and prepares authentication if needed.
317+
* It should be called before sending a request.
318+
*
319+
* @param[in] client The esp_http_client handle
320+
*
321+
* @return
322+
* - ESP_OK on successful
323+
* - ESP_FAIL on error
324+
*/
325+
esp_err_t esp_http_client_prepare(esp_http_client_handle_t client);
326+
327+
/**
328+
* @brief Send HTTP request headers and data
329+
* This function sends the HTTP request line, headers, and any post data to the server.
330+
*
331+
* @param[in] client The esp_http_client handle
332+
* @param[in] write_len Length of data to write (for POST/PUT requests)
333+
*
334+
* @return
335+
* - ESP_OK on successful
336+
* - ESP_FAIL on error
337+
* - ESP_ERR_HTTP_WRITE_DATA if write operation fails
338+
*/
339+
esp_err_t esp_http_client_request_send(esp_http_client_handle_t client, int write_len);
340+
314341
/**
315342
* @brief Cancel an ongoing HTTP request. This API closes the current socket and opens a new socket with the same esp_http_client context.
316343
*
@@ -808,6 +835,15 @@ esp_err_t esp_http_client_get_url(esp_http_client_handle_t client, char *url, co
808835
*/
809836
esp_err_t esp_http_client_get_chunk_length(esp_http_client_handle_t client, int *len);
810837

838+
/**
839+
* @brief Check if persistent connection is supported by the server
840+
*
841+
* @param[in] client The HTTP client handle
842+
*
843+
* @return true if persistent connection is supported, false otherwise
844+
*/
845+
bool esp_http_client_is_persistent_connection(esp_http_client_handle_t client);
846+
811847
#ifdef __cplusplus
812848
}
813849
#endif

components/esp_https_ota/src/esp_https_ota.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,22 @@ static esp_err_t _http_connect(esp_https_ota_t *https_ota_handle)
162162
* is enabled
163163
*/
164164
int post_len = esp_http_client_get_post_field(https_ota_handle->http_client, &post_data);
165-
err = esp_http_client_open(https_ota_handle->http_client, post_len);
165+
166+
#if CONFIG_ESP_HTTPS_OTA_ENABLE_PARTIAL_DOWNLOAD
167+
// If support_persistent_connection is enabled and this is a subsequent request, skip connection
168+
if (esp_http_client_is_persistent_connection(https_ota_handle->http_client) && https_ota_handle->state == ESP_HTTPS_OTA_IN_PROGRESS) {
169+
ESP_LOGD(TAG, "Using existing connection for partial download");
170+
err = esp_http_client_prepare(https_ota_handle->http_client);
171+
if (err != ESP_OK) {
172+
ESP_LOGE(TAG, "Failed to reset HTTP client response state: %s", esp_err_to_name(err));
173+
return err;
174+
}
175+
err = esp_http_client_request_send(https_ota_handle->http_client, post_len);
176+
} else
177+
#endif
178+
{
179+
err = esp_http_client_open(https_ota_handle->http_client, post_len);
180+
}
166181
if (err != ESP_OK) {
167182
ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
168183
return err;
@@ -769,7 +784,10 @@ esp_err_t esp_https_ota_perform(esp_https_ota_handle_t https_ota_handle)
769784
}
770785
if (handle->partial_http_download) {
771786
if (handle->state == ESP_HTTPS_OTA_IN_PROGRESS && handle->image_length > handle->binary_file_len) {
772-
esp_http_client_close(handle->http_client);
787+
// Only close connection if support_persistent_connection is not enabled
788+
if (!esp_http_client_is_persistent_connection(handle->http_client)) {
789+
esp_http_client_close(handle->http_client);
790+
}
773791
char *header_val = NULL;
774792
int header_size = 0;
775793
#if CONFIG_ESP_HTTPS_OTA_DECRYPT_CB

0 commit comments

Comments
 (0)