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)
| 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: |