diff --git a/homeassistant/components/emulated_hue/__init__.py b/homeassistant/components/emulated_hue/__init__.py index 5f1d61dd602..9c0df0f9f03 100644 --- a/homeassistant/components/emulated_hue/__init__.py +++ b/homeassistant/components/emulated_hue/__init__.py @@ -97,8 +97,8 @@ async def async_setup(hass, yaml_config): app._on_startup.freeze() await app.startup() - handler = None - server = None + runner = None + site = None DescriptionXmlView(config).register(app, app.router) HueUsernameView().register(app, app.router) @@ -115,25 +115,24 @@ async def async_setup(hass, yaml_config): async def stop_emulated_hue_bridge(event): """Stop the emulated hue bridge.""" upnp_listener.stop() - if server: - server.close() - await server.wait_closed() - await app.shutdown() - if handler: - await handler.shutdown(10) - await app.cleanup() + if site: + await site.stop() + if runner: + await runner.cleanup() async def start_emulated_hue_bridge(event): """Start the emulated hue bridge.""" upnp_listener.start() - nonlocal handler - nonlocal server + nonlocal site + nonlocal runner - handler = app.make_handler(loop=hass.loop) + runner = web.AppRunner(app) + await runner.setup() + + site = web.TCPSite(runner, config.host_ip_addr, config.listen_port) try: - server = await hass.loop.create_server( - handler, config.host_ip_addr, config.listen_port) + await site.start() except OSError as error: _LOGGER.error("Failed to create HTTP server at port %d: %s", config.listen_port, error) diff --git a/homeassistant/components/http/__init__.py b/homeassistant/components/http/__init__.py index 1b22f8e62d4..7180002430a 100644 --- a/homeassistant/components/http/__init__.py +++ b/homeassistant/components/http/__init__.py @@ -302,12 +302,6 @@ class HomeAssistantHTTP: async def start(self): """Start the aiohttp server.""" - # We misunderstood the startup signal. You're not allowed to change - # anything during startup. Temp workaround. - # pylint: disable=protected-access - self.app._on_startup.freeze() - await self.app.startup() - if self.ssl_certificate: try: if self.ssl_profile == SSL_INTERMEDIATE: @@ -335,6 +329,7 @@ class HomeAssistantHTTP: # However in Home Assistant components can be discovered after boot. # This will now raise a RunTimeError. # To work around this we now prevent the router from getting frozen + # pylint: disable=protected-access self.app._router.freeze = lambda: None self.runner = web.AppRunner(self.app) diff --git a/homeassistant/components/http/auth.py b/homeassistant/components/http/auth.py index 64ee7fb8a3f..1f89dc5e4ca 100644 --- a/homeassistant/components/http/auth.py +++ b/homeassistant/components/http/auth.py @@ -96,11 +96,7 @@ def setup_auth(app, trusted_networks, use_auth, request[KEY_AUTHENTICATED] = authenticated return await handler(request) - async def auth_startup(app): - """Initialize auth middleware when app starts up.""" - app.middlewares.append(auth_middleware) - - app.on_startup.append(auth_startup) + app.middlewares.append(auth_middleware) def _is_trusted_ip(request, trusted_networks): diff --git a/homeassistant/components/http/ban.py b/homeassistant/components/http/ban.py index 2a25de96edc..d6d7168ce6d 100644 --- a/homeassistant/components/http/ban.py +++ b/homeassistant/components/http/ban.py @@ -9,7 +9,7 @@ from aiohttp.web import middleware from aiohttp.web_exceptions import HTTPForbidden, HTTPUnauthorized import voluptuous as vol -from homeassistant.core import callback +from homeassistant.core import callback, HomeAssistant from homeassistant.config import load_yaml_config_file from homeassistant.exceptions import HomeAssistantError import homeassistant.helpers.config_validation as cv @@ -36,13 +36,14 @@ SCHEMA_IP_BAN_ENTRY = vol.Schema({ @callback def setup_bans(hass, app, login_threshold): """Create IP Ban middleware for the app.""" + app.middlewares.append(ban_middleware) + app[KEY_FAILED_LOGIN_ATTEMPTS] = defaultdict(int) + app[KEY_LOGIN_THRESHOLD] = login_threshold + async def ban_startup(app): """Initialize bans when app starts up.""" - app.middlewares.append(ban_middleware) - app[KEY_BANNED_IPS] = await hass.async_add_job( - load_ip_bans_config, hass.config.path(IP_BANS_FILE)) - app[KEY_FAILED_LOGIN_ATTEMPTS] = defaultdict(int) - app[KEY_LOGIN_THRESHOLD] = login_threshold + app[KEY_BANNED_IPS] = await async_load_ip_bans_config( + hass, hass.config.path(IP_BANS_FILE)) app.on_startup.append(ban_startup) @@ -149,7 +150,7 @@ class IpBan: self.banned_at = banned_at or datetime.utcnow() -def load_ip_bans_config(path: str): +async def async_load_ip_bans_config(hass: HomeAssistant, path: str): """Load list of banned IPs from config file.""" ip_list = [] @@ -157,7 +158,7 @@ def load_ip_bans_config(path: str): return ip_list try: - list_ = load_yaml_config_file(path) + list_ = await hass.async_add_executor_job(load_yaml_config_file, path) except HomeAssistantError as err: _LOGGER.error('Unable to load %s: %s', path, str(err)) return ip_list diff --git a/homeassistant/components/http/real_ip.py b/homeassistant/components/http/real_ip.py index f8adc815fde..27a8550ab8c 100644 --- a/homeassistant/components/http/real_ip.py +++ b/homeassistant/components/http/real_ip.py @@ -33,8 +33,4 @@ def setup_real_ip(app, use_x_forwarded_for, trusted_proxies): return await handler(request) - async def app_startup(app): - """Initialize bans when app starts up.""" - app.middlewares.append(real_ip_middleware) - - app.on_startup.append(app_startup) + app.middlewares.append(real_ip_middleware) diff --git a/tests/components/conftest.py b/tests/components/conftest.py index 2568a109244..b519b8e936d 100644 --- a/tests/components/conftest.py +++ b/tests/components/conftest.py @@ -9,7 +9,15 @@ from homeassistant.components.websocket_api.http import URL from homeassistant.components.websocket_api.auth import ( TYPE_AUTH, TYPE_AUTH_OK, TYPE_AUTH_REQUIRED) -from tests.common import MockUser, CLIENT_ID +from tests.common import MockUser, CLIENT_ID, mock_coro + + +@pytest.fixture(autouse=True) +def prevent_io(): + """Fixture to prevent certain I/O from happening.""" + with patch('homeassistant.components.http.ban.async_load_ip_bans_config', + side_effect=lambda *args: mock_coro([])): + yield @pytest.fixture diff --git a/tests/components/http/test_ban.py b/tests/components/http/test_ban.py index a6a07928113..6624937da8d 100644 --- a/tests/components/http/test_ban.py +++ b/tests/components/http/test_ban.py @@ -16,6 +16,9 @@ from homeassistant.components.http.ban import ( from . import mock_real_ip +from tests.common import mock_coro + + BANNED_IPS = ['200.201.202.203', '100.64.0.2'] @@ -25,9 +28,9 @@ async def test_access_from_banned_ip(hass, aiohttp_client): setup_bans(hass, app, 5) set_real_ip = mock_real_ip(app) - with patch('homeassistant.components.http.ban.load_ip_bans_config', - return_value=[IpBan(banned_ip) for banned_ip - in BANNED_IPS]): + with patch('homeassistant.components.http.ban.async_load_ip_bans_config', + return_value=mock_coro([IpBan(banned_ip) for banned_ip + in BANNED_IPS])): client = await aiohttp_client(app) for remote_addr in BANNED_IPS: @@ -71,9 +74,9 @@ async def test_ip_bans_file_creation(hass, aiohttp_client): setup_bans(hass, app, 1) mock_real_ip(app)("200.201.202.204") - with patch('homeassistant.components.http.ban.load_ip_bans_config', - return_value=[IpBan(banned_ip) for banned_ip - in BANNED_IPS]): + with patch('homeassistant.components.http.ban.async_load_ip_bans_config', + return_value=mock_coro([IpBan(banned_ip) for banned_ip + in BANNED_IPS])): client = await aiohttp_client(app) m = mock_open()