@brief HTTP handler for POST requests to /update (firmware upload) @param req HTTP request handle @return ESP_OK on success
| 472 | /// @param req HTTP request handle |
| 473 | /// @return ESP_OK on success |
| 474 | esp_err_t otaHttpPostHandler(httpd_req_t *req) { |
| 475 | // Get HTTP context from user context |
| 476 | OTAHttpContext* ctx = (OTAHttpContext*)req->user_ctx; |
| 477 | |
| 478 | // SECURITY: Require authentication for firmware upload |
| 479 | if (!checkBasicAuth(req, ctx->password)) { |
| 480 | return ESP_FAIL; // Response already sent by checkBasicAuth |
| 481 | } |
| 482 | |
| 483 | esp_ota_handle_t ota_handle = 0; |
| 484 | const esp_partition_t* update_partition = nullptr; |
| 485 | bool ota_started = false; |
| 486 | size_t total_received = 0; |
| 487 | |
| 488 | // Get expected content length for progress tracking |
| 489 | size_t content_length = req->content_len; |
| 490 | |
| 491 | // Get OTA partition |
| 492 | update_partition = esp_ota_get_next_update_partition(nullptr); |
| 493 | if (!update_partition) { |
| 494 | if (ctx->error_cb && *ctx->error_cb) { |
| 495 | (*ctx->error_cb)("No OTA partition found"); |
| 496 | } |
| 497 | httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "No OTA partition found"); |
| 498 | return ESP_FAIL; |
| 499 | } |
| 500 | |
| 501 | // Receive data in chunks |
| 502 | char buffer[1024]; |
| 503 | int received; |
| 504 | bool first_chunk = true; |
| 505 | esp_err_t err; |
| 506 | |
| 507 | while ((received = httpd_req_recv(req, buffer, sizeof(buffer))) > 0) { |
| 508 | // Validate firmware header on first chunk |
| 509 | if (first_chunk) { |
| 510 | if (!validateESP32Firmware((const u8*)buffer, received)) { |
| 511 | if (ctx->error_cb && *ctx->error_cb) { |
| 512 | (*ctx->error_cb)("Invalid ESP32 firmware image"); |
| 513 | } |
| 514 | httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid ESP32 firmware image"); |
| 515 | return ESP_FAIL; |
| 516 | } |
| 517 | |
| 518 | // Begin OTA after validation passes |
| 519 | err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &ota_handle); |
| 520 | if (err != ESP_OK) { |
| 521 | if (ctx->error_cb && *ctx->error_cb) { |
| 522 | (*ctx->error_cb)("OTA begin failed"); |
| 523 | } |
| 524 | httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "OTA begin failed"); |
| 525 | return ESP_FAIL; |
| 526 | } |
| 527 | ota_started = true; |
| 528 | first_chunk = false; |
| 529 | } |
| 530 | |
| 531 | // Write to flash |
nothing calls this directly
no test coverage detected