Skip to content

Treat incomplete Responder close as failure #191

Description

@kentbull

Problem

Responder.close() currently conflates administrative connection teardown with successful WSGI response completion. If a response has started but not ended, close() calls write(b''); for a chunked response this enqueues the terminal zero chunk. It then unconditionally sets ended = True.

Server.closeConnection() invokes this method for remote cutoff, timeout, request parsing failure, server shutdown, and normal nonpersistent cleanup. Normal completion is already established earlier by Responder.service() through iterator exhaustion or exact Content-Length emission. Therefore, reaching close() with ended = False means completion was never observed.

Impact

  • A partially produced chunked response can receive 0\r\n\r\n, making a truncated representation look complete to the client.
  • A partial fixed-length or not-yet-started response is still recorded internally as successful.
  • Later connection lifecycle logic cannot distinguish producer success from forced teardown.

Cleanup may follow completion, but cleanup cannot prove completion.

Expected behavior

  • Closing an already-ended responder should preserve success and only mark it closed.
  • Closing an incomplete responder should record a retained failure, mark it closed, leave ended = False, and enqueue no completion framing.
  • Repeated abort/close should preserve the first cause and byte boundary.
  • A failed responder generation must not be reset for persistent reuse.

Regression coverage

Exercise a real Responder over a real Remoter transmit queue before response start and after partial body output. Verify incomplete close records failure without appending a terminal chunk, first-cause retention is idempotent, failed reset is rejected, and normal iterator exhaustion still emits exactly one terminal chunk.

Scope and dependency

This issue is generic WSGI/HTTP settlement behavior and does not require the GLEIF transport changes. The code port should wait for #179 and #181 because it depends on their Content-Length producer settlement and responder-reset behavior. Returned-iterable cleanup and application/iterator exception handling are separate follow-up concerns.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions