MCPcopy
hub / github.com/benoitc/gunicorn / _handle_http2_request

Method _handle_http2_request

gunicorn/asgi/protocol.py:1548–1730  ·  view source on GitHub ↗

Handle a single HTTP/2 request with streaming support. Streams both request and response body chunks immediately, avoiding buffering entire uploads and enabling SSE, streaming downloads, and other real-time use cases.

(self, request, h2_conn, sockname, peername)

Source from the content-addressed store, hash-verified

1546 return result
1547
1548 async def _handle_http2_request(self, request, h2_conn, sockname, peername):
1549 """Handle a single HTTP/2 request with streaming support.
1550
1551 Streams both request and response body chunks immediately,
1552 avoiding buffering entire uploads and enabling SSE, streaming
1553 downloads, and other real-time use cases.
1554 """
1555 stream_id = request.stream.stream_id
1556 stream = h2_conn.streams.get(stream_id)
1557 scope = self._build_http2_scope(request, sockname, peername)
1558
1559 response_started = False
1560 response_complete = False
1561 headers_sent = False
1562 exc_to_raise = None
1563 response_status = 500
1564 response_headers = []
1565 response_sent = 0
1566
1567 # Track if we've finished receiving body
1568 body_received = False
1569
1570 async def receive():
1571 nonlocal body_received
1572
1573 # Check if stream is closed or missing
1574 if stream is None or stream.state.name == "CLOSED":
1575 return {"type": "http.disconnect"}
1576
1577 # First call: if body already complete (small requests), return it
1578 if not body_received and stream.request_complete and not stream._body_chunks:
1579 body_received = True
1580 body = stream.get_request_body()
1581 return {
1582 "type": "http.request",
1583 "body": body,
1584 "more_body": False,
1585 }
1586
1587 # Streaming: read next chunk
1588 try:
1589 chunk = await asyncio.wait_for(
1590 stream.read_body_chunk(),
1591 timeout=30.0
1592 )
1593 except asyncio.TimeoutError:
1594 return {"type": "http.disconnect"}
1595
1596 if chunk is None:
1597 body_received = True
1598 return {
1599 "type": "http.request",
1600 "body": b"",
1601 "more_body": False,
1602 }
1603
1604 if stream._body_complete:
1605 body_received = True

Callers 1

Calls 14

_build_http2_scopeMethod · 0.95
_convert_h2_headersMethod · 0.95
_build_http2_environMethod · 0.95
_RequestTimeClass · 0.85
ASGIResponseInfoClass · 0.85
pre_requestMethod · 0.80
getMethod · 0.45
appMethod · 0.45
send_errorMethod · 0.45
send_headersMethod · 0.45
_send_pending_dataMethod · 0.45
exceptionMethod · 0.45

Tested by

no test coverage detected