[WIP] http: linger-close after parse errors so clients can read the reply #35780

pull b-l-u-e wants to merge 2 commits into bitcoin:master from b-l-u-e:http-lingering-close changing 8 files +136 −21
  1. b-l-u-e commented at 9:52 PM on July 22, 2026: contributor

    Based on this issue #35632 raised i believe the issue is not with whitespace header validation since the logic works fine coz the server detects the malformed request and queues a 400 reply as expected.

    The problem is how the server closes the connection afterwards. It queues the reply and closes the socket right away sometimes before it has finished reading everything the client had sent. So when socket is closed while there's still unread data sitting in the kernel's receive buffer, Windows responds with a TCP RST. That reset just throws away the reply that was already on its way out, so the client never gets to read the 400 and instead sees the connection aborted.

    So my LLM Buddie and I realized that we should change how the server closes a connection after a parse/size error so the client always gets a chance to read the response first by queuing the 400/413 response with Connection: close. Then, waits until the response has actually left the send buffer. Then, Half-close only the write side (shutdown(SHUT_WR/SD_SEND)) so the client can still finish reading while the server stops sending. Afterwards, Keep draining whatever the client is still sending until it hits EOF or a socket error and only force the connection closed after a 1s fallback timeout, for a client that never finishes.

  2. util: add Sock::ShutdownSend() to half-close the send side
    Wrap shutdown(2) (SHUT_WR, or SD_SEND on Windows) behind the Sock interface so it can be overridden by the mock sockets used in the unit and fuzz tests.
    010f606e11
  3. http: linger-close after parse errors so clients can read the reply
    When the HTTP server rejects a request during parsing a malformed header or an oversized body, it replied and then immediately closed the connection. On Windows, closing a socket that still has unread inbound data can trigger a TCP RST, which discards the queued reply before the client reads it, so the client sees a connection reset instead of the 400/413 response (see #35632).
    Instead of closing abruptly, flush the error reply, half-close the send side, and drain any remaining inbound data until the peer sends EOF. A 1s LINGERING_CLOSE_TIMEOUT bounds clients that never close their side.
    2e991f89e5
  4. DrahtBot added the label RPC/REST/ZMQ on Jul 22, 2026
  5. DrahtBot commented at 9:52 PM on July 22, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/35780.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process. A summary of reviews will appear here.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #35735 (Add state to HTTPRequest by pinheadmz)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  6. b-l-u-e marked this as a draft on Jul 23, 2026
  7. b-l-u-e renamed this:
    http: linger-close after parse errors so clients can read the reply
    [WIP] http: linger-close after parse errors so clients can read the reply
    on Jul 23, 2026

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-07-25 06:50 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me