mirror of
https://github.com/masterking32/MasterHttpRelayVPN.git
synced 2026-05-18 23:54:37 +03:00
refactor: update configuration keys and improve documentation for HTTP proxy settings
This commit is contained in:
@@ -107,6 +107,17 @@ FRONT_SNI_POOL_GOOGLE: tuple[str, ...] = (
|
||||
)
|
||||
|
||||
|
||||
# ── Bypass hosts (direct, no MITM/relay) ────────────────────────────────
|
||||
# Applied when bypass_hosts is omitted from config.json.
|
||||
# Advanced users can override this list in config.json under "bypass_hosts".
|
||||
DEFAULT_BYPASS_HOSTS: tuple[str, ...] = (
|
||||
"localhost",
|
||||
".local",
|
||||
".lan",
|
||||
".home.arpa",
|
||||
)
|
||||
|
||||
|
||||
# ── Per-host stats ────────────────────────────────────────────────────────
|
||||
STATS_LOG_INTERVAL = 300.0 # seconds — how often to log per-host totals
|
||||
STATS_LOG_TOP_N = 10 # how many hosts to include in the log
|
||||
|
||||
@@ -22,6 +22,7 @@ except Exception: # optional dependency fallback
|
||||
from core.constants import (
|
||||
CACHE_MAX_MB,
|
||||
CLIENT_IDLE_TIMEOUT,
|
||||
DEFAULT_BYPASS_HOSTS,
|
||||
GOOGLE_DIRECT_ALLOW_EXACT,
|
||||
GOOGLE_DIRECT_ALLOW_SUFFIXES,
|
||||
GOOGLE_DIRECT_EXACT_EXCLUDE,
|
||||
@@ -73,14 +74,15 @@ class ProxyServer:
|
||||
|
||||
def __init__(self, config: dict):
|
||||
self.host = config.get("listen_host", "127.0.0.1")
|
||||
self.port = config.get("listen_port", 8080)
|
||||
self.socks_enabled = config.get("socks5_enabled", True)
|
||||
# Prefer the new key (http_port) but keep listen_port for old configs.
|
||||
self.port = config.get("http_port", config.get("listen_port", 8080))
|
||||
self.socks_enabled = True
|
||||
self.socks_host = config.get("socks5_host", self.host)
|
||||
self.socks_port = config.get("socks5_port", 1080)
|
||||
if self.socks_enabled and self.socks_host == self.host \
|
||||
and int(self.socks_port) == int(self.port):
|
||||
raise ValueError(
|
||||
f"listen_port and socks5_port must differ on the same host "
|
||||
f"http_port and socks5_port must differ on the same host "
|
||||
f"(both set to {self.port} on {self.host}). "
|
||||
f"Change one of them in config.json."
|
||||
)
|
||||
@@ -137,12 +139,19 @@ class ProxyServer:
|
||||
}
|
||||
|
||||
# ── Per-host policy ────────────────────────────────────────
|
||||
# block_hosts — refuse traffic entirely (close or 403)
|
||||
# bypass_hosts — route directly (no MITM, no relay)
|
||||
# block_hosts — refuse traffic entirely (close or 403)
|
||||
# direct_hosts — route directly (no MITM, no relay)
|
||||
# bypass_hosts — legacy alias kept for backward compatibility
|
||||
# Both accept exact hostnames and leading-dot suffix patterns,
|
||||
# e.g. ".local" matches any *.local domain.
|
||||
self._block_hosts = load_host_rules(config.get("block_hosts", []))
|
||||
self._bypass_hosts = load_host_rules(config.get("bypass_hosts", []))
|
||||
direct_hosts = config.get("direct_hosts", [])
|
||||
bypass_hosts = config.get("bypass_hosts")
|
||||
if bypass_hosts is None:
|
||||
bypass_hosts = list(DEFAULT_BYPASS_HOSTS)
|
||||
self._bypass_hosts = load_host_rules(
|
||||
list(bypass_hosts) + list(direct_hosts)
|
||||
)
|
||||
|
||||
# Route YouTube through the relay when requested; the Google frontend
|
||||
# IP can enforce SafeSearch on the SNI-rewrite path.
|
||||
@@ -428,7 +437,7 @@ class ProxyServer:
|
||||
return
|
||||
|
||||
if self._is_bypassed(host):
|
||||
log.info("Bypass tunnel → %s:%d (matches bypass_hosts)", host, port)
|
||||
log.info("Direct tunnel → %s:%d (matches direct_hosts/bypass_hosts)", host, port)
|
||||
await self._do_direct_tunnel(host, port, reader, writer)
|
||||
return
|
||||
|
||||
|
||||
@@ -137,10 +137,9 @@ class DomainFronter:
|
||||
config, "tls_connect_timeout", TLS_CONNECT_TIMEOUT, minimum=1.0,
|
||||
)
|
||||
self._sni_probe_timeout = min(self._tls_connect_timeout, 4.0)
|
||||
self._max_response_body_bytes = self._cfg_int(
|
||||
config, "max_response_body_bytes", MAX_RESPONSE_BODY_BYTES,
|
||||
minimum=1024,
|
||||
)
|
||||
# Keep response cap as a code-level constant to avoid exposing an
|
||||
# advanced memory-safety knob in end-user config.
|
||||
self._max_response_body_bytes = MAX_RESPONSE_BODY_BYTES
|
||||
|
||||
# Connection pool — TTL-based, pre-warmed, with concurrency control
|
||||
self._pool: list[tuple[asyncio.StreamReader, asyncio.StreamWriter, float]] = []
|
||||
@@ -1418,7 +1417,7 @@ class DomainFronter:
|
||||
502,
|
||||
"Relay response exceeds cap "
|
||||
f"({self._max_response_body_bytes} bytes). "
|
||||
"Increase max_response_body_bytes if your system has enough RAM.",
|
||||
"Increase MAX_RESPONSE_BODY_BYTES in src/core/constants.py if your system has enough RAM.",
|
||||
)
|
||||
if min_size > 0 and total_size < min_size:
|
||||
return self._rewrite_206_to_200(first_resp)
|
||||
|
||||
@@ -224,7 +224,7 @@ def parse_relay_json(data: dict, max_body_bytes: int) -> bytes:
|
||||
return error_response(
|
||||
502,
|
||||
f"Relay response exceeds cap ({max_body_bytes} bytes). "
|
||||
"Increase max_response_body_bytes if your system has enough RAM.",
|
||||
"Increase MAX_RESPONSE_BODY_BYTES in src/core/constants.py if your system has enough RAM.",
|
||||
)
|
||||
|
||||
status_text = {
|
||||
|
||||
Reference in New Issue
Block a user