Skip to content

Found an edge case issue while working on a new uvicorn rust port #383

Open

Description

@appunni-m

Hypercorn’s HTTP/3 path was not propagating some QUIC disconnect events to the ASGI application.

When a client aborted an HTTP/3 request using RESET_STREAM, or when the whole QUIC connection terminated, Hypercorn could see that at the QUIC layer, but the corresponding ASGI app did not receive:

{"type": "http.disconnect"}

This means an application waiting on receive() could continue waiting even though the client was already gone.

Client
  |
  | RESET_STREAM / connection close
  v
aioquic
  |
  | QUIC event
  v
Hypercorn H3Protocol
  |
  X  event was not propagated to the request stream
  |
  v
ASGI application never receives http.disconnect

Reproduce:

async def app(scope, receive, send):
    while True:
        message = await receive()
        print(message)

Start Hypercorn with HTTP/3 enabled.
Open an HTTP/3 request.
Abort the request before it completes, causing a QUIC RESET_STREAM.
Observe the ASGI messages.

Specs

ASGI HTTP spec: closed HTTP connections are represented to the application using http.disconnect.
RFC 9114: HTTP/3 requests may be cancelled using QUIC stream mechanisms.
RFC 9000: QUIC defines RESET_STREAM and connection termination behavior.

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions