Coverage for frappe_manager / site_manager / modules / upload_limit_manager.py: 18%
39 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-07-02 18:13 +0530
« prev ^ index » next coverage.py v7.13.5, created at 2026-07-02 18:13 +0530
1"""
2Manages client_max_body_size configuration for nginx-proxy vhost.d files.
3"""
5import re
6from pathlib import Path
9class UploadLimitManager:
10 """Manages upload limit directives in nginx-proxy vhost.d files."""
12 def __init__(self, vhostd_dir: Path):
13 """
14 Initialize the upload limit manager.
16 Args:
17 vhostd_dir: Path to nginx-proxy vhost.d directory
18 """
19 self.vhostd_dir = vhostd_dir
21 def set_upload_limit(self, domain: str, size: str):
22 """
23 Create or update vhost.d file with upload limit directive.
25 Args:
26 domain: Domain name (e.g., "example.com")
27 size: Size in nginx format (e.g., "50m", "1g")
28 """
29 vhost_file = self.vhostd_dir / domain
31 # Ensure size is lowercase for nginx compatibility
32 size = size.lower()
34 # Read existing content (if any)
35 existing_content = ""
36 if vhost_file.exists():
37 existing_content = vhost_file.read_text()
39 # Check if client_max_body_size already exists
40 if "client_max_body_size" in existing_content:
41 # Update existing directive using regex
42 updated = re.sub(r"client_max_body_size\s+[^;]+;", f"client_max_body_size {size};", existing_content)
43 vhost_file.write_text(updated)
44 else:
45 # Append to existing content
46 new_directive = f"\nclient_max_body_size {size};\n"
47 vhost_file.write_text(existing_content + new_directive)
49 def set_upload_limit_for_domains(self, domains: list[str], size: str):
50 """
51 Set upload limit for multiple domains.
53 Handles wildcard domains intelligently: if a wildcard exists (e.g., *.example.com),
54 subdomains matching that wildcard will NOT get individual files (to avoid nginx duplicates).
56 Args:
57 domains: List of domain names
58 size: Size in nginx format (e.g., "50m", "1g")
59 """
60 # Check if there are wildcard domains
61 wildcards = [d for d in domains if d.startswith("*.")]
62 non_wildcards = [d for d in domains if not d.startswith("*.")]
64 # First, update wildcard domains
65 for domain in wildcards:
66 self.set_upload_limit(domain, size)
68 # For non-wildcard domains, only update if they don't match any wildcard
69 for domain in non_wildcards:
70 # Check if this domain matches any wildcard
71 matches_wildcard = False
72 for wildcard in wildcards:
73 # Convert *.example.com to example.com for matching
74 wildcard_base = wildcard[2:] # Remove "*."
75 if domain.endswith(wildcard_base) and domain != wildcard_base:
76 # This domain is covered by the wildcard (e.g., sub.example.com matches *.example.com)
77 matches_wildcard = True
78 break
80 if not matches_wildcard:
81 # Only update if not covered by a wildcard
82 self.set_upload_limit(domain, size)
84 def remove_upload_limit(self, domain: str):
85 """
86 Remove upload limit directive from vhost.d file.
88 Note: Does not delete the file if other directives exist.
90 Args:
91 domain: Domain name
92 """
93 vhost_file = self.vhostd_dir / domain
95 if not vhost_file.exists():
96 return
98 content = vhost_file.read_text()
100 # Remove client_max_body_size directive
101 updated = re.sub(r"client_max_body_size\s+[^;]+;\n?", "", content)
103 # If file is now empty or only whitespace, remove it
104 if not updated.strip():
105 vhost_file.unlink()
106 else:
107 vhost_file.write_text(updated)