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

Method send

gunicorn/asgi/protocol.py:951–1065  ·  view source on GitHub ↗
(message)

Source from the content-addressed store, hash-verified

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
988
989 # No-body responses (HEAD/1xx/204/304) must not carry a body.
990 # Always drop Transfer-Encoding (no chunked terminator without
991 # a body); Content-Length is dropped only for statuses that
992 # forbid it per RFC 9110 §6.4.2 (1xx, 204). HEAD and 304 keep
993 # an app-supplied Content-Length.
994 omits_body = self._response_omits_body(request.method, response_status)
995 if omits_body and (has_content_length or has_transfer_encoding):
996 response_headers = self._strip_body_framing_headers(
997 response_headers, response_status
998 )
999 if self._response_forbids_content_length(response_status):
1000 has_content_length = False
1001 has_transfer_encoding = False
1002 use_chunked = False
1003
1004 # Use chunked encoding for HTTP/1.1 streaming responses without Content-Length.
1005 # Skip when the response cannot carry a body or when Transfer-Encoding was
1006 # already set by the framework.
1007 needs_chunked = (
1008 not has_content_length

Callers 2

createFunction · 0.45
_sock_sendMethod · 0.45

Calls 15

_send_informationalMethod · 0.95
_response_omits_bodyMethod · 0.95
_send_response_startMethod · 0.95
_send_bodyMethod · 0.95
_safe_writeMethod · 0.95
_convert_h2_headersMethod · 0.95
getMethod · 0.45
warningMethod · 0.45
drainMethod · 0.45
send_informationalMethod · 0.45

Tested by

no test coverage detected