Skip to content

HTTP SSE read deadline cannot fire while the stream is byte-silent #18

Description

@senor14

Found during an adversarial review of 0.6.0 while preparing a downstream conformance test.

HttpMcpTestClient.readSseUntilResponse checks its deadline only after BufferedReader.readLine() returns:

while ((line = reader.readLine()) != null) {
    if (System.nanoTime() > deadline) {
        break;
    }
    ...
}

Two consequences:

  1. A byte-silent stream blocks forever. If a server holds the POST SSE stream open and sends no bytes at all (no keep-alives — e.g. a keep-alive interval of 0, or a server that just stalls), readLine() never returns and the deadline is unreachable. The method's own Javadoc claims the deadline means a server that never responds "fails the test with a message instead of hanging the build" — that only holds when the server keeps sending something. The request-level HttpRequest.timeout() doesn't help; it covers response headers only.
  2. A response arriving just past the deadline is discarded, not returned. The break happens before the just-read line is parsed, so a response landing at deadline+ε turns into the IllegalStateException instead of a (late) success.

The 0.6.0 fix is still correct for the case it targeted (keep-alive streams, where lines keep arriving and the deadline fires within one keep-alive period) — this is the remaining gap.

Proposed fix for 0.7.0: enforce the deadline independently of line arrival — a watchdog that closes the stream at the deadline so readLine() unblocks with an exception (then translated into the timeout message), or a timed read via the async subscriber API. Regression test: a server mode that goes byte-silent after the handshake.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions