5 Commits

Author SHA1 Message Date
Benoit Chesneau
51d350a212 Close transport after WebSocket close handshake completes 2026-04-03 16:34:18 +02:00
Benoit Chesneau
3fc9a2f002 Fix WebSocket close handshake to comply with RFC 6455
- Add _close_sent, _close_received, _close_event state variables
- Server now waits for client's close frame response before marking
  connection as closed (5s timeout)
- Update _read_frames loop to continue reading after sending close
- Fix tests to simulate client close frame response
2026-04-03 14:53:36 +02:00
Benoit Chesneau
241c479701 Fix WebSocket race condition in callback-based _read_exact()
Add double-check after clearing _data_event to prevent deadlock when
data arrives between clear() and wait(). The race condition occurred
when:
1. Task A checks buffer, needs more data
2. Task A clears _data_event
3. Task B (feed_data) sets event
4. Task A awaits on cleared event - deadlock

The fix re-checks the buffer after clear() to catch data that arrived
in the race window.

Also adds tests for edge cases: race condition simulation, EOF during
wait, fragmented message reassembly, and control frames during
fragmentation.
2026-03-23 13:08:57 +01:00
Benoit Chesneau
11c6a97c47 asgi: Fix pylint and pycodestyle warnings
- Remove unused imports (ssl, os, base64, hashlib, traceback)
- Remove unused variables (body_parts, has_content_length, etc.)
- Fix no-else-break patterns in protocol.py and websocket.py
- Replace __anext__() with anext() builtin
- Remove unnecessary pass statements
- Add proper access logging to ASGI protocol handler
- Add ASGIResponseInfo class and _build_environ method for logging
- Disable too-many-return-statements for _read_frame method
- Fix raising-bad-type error (use 'is not None' check)
- Fix whitespace before colon in message.py
2026-01-22 18:03:14 +01:00
Benoit Chesneau
ae1eea8108 asgi: Add native ASGI worker with HTTP and WebSocket support
Add a new ASGI worker type that provides native async support using
gunicorn's own HTTP parsing infrastructure adapted for asyncio.

Features:
- HTTP/1.1 with keepalive support
- WebSocket connections (RFC 6455)
- ASGI lifespan protocol for startup/shutdown hooks
- Optional uvloop support for improved performance
- Full proxy protocol support (inherited from gunicorn)

New configuration options:
- --asgi-loop: Event loop selection (auto/asyncio/uvloop)
- --asgi-lifespan: Lifespan protocol control (auto/on/off)
- --root-path: ASGI root path for reverse proxy setups

Usage: gunicorn -k asgi myapp:app
2026-01-22 17:05:29 +01:00