md5 fixes

This commit is contained in:
J. Nick Koston 2025-07-01 11:09:08 -05:00
parent 149bdaf146
commit cd1390916c
No known key found for this signature in database
10 changed files with 52 additions and 10 deletions

View File

@ -34,7 +34,10 @@ OTAResponseTypes ArduinoESP32OTABackend::begin(size_t image_size) {
return OTA_RESPONSE_ERROR_UNKNOWN;
}
void ArduinoESP32OTABackend::set_update_md5(const char *md5) { Update.setMD5(md5); }
void ArduinoESP32OTABackend::set_update_md5(const char *md5) {
Update.setMD5(md5);
this->md5_set_ = true;
}
OTAResponseTypes ArduinoESP32OTABackend::write(uint8_t *data, size_t len) {
size_t written = Update.write(data, len);
@ -49,7 +52,9 @@ OTAResponseTypes ArduinoESP32OTABackend::write(uint8_t *data, size_t len) {
}
OTAResponseTypes ArduinoESP32OTABackend::end() {
if (Update.end()) {
// Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
// This matches the behavior of the old web_server OTA implementation
if (Update.end(!this->md5_set_)) {
return OTA_RESPONSE_OK;
}

View File

@ -16,6 +16,9 @@ class ArduinoESP32OTABackend : public OTABackend {
OTAResponseTypes end() override;
void abort() override;
bool supports_compression() override { return false; }
private:
bool md5_set_{false};
};
} // namespace ota_base

View File

@ -43,7 +43,10 @@ OTAResponseTypes ArduinoESP8266OTABackend::begin(size_t image_size) {
return OTA_RESPONSE_ERROR_UNKNOWN;
}
void ArduinoESP8266OTABackend::set_update_md5(const char *md5) { Update.setMD5(md5); }
void ArduinoESP8266OTABackend::set_update_md5(const char *md5) {
Update.setMD5(md5);
this->md5_set_ = true;
}
OTAResponseTypes ArduinoESP8266OTABackend::write(uint8_t *data, size_t len) {
size_t written = Update.write(data, len);
@ -58,7 +61,9 @@ OTAResponseTypes ArduinoESP8266OTABackend::write(uint8_t *data, size_t len) {
}
OTAResponseTypes ArduinoESP8266OTABackend::end() {
if (Update.end()) {
// Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
// This matches the behavior of the old web_server OTA implementation
if (Update.end(!this->md5_set_)) {
return OTA_RESPONSE_OK;
}

View File

@ -21,6 +21,9 @@ class ArduinoESP8266OTABackend : public OTABackend {
#else
bool supports_compression() override { return false; }
#endif
private:
bool md5_set_{false};
};
} // namespace ota_base

View File

@ -34,7 +34,10 @@ OTAResponseTypes ArduinoLibreTinyOTABackend::begin(size_t image_size) {
return OTA_RESPONSE_ERROR_UNKNOWN;
}
void ArduinoLibreTinyOTABackend::set_update_md5(const char *md5) { Update.setMD5(md5); }
void ArduinoLibreTinyOTABackend::set_update_md5(const char *md5) {
Update.setMD5(md5);
this->md5_set_ = true;
}
OTAResponseTypes ArduinoLibreTinyOTABackend::write(uint8_t *data, size_t len) {
size_t written = Update.write(data, len);
@ -49,7 +52,9 @@ OTAResponseTypes ArduinoLibreTinyOTABackend::write(uint8_t *data, size_t len) {
}
OTAResponseTypes ArduinoLibreTinyOTABackend::end() {
if (Update.end()) {
// Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
// This matches the behavior of the old web_server OTA implementation
if (Update.end(!this->md5_set_)) {
return OTA_RESPONSE_OK;
}

View File

@ -15,6 +15,9 @@ class ArduinoLibreTinyOTABackend : public OTABackend {
OTAResponseTypes end() override;
void abort() override;
bool supports_compression() override { return false; }
private:
bool md5_set_{false};
};
} // namespace ota_base

View File

@ -43,7 +43,10 @@ OTAResponseTypes ArduinoRP2040OTABackend::begin(size_t image_size) {
return OTA_RESPONSE_ERROR_UNKNOWN;
}
void ArduinoRP2040OTABackend::set_update_md5(const char *md5) { Update.setMD5(md5); }
void ArduinoRP2040OTABackend::set_update_md5(const char *md5) {
Update.setMD5(md5);
this->md5_set_ = true;
}
OTAResponseTypes ArduinoRP2040OTABackend::write(uint8_t *data, size_t len) {
size_t written = Update.write(data, len);
@ -58,7 +61,9 @@ OTAResponseTypes ArduinoRP2040OTABackend::write(uint8_t *data, size_t len) {
}
OTAResponseTypes ArduinoRP2040OTABackend::end() {
if (Update.end()) {
// Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
// This matches the behavior of the old web_server OTA implementation
if (Update.end(!this->md5_set_)) {
return OTA_RESPONSE_OK;
}

View File

@ -17,6 +17,9 @@ class ArduinoRP2040OTABackend : public OTABackend {
OTAResponseTypes end() override;
void abort() override;
bool supports_compression() override { return false; }
private:
bool md5_set_{false};
};
} // namespace ota_base

View File

@ -67,6 +67,7 @@ void OTARequestHandler::schedule_ota_reboot_() {
void OTARequestHandler::ota_init_(const char *filename) {
ESP_LOGI(TAG, "OTA Update Start: %s", filename);
this->ota_read_length_ = 0;
this->ota_success_ = false;
}
void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index,
@ -140,8 +141,15 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Strin
// Finalize
if (final) {
ESP_LOGD(TAG, "OTA final chunk: index=%u, len=%u, total_read=%u, contentLength=%u", index, len,
this->ota_read_length_, request->contentLength());
// For Arduino framework, the Update library tracks expected size from firmware header
// If we haven't received enough data, calling end() will fail
// This can happen if the upload is interrupted or the client disconnects
error_code = this->ota_backend_->end();
if (error_code == ota_base::OTA_RESPONSE_OK) {
this->ota_success_ = true;
#ifdef USE_OTA_STATE_CALLBACK
// Report completion before reboot - use call_deferred since we're in web server task
this->parent_->state_callback_.call_deferred(ota_base::OTA_COMPLETED, 100.0f, 0);
@ -159,8 +167,9 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Strin
void OTARequestHandler::handleRequest(AsyncWebServerRequest *request) {
AsyncWebServerResponse *response;
// Send response based on whether backend still exists (error) or was reset (success)
response = request->beginResponse(200, "text/plain", !this->ota_backend_ ? "Update Successful!" : "Update Failed!");
// Use the ota_success_ flag to determine the actual result
const char *msg = this->ota_success_ ? "Update Successful!" : "Update Failed!";
response = request->beginResponse(200, "text/plain", msg);
response->addHeader("Connection", "close");
request->send(response);
}

View File

@ -159,6 +159,7 @@ class OTARequestHandler : public AsyncWebHandler {
uint32_t last_ota_progress_{0};
uint32_t ota_read_length_{0};
WebServerBase *parent_;
bool ota_success_{false};
private:
std::unique_ptr<ota_base::OTABackend> ota_backend_{nullptr};