| 320 | return {"type": "http.request", "body": body_bytes} |
| 321 | |
| 322 | async def send(message: Message) -> None: |
| 323 | nonlocal raw_kwargs, response_started, debug_info, body_complete, trailers_expected |
| 324 | |
| 325 | if message["type"] == "http.response.start": |
| 326 | assert not response_started, 'Received multiple "http.response.start" messages.' |
| 327 | raw_kwargs["status_code"] = message["status"] |
| 328 | raw_kwargs["headers"] = [(key.decode(), value.decode()) for key, value in message.get("headers", [])] |
| 329 | response_started = True |
| 330 | trailers_expected = message.get("trailers", False) |
| 331 | elif message["type"] == "http.response.body": |
| 332 | assert response_started, 'Received "http.response.body" without "http.response.start".' |
| 333 | assert not response_complete.is_set(), 'Received "http.response.body" after response completed.' |
| 334 | assert not body_complete, 'Received "http.response.body" after body completed.' |
| 335 | body = message.get("body", b"") |
| 336 | more_body = message.get("more_body", False) |
| 337 | if request.method != "HEAD": |
| 338 | raw_kwargs["stream"].write(body) |
| 339 | if not more_body: |
| 340 | raw_kwargs["stream"].seek(0) |
| 341 | body_complete = True |
| 342 | if not trailers_expected: |
| 343 | response_complete.set() |
| 344 | elif message["type"] == "http.response.trailers": |
| 345 | assert trailers_expected, 'Received "http.response.trailers" without declaring trailers.' |
| 346 | assert body_complete, 'Received "http.response.trailers" before body completed.' |
| 347 | assert not response_complete.is_set(), 'Received "http.response.trailers" after response completed.' |
| 348 | trailers.extend(message.get("headers", [])) |
| 349 | if not message.get("more_trailers", False): |
| 350 | response_complete.set() |
| 351 | elif message["type"] == "http.response.debug": |
| 352 | debug_info = message["info"] |
| 353 | |
| 354 | try: |
| 355 | with self.portal_factory() as portal: |