Files
Crosspoint/src/network/HttpDownloader.h
T
Jeremy Klein 19954aa1b5 refactor: route OTA version check through HttpDownloader (#2076)
With both OtaUpdater and HttpDownloader on esp_http_client
(https://github.com/crosspoint-reader/crosspoint-reader/pull/2074,
https://github.com/crosspoint-reader/crosspoint-reader/pull/2075),
checkForUpdate no longer needs its own client and event handler to fetch
the release JSON. It streams the response straight into
ReleaseJsonParser through a new HttpDownloader::fetchUrl(url,
DataCallback) overload, dropping the duplicate esp_http_client setup,
the HTTP_EVENT_ON_DATA handler, and the totalBytesReceived file global.

DataCallback hands body chunks to a callback without buffering. The
naive alternative, collecting the ~32KB JSON into a std::string, aborts
under -fno-exceptions: the growing allocation collides with the TLS
session's heap mid-fetch and operator new calls abort().

The OTA install path stays on esp_https_ota (flash-write streaming),
which has no HttpDownloader equivalent.

HttpDownloader.h must precede the lwip (esp_http_client) headers in
OtaUpdater.cpp, or Arduino/SdFat macros collide with lwip.


Did you use AI tools to help write this code? partial
2026-05-24 21:44:30 -04:00

48 lines
1.7 KiB
C++

#pragma once
#include <HalStorage.h>
#include <functional>
#include <string>
/**
* HTTP client utility for fetching content and downloading files. Built on
* esp_http_client: https is verified against the CA bundle, plain http is
* used for local servers (transport is chosen from the URL scheme).
*/
class HttpDownloader {
public:
using ProgressCallback = std::function<void(size_t downloaded, size_t total)>;
// Called with each body chunk as it arrives; return false to abort. Lets a
// streaming parser consume the response without buffering the whole body.
using DataCallback = std::function<bool(const uint8_t* data, size_t len)>;
enum DownloadError {
OK = 0,
HTTP_ERROR,
FILE_ERROR,
ABORTED,
};
/**
* Fetch text content from a URL with optional credentials.
*/
static bool fetchUrl(const std::string& url, std::string& outContent, const std::string& username = "",
const std::string& password = "");
static bool fetchUrl(const std::string& url, Stream& stream, const std::string& username = "",
const std::string& password = "");
/**
* Stream the response body to onData as it arrives, without buffering it.
*/
static bool fetchUrl(const std::string& url, const DataCallback& onData, const std::string& username = "",
const std::string& password = "");
/**
* Download a file to the SD card with optional credentials.
*/
static DownloadError downloadToFile(const std::string& url, const std::string& destPath,
ProgressCallback progress = nullptr, bool* cancelFlag = nullptr,
const std::string& username = "", const std::string& password = "");
};