mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-17 13:55:08 +00:00
test(nginx): add regression coverage for /files headers
This commit is contained in:
parent
00c3475943
commit
3ffa8b720c
2 changed files with 48 additions and 16 deletions
|
|
@ -5,7 +5,7 @@ from typing import Any
|
|||
import pytest
|
||||
|
||||
from tests.conftest import S3ServiceResult
|
||||
from tests.utils import Compose, check_url_content
|
||||
from tests.utils import Compose, check_url_content, wait_for_url
|
||||
|
||||
BACKEND_SERVICES = (
|
||||
"backend",
|
||||
|
|
@ -81,6 +81,28 @@ def test_files_reachable(frappe_site: str, tmp_path: Path, compose: Compose):
|
|||
)
|
||||
|
||||
|
||||
def test_files_html_security_headers(
|
||||
frappe_site: str, tmp_path: Path, compose: Compose
|
||||
):
|
||||
file_path = tmp_path / "testfile.html"
|
||||
file_path.write_text("<html><body>This is a Frappe Docker test html file</body></html>")
|
||||
|
||||
compose(
|
||||
"cp",
|
||||
str(file_path),
|
||||
f"backend:/home/frappe/frappe-bench/sites/{frappe_site}/public/files/",
|
||||
)
|
||||
|
||||
response = wait_for_url(
|
||||
url=f"http://127.0.0.1/files/{file_path.name}",
|
||||
site_name=frappe_site,
|
||||
)
|
||||
|
||||
assert response.headers["Content-Disposition"] == "attachment"
|
||||
assert response.headers["X-Frame-Options"] == "SAMEORIGIN"
|
||||
assert response.headers["X-Content-Type-Options"] == "nosniff"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("service", BACKEND_SERVICES)
|
||||
@pytest.mark.usefixtures("frappe_site")
|
||||
def test_frappe_connections_in_backends(
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import subprocess
|
|||
import sys
|
||||
import time
|
||||
from contextlib import suppress
|
||||
from http.client import HTTPResponse
|
||||
from typing import Callable, Optional
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.request import Request, urlopen
|
||||
|
|
@ -59,24 +60,11 @@ class Compose:
|
|||
def check_url_content(
|
||||
url: str, callback: Callable[[str], Optional[str]], site_name: str
|
||||
):
|
||||
request = Request(url, headers={"Host": site_name})
|
||||
|
||||
# This is needed to check https override
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
|
||||
for _ in range(100):
|
||||
try:
|
||||
response = urlopen(request, context=ctx)
|
||||
|
||||
except HTTPError as exc:
|
||||
if exc.code not in (404, 502):
|
||||
raise
|
||||
|
||||
except URLError:
|
||||
response = wait_for_url(url=url, site_name=site_name, attempts=1)
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
else:
|
||||
text: str = response.read().decode()
|
||||
ret = callback(text)
|
||||
|
|
@ -86,4 +74,26 @@ def check_url_content(
|
|||
|
||||
time.sleep(0.1)
|
||||
|
||||
raise RuntimeError(f"Couldn't verify expected content from {url}")
|
||||
|
||||
|
||||
def wait_for_url(url: str, site_name: str, attempts: int = 100) -> HTTPResponse:
|
||||
request = Request(url, headers={"Host": site_name})
|
||||
|
||||
# This is needed to check https override
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
|
||||
for _ in range(attempts):
|
||||
try:
|
||||
return urlopen(request, context=ctx)
|
||||
except HTTPError as exc:
|
||||
if exc.code not in (404, 502):
|
||||
raise
|
||||
except URLError:
|
||||
pass
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
raise RuntimeError(f"Couldn't ping {url}")
|
||||
|
|
|
|||
Loading…
Reference in a new issue