MCPcopy
hub / github.com/encode/starlette / wrapped_receive

Method wrapped_receive

starlette/middleware/base.py:34–93  ·  view source on GitHub ↗
(self)

Source from the content-addressed store, hash-verified

32 self._wrapped_rc_stream = self.stream()
33
34 async def wrapped_receive(self) -> Message:
35 # wrapped_rcv state 1: disconnected
36 if self._wrapped_rcv_disconnected:
37 # we've already sent a disconnect to the downstream app
38 # we don't need to wait to get another one
39 # (although most ASGI servers will just keep sending it)
40 return {"type": "http.disconnect"}
41 # wrapped_rcv state 1: consumed but not yet disconnected
42 if self._wrapped_rcv_consumed:
43 # since the downstream app has consumed us all that is left
44 # is to send it a disconnect
45 if self._is_disconnected:
46 # the middleware has already seen the disconnect
47 # since we know the client is disconnected no need to wait
48 # for the message
49 self._wrapped_rcv_disconnected = True
50 return {"type": "http.disconnect"}
51 # we don't know yet if the client is disconnected or not
52 # so we'll wait until we get that message
53 msg = await self.receive()
54 if msg["type"] != "http.disconnect": # pragma: no cover
55 # at this point a disconnect is all that we should be receiving
56 # if we get something else, things went wrong somewhere
57 raise RuntimeError(f"Unexpected message received: {msg['type']}")
58 self._wrapped_rcv_disconnected = True
59 return msg
60
61 # wrapped_rcv state 3: not yet consumed
62 if getattr(self, "_body", None) is not None:
63 # body() was called, we return it even if the client disconnected
64 self._wrapped_rcv_consumed = True
65 return {
66 "type": "http.request",
67 "body": self._body,
68 "more_body": False,
69 }
70 elif self._stream_consumed:
71 # stream() was called to completion
72 # return an empty body so that downstream apps don't hang
73 # waiting for a disconnect
74 self._wrapped_rcv_consumed = True
75 return {
76 "type": "http.request",
77 "body": b"",
78 "more_body": False,
79 }
80 else:
81 # body() was never called and stream() wasn't consumed
82 try:
83 stream = self.stream()
84 chunk = await stream.__anext__()
85 self._wrapped_rcv_consumed = self._stream_consumed
86 return {
87 "type": "http.request",
88 "body": chunk,
89 "more_body": not self._stream_consumed,
90 }
91 except ClientDisconnect:

Callers

nothing calls this directly

Calls 3

streamMethod · 0.80
__anext__Method · 0.80
receiveMethod · 0.45

Tested by

no test coverage detected