|
| 1 | +"""MultiHost capable aiohttp Site.""" |
| 2 | +from __future__ import annotations |
| 3 | + |
| 4 | +import asyncio |
| 5 | +from ssl import SSLContext |
| 6 | + |
| 7 | +from aiohttp import web |
| 8 | +from yarl import URL |
| 9 | + |
| 10 | + |
| 11 | +class MultiHostTCPSite(web.TCPSite): |
| 12 | + """MultiHost capable aiohttp Site. |
| 13 | +
|
| 14 | + Vanilla TCPSite accepts only str as host. However, the underlying asyncio's |
| 15 | + create_server() implementation does take a list of strings to bind to multiple |
| 16 | + host IP's. To support multiple server_host entries (e.g. to enable dual-stack |
| 17 | + explicitly), we would like to pass an array of strings. |
| 18 | + """ |
| 19 | + |
| 20 | + __slots__ = ("_host", "_port", "_reuse_address", "_reuse_port", "_hosturl") |
| 21 | + |
| 22 | + def __init__( |
| 23 | + self, |
| 24 | + runner: web.BaseRunner, |
| 25 | + host: None | str | list[str], |
| 26 | + port: int, |
| 27 | + *, |
| 28 | + ssl_context: SSLContext | None = None, |
| 29 | + backlog: int = 128, |
| 30 | + reuse_address: bool | None = None, |
| 31 | + reuse_port: bool | None = None, |
| 32 | + ) -> None: |
| 33 | + """Initialize HomeAssistantTCPSite.""" |
| 34 | + super().__init__( |
| 35 | + runner, |
| 36 | + ssl_context=ssl_context, |
| 37 | + backlog=backlog, |
| 38 | + ) |
| 39 | + self._host = host |
| 40 | + self._port = port |
| 41 | + self._reuse_address = reuse_address |
| 42 | + self._reuse_port = reuse_port |
| 43 | + |
| 44 | + @property |
| 45 | + def name(self) -> str: |
| 46 | + """Return server URL.""" |
| 47 | + scheme = "https" if self._ssl_context else "http" |
| 48 | + host = self._host[0] if isinstance(self._host, list) else "0.0.0.0" |
| 49 | + return str(URL.build(scheme=scheme, host=host, port=self._port)) |
0 commit comments