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

Method _handle_http_request

gunicorn/asgi/protocol.py:930–1123  ·  view source on GitHub ↗

Handle a single HTTP request.

(self, request, sockname, peername)

Source from the content-addressed store, hash-verified

928 await ws_protocol.run()
929
930 async def _handle_http_request(self, request, sockname, peername):
931 """Handle a single HTTP request."""
932 scope = self._build_http_scope(request, sockname, peername)
933 response_started = False
934 response_complete = False
935 exc_to_raise = None
936 use_chunked = False
937 omits_body = False
938 omits_body_warned = False
939
940 # Reset response buffer for write batching
941 self._response_buffer = None
942
943 # Response tracking for access logging
944 response_status = 500
945 response_headers = []
946 response_sent = 0
947
948 # Use body receiver created in _on_headers_complete (receives data via callbacks)
949 body_receiver = self._body_receiver
950
951 async def send(message):
952 nonlocal response_started, response_complete, exc_to_raise
953 nonlocal response_status, response_headers, response_sent, use_chunked, omits_body
954 nonlocal omits_body_warned
955
956 # If client disconnected, silently ignore send attempts
957 # This allows apps to finish cleanup without errors
958 if self._closed:
959 return
960
961 msg_type = message["type"]
962
963 if msg_type == "http.response.informational":
964 # Handle informational responses (1xx) like 103 Early Hints
965 info_status = message.get("status")
966 info_headers = message.get("headers", [])
967 self._send_informational(info_status, info_headers, request)
968 return
969
970 if msg_type == "http.response.start":
971 if response_started:
972 exc_to_raise = RuntimeError("Response already started")
973 return
974 response_started = True
975 response_status = message["status"]
976 response_headers = message.get("headers", [])
977
978 # Check if Content-Length or Transfer-Encoding is present
979 has_content_length = False
980 has_transfer_encoding = False
981 for name, _ in response_headers:
982 name_lower = name.lower() if isinstance(name, str) else name.lower()
983 if name_lower in (b"content-length", "content-length"):
984 has_content_length = True
985 elif name_lower in (b"transfer-encoding", "transfer-encoding"):
986 has_transfer_encoding = True
987 use_chunked = True # Framework already set chunked encoding

Calls 12

_build_http_scopeMethod · 0.95
_send_error_responseMethod · 0.95
_build_environMethod · 0.95
_RequestTimeClass · 0.85
ASGIResponseInfoClass · 0.85
pre_requestMethod · 0.80
appMethod · 0.45
debugMethod · 0.45
exceptionMethod · 0.45
accessMethod · 0.45
post_requestMethod · 0.45
should_closeMethod · 0.45