Cancel Http client data download

Leander
Posts: 28
Joined: Thu Sep 26, 2019 8:50 pm

Cancel Http client data download

Postby Leander » Thu Jan 07, 2021 9:55 am

I'm using the http client to download a large file to the ESP. The file version is in the first part of the binary file. So I download the first 512 bytes and then check the version.
  1. If its an older version, I want to cancel the download.
  2. If the download is interrupted or fails, I want to retry.
  3. If the download is successful, I want to continue to the next step
The download data is chuncked so the handler starts multiple HTTP_EVENT_ON_DATA events until all data is downloaded.
I'm checking the received data and would like to stop the download at any time. In the HTTP_ON_DATA event I'm returning an esp_err_t state:
  1. Return ESP_ERR_INVALID_VERSION
  2. Return ESP_FAIL.
  3. Return ESP_OK
When I'm returning an error, the client continues to download the file and HTTP_ON_DATA events are triggered.

In the esp_http_client.c file the http_dispatch_event function is returning the esp_err_t from the handler.

Code: Select all

static esp_err_t http_dispatch_event(esp_http_client_t *client, esp_http_client_event_id_t event_id, void *data, int len)
{
    esp_http_client_event_t *event = &client->event;

    if (client->event_handler) {
        event->event_id = event_id;
        event->user_data = client->user_data;
        event->data = data;
        event->data_len = len;
        return client->event_handler(event);
    }
    return ESP_OK;
}
But the http_on_body function is ignoring the return value and always returns ESP_OK (0)

Code: Select all

static int http_on_body(http_parser *parser, const char *at, size_t length)
{
    esp_http_client_t *client = parser->data;
    ESP_LOGD(TAG, "http_on_body %d", length);
    client->response->buffer->raw_data = (char *)at;
    if (client->response->buffer->output_ptr) {
        memcpy(client->response->buffer->output_ptr, (char *)at, length);
        client->response->buffer->output_ptr += length;
    }

    client->response->data_process += length;
    client->response->buffer->raw_len += length;
    http_dispatch_event(client, HTTP_EVENT_ON_DATA, (void *)at, length);
    return 0;
}
If I'm changing the last line in esp_http_client.c and returning the http_dispatch_event, the download is stopped and the HTTP_EVENT_ON_FINISH is triggered. But only after the TCP receive timeout that for other reasons is set to 30s in my code.

I'm not fond of altering the original esp-idf libraries as its blocking future migration to new releases.

I tried to alter the esp_http_client_event_t->event_id in the HTTP_EVENT_ON_DATA and set it to HTTP_EVENT_ON_FINISH but that didn't work (download continues).

If I'm calling the "esp_http_client_close(evt->client);" function, the download stops without the HTTP_EVENT_ON_FINISH (no problem) but also after timeout of 15s.

For the moment this last method seems to be the best for the http server and client. In my opinion i could use global variable to indicate if the download was aborted, complete or not needed.

Are there any other methods or suggestions to cancel a download in a proper way?

toljatyr
Posts: 13
Joined: Mon Mar 07, 2022 10:39 am

Re: Cancel Http client data download

Postby toljatyr » Mon Mar 07, 2022 10:41 am

Hi, Leander
Have you found any solution for the issue?

Leander
Posts: 28
Joined: Thu Sep 26, 2019 8:50 pm

Re: Cancel Http client data download

Postby Leander » Mon Mar 07, 2022 1:14 pm

toljatyr wrote:
Mon Mar 07, 2022 10:41 am
Hi, Leander
Have you found any solution for the issue?
I'm still using the same method with the 15s timeout:
If I'm calling the "esp_http_client_close(evt->client);" function, the download stops without the HTTP_EVENT_ON_FINISH (no problem) but also after timeout of 15s.

ESP_YJM
Posts: 300
Joined: Fri Feb 26, 2021 10:30 am

Re: Cancel Http client data download

Postby ESP_YJM » Tue Mar 08, 2022 2:26 am

I think you can use low level http APIs to get http data. Like flow: esp_http_client_init->esp_http_client_open->esp_http_client_read. You can follow esp_http_client_example.c, function http_perform_as_stream_reader. No need to use http event handle.

toljatyr
Posts: 13
Joined: Mon Mar 07, 2022 10:39 am

Re: Cancel Http client data download

Postby toljatyr » Tue Apr 19, 2022 11:45 am

Solving a similar issue I solved it by using esp_http_client_close(client) within HTTP_EVENT_ON_DATA event which seemed to work at first. However, later I faced a problem - after calling esp_http_client_close the task become blocked inside esp_http_client_perform() function. Therefore, I came to a conclusion that it is not allowed to call esp_http_client_close from within http event handler - is this correct?

ESP_YJM
Posts: 300
Joined: Fri Feb 26, 2021 10:30 am

Re: Cancel Http client data download

Postby ESP_YJM » Tue May 10, 2022 3:16 am

Hi toljatyr,
Yes, you are right. It is not recommanded that do block action(such as call esp_http_client_close) in http event callback function.

Who is online

Users browsing this forum: No registered users and 96 guests