Minor adjustment for BOM strings
This commit is contained in:
@@ -42,6 +42,21 @@ void beginRequest(const char* operation) {
|
||||
KOReaderSyncClient::lastContigHeapAtFailure = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT | MALLOC_CAP_DEFAULT);
|
||||
}
|
||||
|
||||
// Skip a leading UTF-8 BOM (EF BB BF) and ASCII whitespace, returning a pointer
|
||||
// to the first content character. Used by response-body checks that verify the
|
||||
// payload starts with '{' (JSON) rather than '<' (HTML captive-portal page).
|
||||
const char* skipBomAndWhitespace(const char* p) {
|
||||
// UTF-8 BOM
|
||||
if (static_cast<unsigned char>(p[0]) == 0xEF && static_cast<unsigned char>(p[1]) == 0xBB &&
|
||||
static_cast<unsigned char>(p[2]) == 0xBF) {
|
||||
p += 3;
|
||||
}
|
||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
|
||||
p++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
// Device identifier for CrossPoint reader
|
||||
constexpr char DEVICE_NAME[] = "CrossPoint";
|
||||
constexpr char DEVICE_ID[] = "crosspoint-reader";
|
||||
@@ -377,19 +392,8 @@ KOReaderSyncClient::Error KOReaderSyncClient::authenticate() {
|
||||
if (err != ESP_OK) return NETWORK_ERROR;
|
||||
if (httpCode >= 300 && httpCode < 400) return REDIRECT_ERROR;
|
||||
if (httpCode == 200) {
|
||||
// The kosync auth response is always a JSON object. Guard against a reverse
|
||||
// proxy returning HTTP 200 + HTML (e.g. a login wall that followed all
|
||||
// redirects and landed on an auth page instead of the API endpoint).
|
||||
// Skip leading whitespace before checking for '{' so servers that emit
|
||||
// a BOM or indent their JSON don't get incorrectly rejected.
|
||||
if (!activeBuf->data) {
|
||||
return INVALID_RESPONSE;
|
||||
}
|
||||
const char* p = activeBuf->data;
|
||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
|
||||
p++;
|
||||
}
|
||||
if (*p != '{') {
|
||||
// Guard against a reverse proxy or captive portal returning HTTP 200 + HTML.
|
||||
if (!activeBuf->data || *skipBomAndWhitespace(activeBuf->data) != '{') {
|
||||
return INVALID_RESPONSE;
|
||||
}
|
||||
return OK;
|
||||
@@ -577,14 +581,10 @@ KOReaderSyncClient::Error KOReaderSyncClient::updateProgress(const KOReaderProgr
|
||||
if (err != ESP_OK) return NETWORK_ERROR;
|
||||
if (httpCode >= 300 && httpCode < 400) return REDIRECT_ERROR;
|
||||
if (httpCode == 200 || httpCode == 202) {
|
||||
// Guard against a reverse proxy or captive portal returning HTTP 200 + HTML
|
||||
// instead of the real API response, consistent with authenticate()'s check.
|
||||
// Guard against a reverse proxy or captive portal returning HTTP 200 + HTML.
|
||||
if (activeBuf->data) {
|
||||
const char* p = activeBuf->data;
|
||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
|
||||
p++;
|
||||
}
|
||||
if (*p != '\0' && *p != '{') {
|
||||
const char c = *skipBomAndWhitespace(activeBuf->data);
|
||||
if (c != '\0' && c != '{') {
|
||||
return INVALID_RESPONSE;
|
||||
}
|
||||
}
|
||||
@@ -609,13 +609,13 @@ const char* KOReaderSyncClient::lastFailureDetail() {
|
||||
}
|
||||
// Network/TLS case: esp_http_client_perform() failed before getting a status code.
|
||||
if (lastHttpCode == 0 && lastEspError != 0) {
|
||||
// Detect TLS handshake failures on HTTPS URLs — likely caused by the server
|
||||
// requiring TLS 1.3 which the ESP32 mbedTLS library does not support.
|
||||
// HTTPS connect failures can be TLS version issues (ESP32 only supports up
|
||||
// to TLS 1.2), but also DNS, cert, or plain network problems. Include the
|
||||
// error name and heap stats so the user/bug-report has enough to triage.
|
||||
if (lastEspError == ESP_ERR_HTTP_CONNECT && KOREADER_STORE.getBaseUrl().rfind("https", 0) == 0) {
|
||||
snprintf(
|
||||
g_failureDetailBuf, sizeof(g_failureDetailBuf),
|
||||
"%s: TLS handshake failed. Server may require TLS 1.3 (unsupported). Try a different server or use HTTP.",
|
||||
lastOperation);
|
||||
snprintf(g_failureDetailBuf, sizeof(g_failureDetailBuf),
|
||||
"%s: connect failed — check network, DNS, certs, or TLS 1.2 compat (heap %u/%u contig)", lastOperation,
|
||||
lastHeapAtFailure, lastContigHeapAtFailure);
|
||||
} else {
|
||||
snprintf(g_failureDetailBuf, sizeof(g_failureDetailBuf), "%s: %s (heap %u/%u contig)", lastOperation,
|
||||
esp_err_to_name(lastEspError), lastHeapAtFailure, lastContigHeapAtFailure);
|
||||
|
||||
Reference in New Issue
Block a user