Fix web radio reconnect busy-loop on non-2xx HTTP status
openStream() only established the TCP/TLS connection; it never checked the HTTP status code. A 4xx/5xx response (wrong stream path, station temporarily down, etc.) still returned a valid client handle, so streamWhileEnabled() entered its pump loop, immediately read 0 bytes (no body), and returned -- skipping the kReconnectDelay branch entirely, which only fired when openStream() itself returned nullptr. run()'s outer loop then retried immediately: a full TCP+TLS handshake in a tight loop bounded only by network RTT, not the intended 5s backoff -- observed live at roughly 2 attempts/second. This mattered beyond wasted reconnects: a concurrent full FM band scan (POST /api/tuner/scan/full, which legitimately takes 70-135s) lost its HTTP connection outright while this loop was running, before this fix. After adding the status-code check and routing non-2xx through the same reconnect delay as a failed connection, the same scan completed cleanly twice in a row under the same conditions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -190,6 +190,25 @@ void streamWhileEnabled(webradio::WebRadioService& service,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// esp_http_client_open() only establishes the TCP/TLS connection; a 4xx/
|
||||||
|
// 5xx HTTP response (wrong path, station offline, etc.) still returns a
|
||||||
|
// valid client handle here. Without this check, such a response reads
|
||||||
|
// as an empty body -> pumpOneFrame() returns false on its first call ->
|
||||||
|
// the reconnect delay below is skipped entirely, and run()'s outer loop
|
||||||
|
// immediately retries: a full TCP+TLS handshake in a tight loop, bounded
|
||||||
|
// only by network RTT, not kReconnectDelay. Observed live 2026-08-26 at
|
||||||
|
// roughly 2 attempts/second against a misconfigured URL, competing for
|
||||||
|
// CPU/heap with an unrelated concurrent FM scan on the same board.
|
||||||
|
const int status = esp_http_client_get_status_code(client);
|
||||||
|
if (status < 200 || status >= 300) {
|
||||||
|
ESP_LOGW(kTag, "stream %s returned HTTP %d, not audio -- backing off",
|
||||||
|
url.c_str(), status);
|
||||||
|
esp_http_client_close(client);
|
||||||
|
esp_http_client_cleanup(client);
|
||||||
|
vTaskDelay(kReconnectDelay);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
InputBuffer in;
|
InputBuffer in;
|
||||||
bool loggedFormat = false;
|
bool loggedFormat = false;
|
||||||
while (service.config().enabled
|
while (service.config().enabled
|
||||||
|
|||||||
Reference in New Issue
Block a user