-
Notifications
You must be signed in to change notification settings - Fork 7.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
esp_https_ota doesn't follow redirects (IDFGH-850) #3218
Comments
I have an idea why this happens. ota_write_err = esp_ota_write(update_handle, (const void *) upgrade_data_buf, data_read);
if (ota_write_err != ESP_OK) { // upgrade_data_buf contains nonsense html from redirected response
break;
} I'm not sure if it's possible to skip first response read. This doesn't works: while (1) {
int status = esp_http_client_get_status_code(client);
if (300 <= status && status < 599) {
continue;
}
int data_read = esp_http_client_read(client, upgrade_data_buf, alloc_size);
if (data_read == 0) {
ESP_LOGI(TAG, "Connection closed, all data received");
break;
} But here's my implementation with event instead of static bool ota_start(const char *url) {
bool ok = false;
esp_err_t err = ESP_OK;
esp_http_client_handle_t client = NULL;
do {
ESP_LOGI(TAG, "starting ota");
const esp_partition_t *update_partition = esp_ota_get_next_update_partition(NULL);
if (update_partition == NULL) {
ESP_LOGE(TAG, "passive ota partition not found");
break;
}
ESP_LOGI(TAG, "writing to partition subtype %d at offset 0x%x", update_partition->subtype, update_partition->address);
OTA_Context_t ctx;
ctx.ok = true;
ctx.handle = 0;
if (esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &ctx.handle) != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_begin failed: %s", esp_err_to_name(err));
break;
}
ESP_LOGI(TAG, "esp_ota_begin succeeded");
ESP_LOGI(TAG, "please wait...");
esp_http_client_config_t config = {
.event_handler = http_event_handle,
.url = url,
.timeout_ms = 6000,
.method = HTTP_METHOD_GET,
.cert_pem = certs(),
.max_redirection_count = 4,
.disable_auto_redirect = false,
.user_data = (void *)&ctx,
.buffer_size = 2048
};
ESP_LOGI(TAG, "request to %s", config.url);
client = esp_http_client_init(&config);
char ua[128] = { 0 };
sysinfo_useragent(ua, sizeof(ua));
esp_http_client_set_header(client, "User-Agent", ua);
err = esp_http_client_perform(client);
if (err == ESP_OK) {
int status = esp_http_client_get_status_code(client);
if (200 <= status && status < 300 && ctx.ok) {
err = esp_ota_end(ctx.handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_end failed: %s", esp_err_to_name(err));
break;
}
err = esp_ota_set_boot_partition(update_partition);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_set_boot_partition failed: %s", esp_err_to_name(err));
break;
}
ESP_LOGI(TAG, "esp_ota_set_boot_partition succeeded");
ok = true;
}
} else {
ESP_LOGE(TAG, "http get request failed: %s", esp_err_to_name(err));
break;
}
} while(false);
esp_http_client_cleanup(client);
return ok;
}
static esp_err_t http_event_handle(esp_http_client_event_t *evt) {
switch(evt->event_id) {
case HTTP_EVENT_ERROR:
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
break;
case HTTP_EVENT_ON_CONNECTED:
ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
break;
case HTTP_EVENT_HEADER_SENT:
ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
break;
case HTTP_EVENT_ON_HEADER:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER %s = %s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_DATA:
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
// Crucial part here! Don't read the response if it was redirect
int status = esp_http_client_get_status_code(evt->client);
if (300 <= status && status < 599) {
break;
}
OTA_Context_t *ctx = (OTA_Context_t *)evt->user_data;
esp_err_t ota_write_err = esp_ota_write(ctx->handle, evt->data, evt->data_len);
if (ota_write_err != ESP_OK) {
ESP_LOGE(TAG, "OTA write error: %s", esp_err_to_name(ota_write_err));
ctx->ok = false;
}
break;
case HTTP_EVENT_ON_FINISH:
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
break;
case HTTP_EVENT_DISCONNECTED:
ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
break;
}
return ESP_OK;
} |
@olegantonyan We have similar fix in our internal development queue, will try to prioritize and fix this soon. (CC @jitin17) |
@olegantonyan I am attaching a patch with support for URL redirection in |
@jitin17 there's either a problem with the patch, or I'm too young to know how to use them :)
Can you make a pull-request? |
It was a mistake from my side. |
Yep, this seems to work |
When do you expect to merge this fix to master? |
…ontrol with new APIs Bugfixes: - Fix http url redirection issue - Fix basic/digest auth issue with http url Features: - Add support for adding custom http header - Add support for reading firmware image header - Add support for monitoring upgrade status - This requires breaking down esp_https_ota API such that it allows finer application level control - For simpler use-cases previous API is still supported Closes espressif#3218 Closes espressif#2921
…ontrol with new APIs Bugfixes: - Fix http url redirection issue - Fix basic/digest auth issue with http url Features: - Add support for adding custom http header - Add support for reading firmware image header - Add support for monitoring upgrade status - This requires breaking down esp_https_ota API such that it allows finer application level control - For simpler use-cases previous API is still supported Closes #3218 Closes #2921
Hi I am facing the same issue. |
Hi if anyone is still unable to perform OTA from google drive then please have a look here. This patch works for me. Thanks, |
It looks like this patch from #8521 was included in v4.4 (#d485a8c), but I'm experiencing the same issue using IDF 5.2. Trying to download a binary attached to a github release redirects to objects.githubusercontent.com, which returns a 401. I'm able to successfully redirect and download in both my browser and POSTman. ESP logs: |
What happens if you increase the HTTP client buffer size (e.g., 2K)?
|
Thanks for the quick reply. Just tried with a buffer size of 2048, 4096, and 8192 and still no luck. Though now it specifically errors for exceeding the buffer size. |
I was able to get the download working for the URL that you shared by applying following change to
Redirection URL seems quite big and hence the change to buffer values. Please try once and see if this works. |
@mahavirj adding keep alive and the tx buffer resolved it. Thank you! |
If
url
gets redirected OTA fails:E (367424) esp_ota_ops: OTA image has invalid magic byte (expected 0xE9, saw 0x3c
0x3c
==<
ascii symbolI expect redirects to work here because they work in esp_http_client and I need them to work because this is the way files storage work on my server.
The text was updated successfully, but these errors were encountered: