http: do not process requests after a closing reply #36652

pull fametrano wants to merge 2 commits into bitcoin:master from fametrano:http-close-cl-te changing 4 files +108 −3
  1. fametrano commented at 8:34 PM on October 24, 2026: none

    The HTTP server runs requests that are already in its receive buffer after it has queued a reply that closes the connection. RFC 9112 section 9.6 says it must not. This is a regression from #35182, which replaced libevent: libevent's evhttp_send_done() frees the connection once a closing reply is sent, so buffered requests were never parsed. The server also keeps the connection open after a request with both Content-Length and Transfer-Encoding. Section 6.1 says it must close it. Until both are fixed, a request sent right behind a request with both headers is run.

    The first commit stops reading requests from a client once a closing reply is queued or the client is flagged for disconnection. Its code and unit tests are azuchi's work from #36355, which was closed. The second commit makes WriteReply() send "Connection: close" for a request with both headers, so the server closes the connection. It extends the Content-Length plus Transfer-Encoding case in interface_http.py: a setnetworkactive false request sent right behind it must not run, and the only reply must say "Connection: close". Tested with test_bitcoin --run_test=httpserver_tests and the functional tests interface_http.py, interface_rpc.py and interface_rest.py, which pass.

  2. http: stop reading after a closing reply
    After a reply that closes the connection is queued, the server still
    parses requests already in its receive buffer. It runs them. If the
    closing reply is still being sent, a keep-alive request behind it also
    keeps the connection open. RFC 9112 section 9.6 says a server that sends
    a close must not process further requests on that connection.
    
    `Send()` now sets `m_closing` when the reply is not keep-alive.
    `TryReadRequest()` returns nothing for a client with `m_closing` or
    `m_disconnect` set. From #36355. Two new unit tests cover a closing
    reply that is flushed at once and one that stays queued. The existing
    two-request unit test now asks for keep-alive.
    8b1a97923d
  3. http: close connection on conflicting framing
    The HTTP server keeps the connection open after it answers a request
    with both Content-Length and Transfer-Encoding. RFC 9112 section 6.1
    says the server must close the connection after responding to such a
    request.
    
    `HTTPRequest::WriteReply()` now sends "Connection: close" in that case,
    as it does when the client asks for it. The server then closes the
    connection. The request itself is processed as before. The
    Content-Length plus Transfer-Encoding case in `interface_http.py` now
    sends a `setnetworkactive false` request right behind it. The test
    checks that a single reply comes back, with "Connection: close", and
    that the network stays active.
    cdd831035d
  4. DrahtBot added the label RPC/REST/ZMQ on Oct 24, 2026
  5. DrahtBot commented at 8:34 PM on October 24, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--006a51241073e994b41acfe9ec718e94-->

    External sites

    <!--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:

    • #36259 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36259.svg"></sub> (http: update m_keep_alive under m_send_mutex by azuchi)

    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. pinheadmz commented at 12:01 AM on October 25, 2026: member

    We closed #36355 because it doesn't appear to pose any security risk, nor does the existing code interfere with any legitimate use case of the HTTP server. Our HTTP doesn't need to be Apache or nginx -- are you certain this submission is worth reviewer time?


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-10-30 15:51 UTC

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