DAVx5 (CalDAV/CardDAV) on greg's phone was intermittently failing every
sync type (CONTACTS/EVENTS/TASKS/RefreshCollectionsWorker) against
next.thehellings.com with:
java.io.IOException: unexpected end of stream
Caused by: java.io.EOFException: \n not found: limit=0
This is the classic OkHttp/HTTP client signature of the far end
silently closing a pooled keep-alive connection: the client reuses a
socket it still believes is open, gets zero bytes back while reading
response headers, and throws exactly this exception.
Root cause: HAProxy's 'next' backend proxies to nginx on
127.0.0.1:8080, and HAProxy defaults to end-to-end keep-alive (both
client- and server-side) unless told otherwise. nginx's
keepalive_timeout is 65s, so any HAProxy<->nginx connection idle past
that gets closed by nginx without HAProxy's knowledge. A request that
lands on that now-dead pooled connection right after gets nothing back
- surfacing to the client as a bare socket EOF while reading headers.
The frontend's existing 'option http-server-close'/'http-keep-alive'
pair only governs the client-facing side of HAProxy and does nothing
for the HAProxy->nginx leg.
Fix:
- backend next: add 'option http-server-close' so HAProxy opens a
fresh connection to nginx per request instead of pooling/reusing
one. The backend is localhost, so the extra TCP handshake cost is
negligible, and this removes the whole class of stale-connection EOF
errors.
- defaults: add 'timeout http-keep-alive 30s' to bound how long an
idle client-facing keep-alive connection is held open. Previously
unset, it fell back to 'timeout client' (500s) - unnecessarily long
given maxconn is only 80, and tightens client-side connection churn
to be more predictable too.
Diagnosed by pulling the nginx_access journal (enabled in #37/#38) for
the failing sync window and cross-referencing nginx's
services.nginx.appendHttpConfig / generated nginx.conf keepalive
settings against HAProxy's request-level defaults. Could not run
'haproxy -c'/'nginx -t' locally (no toolchain in the agent sandbox) -
recommend confirming via CI/garnix before merge, same as #38.