(self, message: ASGISendEvent)
| 457 | |
| 458 | # ASGI interface |
| 459 | async def send(self, message: ASGISendEvent) -> None: |
| 460 | if self.flow.write_paused and not self.disconnected: |
| 461 | await self.flow.drain() # pragma: full coverage |
| 462 | |
| 463 | if self.disconnected: |
| 464 | return # pragma: full coverage |
| 465 | |
| 466 | if not self.response_started: |
| 467 | # Sending response status line and headers |
| 468 | if message["type"] != "http.response.start": |
| 469 | raise RuntimeError(f"Expected ASGI message 'http.response.start', but got '{message['type']}'.") |
| 470 | |
| 471 | self.response_started = True |
| 472 | self.waiting_for_100_continue = False |
| 473 | |
| 474 | status = message["status"] |
| 475 | headers = self.default_headers + list(message.get("headers", [])) |
| 476 | |
| 477 | if CLOSE_HEADER in self.scope["headers"] and CLOSE_HEADER not in headers: |
| 478 | headers = headers + [CLOSE_HEADER] |
| 479 | |
| 480 | if self.access_log: |
| 481 | self.access_logger.info( |
| 482 | '%s - "%s %s HTTP/%s" %d', |
| 483 | get_client_addr(self.scope), |
| 484 | self.scope["method"], |
| 485 | get_path_with_query_string(self.scope), |
| 486 | self.scope["http_version"], |
| 487 | status, |
| 488 | ) |
| 489 | |
| 490 | # Write response status line and headers |
| 491 | reason = STATUS_PHRASES[status] |
| 492 | response = h11.Response(status_code=status, headers=headers, reason=reason) |
| 493 | output = self.conn.send(event=response) |
| 494 | self.transport.write(output) |
| 495 | |
| 496 | elif not self.response_complete: |
| 497 | # Sending response body |
| 498 | if message["type"] != "http.response.body": |
| 499 | raise RuntimeError(f"Expected ASGI message 'http.response.body', but got '{message['type']}'.") |
| 500 | |
| 501 | body = message.get("body", b"") |
| 502 | more_body = message.get("more_body", False) |
| 503 | |
| 504 | # Write response body |
| 505 | data = b"" if self.scope["method"] == "HEAD" else body |
| 506 | output = self.conn.send(event=h11.Data(data=data)) |
| 507 | self.transport.write(output) |
| 508 | |
| 509 | # Handle response completion |
| 510 | if not more_body: |
| 511 | self.response_complete = True |
| 512 | self.message_event.set() |
| 513 | output = self.conn.send(event=h11.EndOfMessage()) |
| 514 | self.transport.write(output) |
| 515 | |
| 516 | else: |
no test coverage detected