上传文件至「lite」
This commit is contained in:
+25
-11
@@ -228,17 +228,15 @@ def _start_pac_server(pac_content: str) -> int:
|
|||||||
return port
|
return port
|
||||||
|
|
||||||
def _stop_pac_server():
|
def _stop_pac_server():
|
||||||
"""停止本地 PAC HTTP 服务;shutdown() 可能阻塞,因此先关闭 socket 再异步收尾。"""
|
"""停止本地 PAC HTTP 服务;shutdown() 唤醒 serve_forever 后优雅退出。"""
|
||||||
global _pac_server
|
global _pac_server
|
||||||
if _pac_server:
|
if _pac_server:
|
||||||
srv = _pac_server["server"]
|
srv = _pac_server["server"]
|
||||||
_pac_server = None
|
_pac_server = None
|
||||||
try:
|
# 不要直接 close socket:serve_forever 的 select 仍注册着它,Windows 上
|
||||||
# 先关闭 socket,让 serve_forever() 从 select/accept 中立即退出
|
# 对已关闭 socket 做 select 会抛 WinError 10038(非套接字操作)。
|
||||||
srv.socket.close()
|
# shutdown() 让 select 在 poll_interval(0.5s)内返回并正常退出。
|
||||||
except Exception:
|
srv.daemon_threads = True # 请求处理线程不阻塞 serve_forever 退出
|
||||||
pass
|
|
||||||
# 在后台线程里尝试优雅 shutdown,最多等 1 秒,避免阻塞 GUI
|
|
||||||
def _shutdown():
|
def _shutdown():
|
||||||
try:
|
try:
|
||||||
srv.shutdown()
|
srv.shutdown()
|
||||||
@@ -390,7 +388,20 @@ def _tls_start(remote_host, remote_port=443, use_tls=True, bypass_lan=False, sma
|
|||||||
|
|
||||||
svr = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
svr = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
svr.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
svr.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
svr.bind(("127.0.0.1", _TLS_LOCAL_PORT))
|
# Windows 上 Hyper-V/WSL 的端口保留区间会动态变动,bind 可能瞬时被拒
|
||||||
|
# (WinError 10013/10048);重试 3 次,间隔 1 秒
|
||||||
|
last_err = None
|
||||||
|
for attempt in range(3):
|
||||||
|
try:
|
||||||
|
svr.bind(("127.0.0.1", _TLS_LOCAL_PORT))
|
||||||
|
break
|
||||||
|
except OSError as e:
|
||||||
|
last_err = e
|
||||||
|
if attempt < 2:
|
||||||
|
log(f"端口 {_TLS_LOCAL_PORT} 绑定失败: {e},1 秒后重试 ({attempt + 1}/3)")
|
||||||
|
time.sleep(1)
|
||||||
|
else:
|
||||||
|
raise last_err
|
||||||
svr.listen(32)
|
svr.listen(32)
|
||||||
svr.settimeout(1)
|
svr.settimeout(1)
|
||||||
_tls_forwarder = {"sock": svr, "running": True}
|
_tls_forwarder = {"sock": svr, "running": True}
|
||||||
@@ -1183,13 +1194,16 @@ class MainWindow(QWidget):
|
|||||||
self._proxy_set_by_us = True # 标记系统代理由本程序设置,退出时据此清理
|
self._proxy_set_by_us = True # 标记系统代理由本程序设置,退出时据此清理
|
||||||
log("验证代理连通性...")
|
log("验证代理连通性...")
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
# 显式 ProxyHandler 强制经本地转发器;默认 opener 会套用系统/环境代理
|
||||||
|
# 设置(PAC 模式下注册表 ProxyEnable=0,urllib 认为无代理而绕开),造成假"可达"
|
||||||
|
opener = urllib.request.build_opener(
|
||||||
|
urllib.request.ProxyHandler({"http": f"{PROXY_HOST}:{PROXY_PORT}",
|
||||||
|
"https": f"{PROXY_HOST}:{PROXY_PORT}"}))
|
||||||
# baidu 验证国内直连路径,google 验证境外隧道路径
|
# baidu 验证国内直连路径,google 验证境外隧道路径
|
||||||
test_urls = [("baidu.com", "http://www.baidu.com"), ("google.com", "http://www.google.com")]
|
test_urls = [("baidu.com", "http://www.baidu.com"), ("google.com", "http://www.google.com")]
|
||||||
for name, url in test_urls:
|
for name, url in test_urls:
|
||||||
try:
|
try:
|
||||||
req = urllib.request.Request(url)
|
opener.open(url, timeout=10)
|
||||||
req.set_proxy(f"{PROXY_HOST}:{PROXY_PORT}", "http")
|
|
||||||
urllib.request.urlopen(req, timeout=10)
|
|
||||||
log(f" {name} 可达")
|
log(f" {name} 可达")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log(f" {name} 不可达: {e}")
|
log(f" {name} 不可达: {e}")
|
||||||
|
|||||||
Reference in New Issue
Block a user