| 212 | |
| 213 | |
| 214 | class Request(HTTPConnection[StateT]): |
| 215 | _form: FormData | None |
| 216 | |
| 217 | def __init__(self, scope: Scope, receive: Receive = empty_receive, send: Send = empty_send): |
| 218 | super().__init__(scope) |
| 219 | assert scope["type"] == "http" |
| 220 | self._receive = receive |
| 221 | self._send = send |
| 222 | self._stream_consumed = False |
| 223 | self._is_disconnected = False |
| 224 | self._form = None |
| 225 | |
| 226 | @property |
| 227 | def method(self) -> str: |
| 228 | return cast(str, self.scope["method"]) |
| 229 | |
| 230 | @property |
| 231 | def receive(self) -> Receive: |
| 232 | return self._receive |
| 233 | |
| 234 | async def stream(self) -> AsyncGenerator[bytes, None]: |
| 235 | if hasattr(self, "_body"): |
| 236 | yield self._body |
| 237 | yield b"" |
| 238 | return |
| 239 | if self._stream_consumed: |
| 240 | raise RuntimeError("Stream consumed") |
| 241 | while not self._stream_consumed: |
| 242 | message = await self._receive() |
| 243 | if message["type"] == "http.request": |
| 244 | body = message.get("body", b"") |
| 245 | if not message.get("more_body", False): |
| 246 | self._stream_consumed = True |
| 247 | if body: |
| 248 | yield body |
| 249 | elif message["type"] == "http.disconnect": # pragma: no branch |
| 250 | self._is_disconnected = True |
| 251 | raise ClientDisconnect() |
| 252 | yield b"" |
| 253 | |
| 254 | async def body(self) -> bytes: |
| 255 | if not hasattr(self, "_body"): |
| 256 | chunks: list[bytes] = [] |
| 257 | async for chunk in self.stream(): |
| 258 | chunks.append(chunk) |
| 259 | self._body = b"".join(chunks) |
| 260 | return self._body |
| 261 | |
| 262 | async def json(self) -> Any: |
| 263 | if not hasattr(self, "_json"): # pragma: no branch |
| 264 | body = await self.body() |
| 265 | self._json = json.loads(body) |
| 266 | return self._json |
| 267 | |
| 268 | async def _get_form( |
| 269 | self, |
| 270 | *, |
| 271 | max_files: int | float = 1000, |
no outgoing calls