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

Class _CachedRequest

starlette/middleware/base.py:20–93  ·  view source on GitHub ↗

If the user calls Request.body() from their dispatch function we cache the entire request body in memory and pass that to downstream middlewares, but if they call Request.stream() then all we do is send an empty body so that downstream things don't hang forever.

Source from the content-addressed store, hash-verified

18
19
20class _CachedRequest(Request):
21 """
22 If the user calls Request.body() from their dispatch function
23 we cache the entire request body in memory and pass that to downstream middlewares,
24 but if they call Request.stream() then all we do is send an
25 empty body so that downstream things don't hang forever.
26 """
27
28 def __init__(self, scope: Scope, receive: Receive):
29 super().__init__(scope, receive)
30 self._wrapped_rcv_disconnected = False
31 self._wrapped_rcv_consumed = False
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"",

Callers 1

__call__Method · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected