Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@
- Changing global font or page layout settings from the pull-down panel on touch devices now updates the open book when it inherits those settings.
- KOReader authentication now rejects unexpectedly large server responses to avoid crashes.

### Security

- Download logs show a URL without its query string, so signed download tokens (such as `?token=` on a redirected OPDS book download) no longer end up in serial or saved logs.

## [v1.6.0] - 2026-09-21

### Added
Expand Down
10 changes: 7 additions & 3 deletions src/network/HttpDownloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <esp_http_client.h>
#include <strings.h>

#include <algorithm>
#include <cstdio>
#include <functional>
#include <string>
Expand All @@ -32,6 +33,9 @@ constexpr uint32_t DOWNLOAD_IDLE_TIMEOUT_MS = 30000;
constexpr size_t DEFAULT_DOWNLOAD_BUFFER_SIZE = 2048;
constexpr uint8_t MAX_REDIRECTS = 5;

// Length to log with %.*s: the query string can hold a signed download token.
int pathOnly(const std::string& url) { return static_cast<int>(std::min(url.find('?'), url.size())); }

void logNetworkState(const char* phase) {
LOG_DBG("HTTP", "%s: heap free=%u maxAlloc=%u wifi=%d rssi=%d", phase, ESP.getFreeHeap(), ESP.getMaxAllocHeap(),
static_cast<int>(WiFi.status()), WiFi.status() == WL_CONNECTED ? WiFi.RSSI() : 0);
Expand Down Expand Up @@ -154,7 +158,7 @@ HttpDownloader::DownloadError runGetWolfSsl(const std::string& url, const std::s
// existing KOSync transport; cross-origin hops omit Basic credentials.
http.setInsecure();
if (!http.begin(currentUrl)) {
LOG_ERR("HTTP", "wolfSSL rejected URL: %s", currentUrl.c_str());
LOG_ERR("HTTP", "wolfSSL rejected URL: %.*s", pathOnly(currentUrl), currentUrl.c_str());
return HttpDownloader::HTTP_ERROR;
}
// Replace SecureHttpClient's built-in User-Agent so strict servers receive
Expand All @@ -172,7 +176,7 @@ HttpDownloader::DownloadError runGetWolfSsl(const std::string& url, const std::s
http.addHeader("Authorization", std::string("Basic ") + encoded.c_str());
}

LOG_DBG("HTTP", "wolfSSL GET: %s", currentUrl.c_str());
LOG_DBG("HTTP", "wolfSSL GET: %.*s", pathOnly(currentUrl), currentUrl.c_str());
const int status = http.GET(
[&http, &sink, &progressNotifier](const uint8_t* data, const size_t len) {
const int responseStatus = http.getStatus();
Expand Down Expand Up @@ -202,7 +206,7 @@ HttpDownloader::DownloadError runGetWolfSsl(const std::string& url, const std::s
return HttpDownloader::HTTP_ERROR;
}
if (status < 0) {
LOG_ERR("HTTP", "wolfSSL request failed: %s", currentUrl.c_str());
LOG_ERR("HTTP", "wolfSSL request failed: %.*s", pathOnly(currentUrl), currentUrl.c_str());
logNetworkState("wolfSSL request failure");
return HttpDownloader::HTTP_ERROR;
}
Expand Down
Loading