diff --git a/homeassistant/components/backup/http.py b/homeassistant/components/backup/http.py index 11d8199bdc5..b71859611b4 100644 --- a/homeassistant/components/backup/http.py +++ b/homeassistant/components/backup/http.py @@ -8,7 +8,7 @@ import threading from typing import IO, cast from aiohttp import BodyPartReader -from aiohttp.hdrs import CONTENT_DISPOSITION +from aiohttp.hdrs import CONTENT_DISPOSITION, CONTENT_TYPE from aiohttp.web import FileResponse, Request, Response, StreamResponse from multidict import istr @@ -76,7 +76,8 @@ class DownloadBackupView(HomeAssistantView): return Response(status=HTTPStatus.NOT_FOUND) headers = { - CONTENT_DISPOSITION: f"attachment; filename={slugify(backup.name)}.tar" + CONTENT_DISPOSITION: f"attachment; filename={slugify(backup.name)}.tar", + CONTENT_TYPE: "application/x-tar", } try: diff --git a/tests/components/backup/test_http.py b/tests/components/backup/test_http.py index b3845b1209a..0d5bdfd6504 100644 --- a/tests/components/backup/test_http.py +++ b/tests/components/backup/test_http.py @@ -4,11 +4,13 @@ import asyncio from collections.abc import AsyncIterator from io import BytesIO, StringIO import json +import re import tarfile from typing import Any from unittest.mock import patch from aiohttp import web +from aiohttp.hdrs import CONTENT_DISPOSITION, CONTENT_TYPE import pytest from homeassistant.components.backup import ( @@ -166,10 +168,19 @@ async def _test_downloading_encrypted_backup( agent_id: str, ) -> None: """Test downloading an encrypted backup file.""" + + def assert_tar_download_response(resp: web.Response) -> None: + assert resp.status == 200 + assert resp.headers.get(CONTENT_TYPE, "") == "application/x-tar" + assert re.match( + r"attachment; filename=.*\.tar", resp.headers.get(CONTENT_DISPOSITION, "") + ) + # Try downloading without supplying a password client = await hass_client() resp = await client.get(f"/api/backup/download/c0cb53bd?agent_id={agent_id}") - assert resp.status == 200 + assert_tar_download_response(resp) + backup = await resp.read() # We expect a valid outer tar file, but the inner tar file is encrypted and # can't be read @@ -187,7 +198,7 @@ async def _test_downloading_encrypted_backup( resp = await client.get( f"/api/backup/download/c0cb53bd?agent_id={agent_id}&password=wrong" ) - assert resp.status == 200 + assert_tar_download_response(resp) backup = await resp.read() # We expect a truncated outer tar file with ( @@ -200,7 +211,7 @@ async def _test_downloading_encrypted_backup( resp = await client.get( f"/api/backup/download/c0cb53bd?agent_id={agent_id}&password=hunter2" ) - assert resp.status == 200 + assert_tar_download_response(resp) backup = await resp.read() # We expect a valid outer tar file, the inner tar file is decrypted and can be read with (