Send messages to the current cycle.
(self, message: dict[str, Any])
| 1416 | return message |
| 1417 | |
| 1418 | async def send(self, message: dict[str, Any]) -> None: |
| 1419 | """Send messages to the current cycle.""" |
| 1420 | message_type = message["type"] |
| 1421 | |
| 1422 | if self.state is ASGICycleState.REQUEST: |
| 1423 | if message_type != "http.response.start": |
| 1424 | raise RuntimeError( |
| 1425 | f"Expected 'http.response.start'," |
| 1426 | f" received: {message_type}" |
| 1427 | ) |
| 1428 | |
| 1429 | status_code = message["status"] |
| 1430 | raw_headers: list[tuple[bytes | str, bytes | str]] = ( |
| 1431 | message.get("headers", []) |
| 1432 | ) |
| 1433 | |
| 1434 | # Headers from werkzeug transform bytes header value |
| 1435 | # from b'value' to "b'value'" so we need to process |
| 1436 | # ASGI headers manually |
| 1437 | decoded_headers: list[tuple[str, str]] = [] |
| 1438 | for key, value in raw_headers: |
| 1439 | decoded_key = ( |
| 1440 | key.decode() if isinstance(key, bytes) else key |
| 1441 | ) |
| 1442 | decoded_value = ( |
| 1443 | value.decode() |
| 1444 | if isinstance(value, bytes) |
| 1445 | else value |
| 1446 | ) |
| 1447 | decoded_headers.append((decoded_key, decoded_value)) |
| 1448 | |
| 1449 | headers = Headers(decoded_headers) |
| 1450 | |
| 1451 | self.on_request(headers, status_code) |
| 1452 | self.state = ASGICycleState.RESPONSE |
| 1453 | |
| 1454 | elif self.state is ASGICycleState.RESPONSE: |
| 1455 | if message_type != "http.response.body": |
| 1456 | raise RuntimeError( |
| 1457 | f"Expected 'http.response.body'," |
| 1458 | f" received: {message_type}" |
| 1459 | ) |
| 1460 | |
| 1461 | body = message.get("body", b"") |
| 1462 | more_body = message.get("more_body", False) |
| 1463 | |
| 1464 | # The body must be completely read before |
| 1465 | # returning the response. |
| 1466 | self.body += body |
| 1467 | |
| 1468 | if not more_body: |
| 1469 | self.on_response() |
| 1470 | self.put_message({"type": "http.disconnect"}) |
| 1471 | |
| 1472 | def on_request(self, headers: Any, status_code: int) -> None: |
| 1473 | self.response["statusCode"] = status_code |