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

Method finish_body

gunicorn/http/parser.py:38–99  ·  view source on GitHub ↗

Discard any unread body of the current message. Called before returning a keepalive connection to the poller so the socket does not appear readable due to leftover body bytes. ``deadline`` is an absolute ``time.monotonic()`` value; when set the socket read timeout i

(self, deadline=None, max_bytes=None)

Source from the content-addressed store, hash-verified

36 return self
37
38 def finish_body(self, deadline=None, max_bytes=None):
39 """Discard any unread body of the current message.
40
41 Called before returning a keepalive connection to the poller so the
42 socket does not appear readable due to leftover body bytes.
43
44 ``deadline`` is an absolute ``time.monotonic()`` value; when set the
45 socket read timeout is bounded by the remaining time before each read.
46 ``max_bytes`` caps the total drained bytes; when a deadline is given
47 and ``max_bytes`` is left at the default, ``_DRAIN_MAX_BYTES`` applies
48 to defend against a slow client that keeps trickling under it. When
49 called without a deadline (the default invocation from ``__next__``),
50 no byte cap is applied so the prior unbounded drain semantics are
51 preserved for callers that don't know how to react to a partial drain.
52
53 Returns ``True`` when the body was fully drained, ``False`` when the
54 drain was abandoned (deadline, byte cap, or socket timeout). Callers
55 that observe ``False`` MUST close the connection rather than serve
56 another request on it.
57 """
58 if not self.mesg:
59 return True
60
61 if max_bytes is None and deadline is not None:
62 max_bytes = _DRAIN_MAX_BYTES
63
64 sock = getattr(self.unreader, "sock", None)
65 # gettimeout/settimeout only matter when bounding a real socket; a
66 # mock or non-socket source skips the timeout plumbing.
67 if sock is not None and hasattr(sock, "gettimeout") and hasattr(sock, "settimeout"):
68 timeoutable_sock = sock
69 prior_timeout = sock.gettimeout()
70 else:
71 timeoutable_sock = None
72 prior_timeout = None
73
74 drained = 0
75 try:
76 while True:
77 if deadline is not None and timeoutable_sock is not None:
78 remaining = deadline - time.monotonic()
79 if remaining <= 0:
80 return False
81 timeoutable_sock.settimeout(remaining)
82 try:
83 data = self.mesg.body.read(1024)
84 except (socket.timeout, TimeoutError):
85 return False
86 except ssl.SSLWantReadError:
87 # SSL socket has no more application data available
88 return True
89 if not data:
90 return True
91 drained += len(data)
92 if max_bytes is not None and drained >= max_bytes:
93 return False
94 finally:
95 if timeoutable_sock is not None:

Calls 2

settimeoutMethod · 0.45
readMethod · 0.45