This commit is contained in:
Mateusz Gruszczyński committed 2026-11-08 09:55:44 +01:00
1 parent 6ef01212ec
commit d7fb869783
4 files changed
+41 -6

No files matched your search

+1
View File
@@ -7,6 +7,7 @@ Release history focused on **features, settings, default behavior, compatibility
- **Certificate auto-selection:** when creating a vhost, redirect or 404 host, RustProxy picks the stored certificate that covers every host name you enter (an exact name beats a wildcard, the narrowest certificate wins). A hint names the chosen certificate and the selector still lets you pick another one or the global default. Existing entries are never changed. - **Certificate auto-selection:** when creating a vhost, redirect or 404 host, RustProxy picks the stored certificate that covers every host name you enter (an exact name beats a wildcard, the narrowest certificate wins). A hint names the chosen certificate and the selector still lets you pick another one or the global default. Existing entries are never changed.
- **Clearer host conflicts:** the "overlapping frontend bindings for hostname …" error now names the entry that already uses the host (`vhost`, `redirect` or `404 host` plus its ID) and the conflicting listener address. - **Clearer host conflicts:** the "overlapping frontend bindings for hostname …" error now names the entry that already uses the host (`vhost`, `redirect` or `404 host` plus its ID) and the conflicting listener address.
- **Clearer validation errors:** duplicate or invalid IDs, repeated hostnames, missing hostnames or listeners, invalid location IDs, regular expressions, exact paths and duplicate location matchers now say which value or location is wrong and how to fix it. - **Clearer validation errors:** duplicate or invalid IDs, repeated hostnames, missing hostnames or listeners, invalid location IDs, regular expressions, exact paths and duplicate location matchers now say which value or location is wrong and how to fix it.
- **Deploy script:** `update.sh` / `install.sh` retry the GeoIP download (transient 502/503/504, timeouts) up to four times and, if it still fails, warn and continue with the installed GeoIP data instead of aborting the update with `HTTP Error 504`.
## 0.36.4 — cache readability and editor UX polish ## 0.36.4 — cache readability and editor UX polish
+3 -3
View File
@@ -2,7 +2,7 @@
4140a2956264b44f259e6a37fc00ba02097bbe68b09296e04d3d243c1287129b /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/.env.example 4140a2956264b44f259e6a37fc00ba02097bbe68b09296e04d3d243c1287129b /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/.env.example
e76e688874828e3743d03693b1d2872b9633b4db09909673786caf30f7cfe489 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/.gitignore e76e688874828e3743d03693b1d2872b9633b4db09909673786caf30f7cfe489 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/.gitignore
875fa17d64e0cf8f097cd4635ca801686c256d556680a39a9259dcdb1155ed6c /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/AGENTS.md 875fa17d64e0cf8f097cd4635ca801686c256d556680a39a9259dcdb1155ed6c /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/AGENTS.md
a544bba6a7558f7aa780ddd3e1c9e67aae58e371dddb99e8b277455f2d4cb46b /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/CHANGELOG.md 7619bfb852154916eaec3f84ecae54cc58b2ab1607c8a38f158524a5e388a542 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/CHANGELOG.md
eae2405a396e300ca4f2997a36239648b74acebf9e724b8c8d095c11969e3fd9 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/Cargo.lock eae2405a396e300ca4f2997a36239648b74acebf9e724b8c8d095c11969e3fd9 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/Cargo.lock
202e5377c7875ef538d420ccb563c26d4cb010dbcd49ce80ca1a1555d267b038 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/Cargo.toml 202e5377c7875ef538d420ccb563c26d4cb010dbcd49ce80ca1a1555d267b038 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/Cargo.toml
25c7f3c8162cbf5cc156439774118a81dae9fdc52b611ec7e40c230fc99a772c /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/Dockerfile 25c7f3c8162cbf5cc156439774118a81dae9fdc52b611ec7e40c230fc99a772c /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/Dockerfile
@@ -120,8 +120,8 @@ fd1c34599f725ad5f7c3c0cc89e08b11917baef02c83af054ac8528b2e01dd8e /sessions/rcw-
c3066f40f152a2655f88314fd9cf784eddbfa6c3238a494da13d972ef9ad930c /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/build/panel_css.py c3066f40f152a2655f88314fd9cf784eddbfa6c3238a494da13d972ef9ad930c /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/build/panel_css.py
5e98d6c30047512825f5dc1c42709b82f0f6342fc0db8346a67ae85ffeb40c90 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/build/swagger_assets.py 5e98d6c30047512825f5dc1c42709b82f0f6342fc0db8346a67ae85ffeb40c90 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/build/swagger_assets.py
e4d15aa6aa864d04b9b30aca33826b833632af02ca643f8b23e219a5ea1298dd /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/deploy/deploy.py e4d15aa6aa864d04b9b30aca33826b833632af02ca643f8b23e219a5ea1298dd /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/deploy/deploy.py
618603239b000bbe4af36a6a6ee268758af632c761fc53fc6b7f44a4a818bdf1 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/deploy/deploy_core.py f0edbdca3af49cfa8f9c118d3eb0977c99569264dc5d74a85c4610234ea1fe88 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/deploy/deploy_core.py
992c9a806464fa10902de5be102f1609469986331fc0ae223a5b5f8507153574 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/deploy/deploy_runtime.py f26297284e0ad9fb4e4317deac24b25de819c10d04fed551134ddb6debc41837 /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/deploy/deploy_runtime.py
a59587ce8ad41b1bbb431356b58398f9c8ff7cb96a613a91752e907a70e10c2e /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/deploy/upgrade.py a59587ce8ad41b1bbb431356b58398f9c8ff7cb96a613a91752e907a70e10c2e /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/deploy/upgrade.py
2cc658faaa610b21b48942c59b955525539ad4503fd60f2a49c7e626a22faaff /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/migration/migrate_npm.py 2cc658faaa610b21b48942c59b955525539ad4503fd60f2a49c7e626a22faaff /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/migration/migrate_npm.py
a459d95bbb0076f33ade8b273b813308167f9d8d45242b309a2d18320ca0093c /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/migration/migrate_npm_api.py a459d95bbb0076f33ade8b273b813308167f9d8d45242b309a2d18320ca0093c /sessions/rcw-01mmsgszuju6d7f2h8egrxc4/mnt/RustProxy/scripts/migration/migrate_npm_api.py
Executable → Regular
+27 -1
View File
@@ -28,6 +28,7 @@ import subprocess
import sys import sys
import time import time
import uuid import uuid
import urllib.error
import urllib.request import urllib.request
import urllib.parse import urllib.parse
@@ -41,6 +42,12 @@ GEOIP_SOURCES = {
'user-country-ipv6.csv': 'https://github.com/sapics/ip-location-db/releases/download/latest/user-country-ipv6.csv', 'user-country-ipv6.csv': 'https://github.com/sapics/ip-location-db/releases/download/latest/user-country-ipv6.csv',
} }
GEOIP_MAX_BYTES = 256 * 1024 * 1024 GEOIP_MAX_BYTES = 256 * 1024 * 1024
GEOIP_FETCH_ATTEMPTS = 4
GEOIP_RETRY_DELAYS = (3, 6, 12)
class GeoipUnavailable(RuntimeError):
"""The GeoIP CSV download failed after retries; the deployment itself can continue."""
def run(args: list[str], **kwargs) -> subprocess.CompletedProcess: def run(args: list[str], **kwargs) -> subprocess.CompletedProcess:
@@ -93,7 +100,7 @@ def digest(path: Path) -> str:
return result.hexdigest() return result.hexdigest()
def fetch_https(url: str, max_bytes: int) -> bytes: def _fetch_https_once(url: str, max_bytes: int) -> bytes:
if urllib.parse.urlparse(url).scheme != 'https': if urllib.parse.urlparse(url).scheme != 'https':
raise ValueError('GeoIP downloads require HTTPS.') raise ValueError('GeoIP downloads require HTTPS.')
request = urllib.request.Request(url, headers={'User-Agent': 'RustProxy-installer'}) request = urllib.request.Request(url, headers={'User-Agent': 'RustProxy-installer'})
@@ -114,6 +121,25 @@ def fetch_https(url: str, max_bytes: int) -> bytes:
return bytes(result) return bytes(result)
def fetch_https(url: str, max_bytes: int) -> bytes:
"""Download with retries; transient gateway/network failures (502/503/504, timeouts) are retried."""
last: BaseException | None = None
for attempt in range(GEOIP_FETCH_ATTEMPTS):
try:
return _fetch_https_once(url, max_bytes)
except urllib.error.HTTPError as error:
last = error
if error.code not in (408, 425, 429) and error.code < 500:
break
except (urllib.error.URLError, TimeoutError, ConnectionError, ssl.SSLError) as error:
last = error
if attempt + 1 < GEOIP_FETCH_ATTEMPTS:
delay = GEOIP_RETRY_DELAYS[min(attempt, len(GEOIP_RETRY_DELAYS) - 1)]
print(f'GeoIP download failed ({last}); retrying in {delay}s ({attempt + 1}/{GEOIP_FETCH_ATTEMPTS - 1}).', file=sys.stderr)
time.sleep(delay)
raise GeoipUnavailable(f'GeoIP download from {url} failed: {last}')
def acquire_geoip_update_lock(data: Path, uid: int | None = None, gid: int | None = None) -> int: def acquire_geoip_update_lock(data: Path, uid: int | None = None, gid: int | None = None) -> int:
"""Serialize installer/manual GeoIP refresh with the in-process worker.""" """Serialize installer/manual GeoIP refresh with the in-process worker."""
path = data / '.geoip-update.lock' path = data / '.geoip-update.lock'
Executable → Regular
+10 -2
View File
@@ -365,7 +365,12 @@ def update(record: dict, binary: Path, sha: str, start: bool, refresh_geoip: boo
if refresh_geoip: if refresh_geoip:
# Shared lock with the runtime worker prevents concurrent upgrades. # Shared lock with the runtime worker prevents concurrent upgrades.
geoip_lock_fd = acquire_geoip_update_lock(data, account.pw_uid, account.pw_gid) geoip_lock_fd = acquire_geoip_update_lock(data, account.pw_uid, account.pw_gid)
geoip_stage, geoip_names = prepare_geoip_update(data, prefix) try:
geoip_stage, geoip_names = prepare_geoip_update(data, prefix)
except GeoipUnavailable as error:
# GeoIP is refreshed best-effort: the update must not be blocked by a flaky download.
print(f'WARNING: GeoIP refresh skipped, keeping the installed country data: {error}', file=sys.stderr)
geoip_stage, geoip_names = None, []
active = subprocess.run(['systemctl', 'is-active', '--quiet', SERVICE], check=False, stdout=subprocess.DEVNULL).returncode == 0 active = subprocess.run(['systemctl', 'is-active', '--quiet', SERVICE], check=False, stdout=subprocess.DEVNULL).returncode == 0
stop_for_managed_update(data) stop_for_managed_update(data)
try: try:
@@ -434,7 +439,10 @@ def install(record: dict, binary: Path, sha: str, start: bool, install_geoip: bo
prefix.mkdir(parents=True, mode=0o755, exist_ok=True); os.chmod(prefix, 0o755) prefix.mkdir(parents=True, mode=0o755, exist_ok=True); os.chmod(prefix, 0o755)
data.mkdir(parents=True, mode=0o700, exist_ok=True); os.chmod(data, 0o700); os.chown(data, account.pw_uid, account.pw_gid) data.mkdir(parents=True, mode=0o700, exist_ok=True); os.chmod(data, 0o700); os.chown(data, account.pw_uid, account.pw_gid)
if install_geoip: if install_geoip:
download_geoip(data, account.pw_uid, account.pw_gid) try:
download_geoip(data, account.pw_uid, account.pw_gid)
except GeoipUnavailable as error:
print(f'WARNING: GeoIP download skipped ({error}). Country allow/block lists will use data fetched later by the GeoIP updater, or rerun update.sh.', file=sys.stderr)
release, version = stage(binary, prefix, record['user'], sha) release, version = stage(binary, prefix, record['user'], sha)
record.update(release=release, version=version, sha256=sha) record.update(release=release, version=version, sha256=sha)
switch(prefix, release) switch(prefix, release)