Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions backend/tests/test_uploads.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import inspect
import io
import re
from pathlib import Path

import pytest
from fastapi import UploadFile
Expand Down Expand Up @@ -62,6 +64,26 @@ def test_the_archive_cap_is_the_one_that_dominates():
assert parsed.max_request_bytes == 50_000 + MULTIPART_OVERHEAD_BYTES


NGINX_CONF = Path(__file__).resolve().parents[2] / "frontend" / "nginx.conf"
NGINX_UNITS = {"": 1, "k": 1024, "m": 1024**2, "g": 1024**3}


@pytest.mark.skipif(not NGINX_CONF.exists(), reason="needs the whole repository")
def test_the_proxy_admits_the_largest_body_the_api_accepts():
"""nginx sits in front of the API, so its cap has to be the looser one.

Below the API's, a full export archive is refused by nginx with an HTML
page before FastAPI sees it — which is how a 24m cap once stopped every
archive over 24 MiB while the API was ready to take 200.
"""
match = re.search(r"client_max_body_size\s+(\d+)([kmg]?);", NGINX_CONF.read_text(), re.I)
assert match, "nginx.conf no longer sets client_max_body_size"
proxy_limit = int(match[1]) * NGINX_UNITS[match[2].lower()]
defaults = Settings(_env_file=None, database_url="sqlite://")

assert proxy_limit >= defaults.max_request_bytes


def test_cors_origins_accept_a_comma_separated_string():
parsed = Settings(_env_file=None, database_url="sqlite://", cors_origins="http://a,http://b")

Expand Down
5 changes: 4 additions & 1 deletion frontend/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ server {

# Uploads go through here: keep this above the API's own limit so the
# request reaches FastAPI and gets a JSON 413 rather than an nginx page.
client_max_body_size 24m;
# That limit is the largest thing any route accepts — an export archive,
# MAX_ARCHIVE_BYTES (200 MiB) plus 1 MiB of framing — not a single file.
# test_uploads.py fails if the two drift apart.
client_max_body_size 210m;

gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;
Expand Down
Loading