Spaces:
Paused
Paused
Upload 20 files
Browse files- app/main.py +53 -11
- entrypoint.sh +19 -10
app/main.py
CHANGED
|
@@ -278,13 +278,21 @@ def clash_api_proxy(subpath):
|
|
| 278 |
return jsonify({"message": "Authentication required"}), 401
|
| 279 |
|
| 280 |
# 2. 检查Clash是否运行
|
| 281 |
-
if clash_manager is None
|
| 282 |
logger.error(f"Clash API不可用,无法代理请求: {subpath}")
|
| 283 |
return jsonify({
|
| 284 |
"success": False,
|
| 285 |
"error": f"Clash API未运行: {initialization_error or '内部错误'}"
|
| 286 |
}), 503
|
| 287 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
# 3. 构建目标URL
|
| 289 |
target_url = f"http://127.0.0.1:{CLASH_API_PORT}/{subpath}"
|
| 290 |
if request.query_string:
|
|
@@ -294,25 +302,33 @@ def clash_api_proxy(subpath):
|
|
| 294 |
|
| 295 |
# 4. 转发请求
|
| 296 |
try:
|
| 297 |
-
# 准备请求头,移除Host
|
| 298 |
-
req_headers = {
|
|
|
|
|
|
|
|
|
|
| 299 |
|
| 300 |
-
#
|
| 301 |
-
if request.
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
|
| 306 |
# 普通HTTP请求
|
| 307 |
resp = requests.request(
|
| 308 |
method=request.method,
|
| 309 |
url=target_url,
|
| 310 |
headers=req_headers,
|
| 311 |
-
data=
|
| 312 |
cookies=request.cookies,
|
| 313 |
allow_redirects=False,
|
| 314 |
stream=True, # 对于大响应或流式响应
|
| 315 |
-
timeout=
|
| 316 |
)
|
| 317 |
|
| 318 |
# 5. 构建并返回响应
|
|
@@ -376,6 +392,14 @@ def index():
|
|
| 376 |
border: 1px dashed #ccc;
|
| 377 |
background-color: #f9f9f9;
|
| 378 |
}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 379 |
pre {{ max-height: 300px; overflow: auto; background-color: #eee; padding: 10px; border-radius: 4px; }}
|
| 380 |
</style>
|
| 381 |
<script>
|
|
@@ -433,6 +457,24 @@ def index():
|
|
| 433 |
<h2>控制面板</h2>
|
| 434 |
{yacd_link}
|
| 435 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 436 |
<h2>基本操作</h2>
|
| 437 |
<button class="button warning" onclick="requestWithApiKey('/api/refresh')">刷新订阅并重启Clash</button>
|
| 438 |
|
|
|
|
| 278 |
return jsonify({"message": "Authentication required"}), 401
|
| 279 |
|
| 280 |
# 2. 检查Clash是否运行
|
| 281 |
+
if clash_manager is None:
|
| 282 |
logger.error(f"Clash API不可用,无法代理请求: {subpath}")
|
| 283 |
return jsonify({
|
| 284 |
"success": False,
|
| 285 |
"error": f"Clash API未运行: {initialization_error or '内部错误'}"
|
| 286 |
}), 503
|
| 287 |
+
|
| 288 |
+
# 特殊处理 /logs 路径 (这是WebSocket接口,我们不支持)
|
| 289 |
+
if subpath == 'logs':
|
| 290 |
+
logger.info("请求了日志WebSocket接口,但当前版本不支持WebSocket代理")
|
| 291 |
+
return jsonify({
|
| 292 |
+
"success": False,
|
| 293 |
+
"error": "不支持WebSocket日志接口。请使用标准HTTP API。"
|
| 294 |
+
}), 400
|
| 295 |
+
|
| 296 |
# 3. 构建目标URL
|
| 297 |
target_url = f"http://127.0.0.1:{CLASH_API_PORT}/{subpath}"
|
| 298 |
if request.query_string:
|
|
|
|
| 302 |
|
| 303 |
# 4. 转发请求
|
| 304 |
try:
|
| 305 |
+
# 准备请求头,移除Host
|
| 306 |
+
req_headers = {
|
| 307 |
+
k: v for k, v in request.headers.items()
|
| 308 |
+
if k.lower() not in ['host', 'content-length']
|
| 309 |
+
}
|
| 310 |
|
| 311 |
+
# 确保Content-Type正确传递,尤其对PUT请求
|
| 312 |
+
if request.method in ['POST', 'PUT', 'PATCH'] and 'Content-Type' not in req_headers:
|
| 313 |
+
req_headers['Content-Type'] = 'application/json'
|
| 314 |
+
|
| 315 |
+
# 对于PUT请求,确保正确获取请求数据
|
| 316 |
+
if request.method == 'PUT':
|
| 317 |
+
logger.debug(f"处理PUT请求到 {target_url}, 数据: {request.data}")
|
| 318 |
+
req_data = request.get_data()
|
| 319 |
+
else:
|
| 320 |
+
req_data = request.get_data()
|
| 321 |
|
| 322 |
# 普通HTTP请求
|
| 323 |
resp = requests.request(
|
| 324 |
method=request.method,
|
| 325 |
url=target_url,
|
| 326 |
headers=req_headers,
|
| 327 |
+
data=req_data,
|
| 328 |
cookies=request.cookies,
|
| 329 |
allow_redirects=False,
|
| 330 |
stream=True, # 对于大响应或流式响应
|
| 331 |
+
timeout=10 # 缩短超时,防止工作进程卡住
|
| 332 |
)
|
| 333 |
|
| 334 |
# 5. 构建并返回响应
|
|
|
|
| 392 |
border: 1px dashed #ccc;
|
| 393 |
background-color: #f9f9f9;
|
| 394 |
}}
|
| 395 |
+
.note {{
|
| 396 |
+
background-color: #fcf8e3;
|
| 397 |
+
border-left: 4px solid #f0ad4e;
|
| 398 |
+
padding: 10px 15px;
|
| 399 |
+
margin: 10px 0;
|
| 400 |
+
color: #8a6d3b;
|
| 401 |
+
font-size: 14px;
|
| 402 |
+
}}
|
| 403 |
pre {{ max-height: 300px; overflow: auto; background-color: #eee; padding: 10px; border-radius: 4px; }}
|
| 404 |
</style>
|
| 405 |
<script>
|
|
|
|
| 457 |
<h2>控制面板</h2>
|
| 458 |
{yacd_link}
|
| 459 |
|
| 460 |
+
<div class="note">
|
| 461 |
+
<strong>⚠️ 重要提示:</strong>
|
| 462 |
+
<ul>
|
| 463 |
+
<li>首次使用高级控制面板时,您需要在设置中填入:
|
| 464 |
+
<ul>
|
| 465 |
+
<li>外部控制器地址:<code>/clashapi</code></li>
|
| 466 |
+
<li>密钥:<code>changeme</code> (除非您自定义了API_KEY)</li>
|
| 467 |
+
</ul>
|
| 468 |
+
</li>
|
| 469 |
+
<li>当前版本对控制面板有以下限制:
|
| 470 |
+
<ul>
|
| 471 |
+
<li>不支持WebSocket接口,因此日志查看功能不可用</li>
|
| 472 |
+
<li>某些PUT操作可能不稳定,如果遇到问题请刷新页面</li>
|
| 473 |
+
</ul>
|
| 474 |
+
</li>
|
| 475 |
+
</ul>
|
| 476 |
+
</div>
|
| 477 |
+
|
| 478 |
<h2>基本操作</h2>
|
| 479 |
<button class="button warning" onclick="requestWithApiKey('/api/refresh')">刷新订阅并重启Clash</button>
|
| 480 |
|
entrypoint.sh
CHANGED
|
@@ -84,18 +84,27 @@ if [ -z "$API_KEY" ]; then
|
|
| 84 |
fi
|
| 85 |
|
| 86 |
# 启动Flask应用
|
| 87 |
-
echo "${GREEN}Starting Flask application...${NC}"
|
| 88 |
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
|
| 94 |
-
#
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
--bind 0.0.0.0:${FLASK_PORT
|
| 98 |
-
--
|
|
|
|
| 99 |
--access-logfile - \
|
| 100 |
--error-logfile - \
|
|
|
|
|
|
|
| 101 |
app.main:app
|
|
|
|
| 84 |
fi
|
| 85 |
|
| 86 |
# 启动Flask应用
|
| 87 |
+
echo -e "${GREEN}Starting Flask application...${NC}"
|
| 88 |
|
| 89 |
+
if [ -n "$WORKERS" ]; then
|
| 90 |
+
echo "Using $WORKERS workers"
|
| 91 |
+
DEFAULT_WORKERS="$WORKERS"
|
| 92 |
+
else
|
| 93 |
+
# 计算合适的worker数量 (默认根据CPU数量,但最少2个,最多17个)
|
| 94 |
+
DEFAULT_WORKERS=$(($(nproc) * 2 + 1))
|
| 95 |
+
[ $DEFAULT_WORKERS -lt 2 ] && DEFAULT_WORKERS=2
|
| 96 |
+
[ $DEFAULT_WORKERS -gt 17 ] && DEFAULT_WORKERS=17
|
| 97 |
+
echo "Using $DEFAULT_WORKERS workers"
|
| 98 |
+
fi
|
| 99 |
|
| 100 |
+
# 增加超时时间,确保长连接能正常工作
|
| 101 |
+
# 增加记录器配置使错误更容易诊断
|
| 102 |
+
cd /app && gunicorn \
|
| 103 |
+
--bind 0.0.0.0:${FLASK_PORT} \
|
| 104 |
+
--workers ${DEFAULT_WORKERS} \
|
| 105 |
+
--timeout 300 \
|
| 106 |
--access-logfile - \
|
| 107 |
--error-logfile - \
|
| 108 |
+
--capture-output \
|
| 109 |
+
--log-level info \
|
| 110 |
app.main:app
|