v2.5.6: fix 404 after update without tunnel

This commit is contained in:
orohi
2026-07-28 11:00:34 +03:00
parent 2808a49fa5
commit ff7cc5c592
5 changed files with 95 additions and 24 deletions
+47 -4
View File
@@ -29,7 +29,8 @@ from fastapi.responses import JSONResponse, RedirectResponse, HTMLResponse, Stre
from starlette.background import BackgroundTask
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi import FastAPI, Request, Query, UploadFile, File
from fastapi import FastAPI, Request, Query, UploadFile, File, HTTPException
from starlette.exceptions import HTTPException as StarletteHTTPException
from starlette.middleware.sessions import SessionMiddleware
from pydantic import BaseModel
from typing import Optional, List, Dict
@@ -102,7 +103,7 @@ else:
application_path = os.path.dirname(__file__)
DATA_FILE = os.path.join(application_path, 'data.json') # legacy JSON; used only for one-shot import / export
CURRENT_VERSION = "v2.5.5"
CURRENT_VERSION = "v2.5.6"
RELEASES_REPO_URL = repo_url()
RELEASES_API_LATEST = api_latest_url()
BIN_DIR = os.environ.get('TUNNEL_BIN_DIR', os.path.join(application_path, 'bin'))
@@ -278,6 +279,48 @@ def get_panel_tunnel_target_url():
return f"{scheme}://127.0.0.1:{port}"
def get_panel_public_url(request: Optional[Request] = None) -> str:
if request is not None:
forwarded_proto = (request.headers.get('x-forwarded-proto') or '').split(',')[0].strip()
scheme = forwarded_proto or request.url.scheme or 'http'
host = (
(request.headers.get('x-forwarded-host') or '').split(',')[0].strip()
or request.headers.get('host')
or request.url.netloc
)
if host:
return f"{scheme}://{host}/"
return get_panel_local_url(request).rstrip('/') + '/'
def enrich_update_result(request: Request, result: dict) -> dict:
result['panel_url'] = get_panel_public_url(request)
return result
@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request: Request, exc: StarletteHTTPException):
if exc.status_code != 404:
detail = exc.detail if isinstance(exc.detail, str) else 'Error'
if request.url.path.startswith('/api/'):
return JSONResponse({'error': detail}, status_code=exc.status_code)
return HTMLResponse(f'<h1>{exc.status_code}</h1><p>{detail}</p>', status_code=exc.status_code)
if request.url.path.startswith('/api/') or 'application/json' in (request.headers.get('accept') or '').lower():
return JSONResponse({'error': 'Not found'}, status_code=404)
home = get_panel_public_url(request)
return HTMLResponse(
f'''<!DOCTYPE html><html><head><meta charset="utf-8"><title>Amnezia Panel</title></head>
<body style="font-family:sans-serif;max-width:520px;margin:3rem auto;padding:0 1rem;">
<h1>Страница не найдена</h1>
<p>Адрес <code>{request.url.path}</code> не существует в панели.</p>
<p>Если вы только что обновили панель, подождите 1030 секунд и откройте:</p>
<p><a href="{home}">{home}</a></p>
<p><a href="/health">/health</a> проверка, что панель запущена.</p>
</body></html>''',
status_code=404,
)
@app.get('/health', include_in_schema=False)
@app.get('/api/health', include_in_schema=False)
async def health_check():
@@ -6009,7 +6052,7 @@ async def api_apply_update(request: Request, req: ApplyUpdateRequest):
if result.get('restart'):
UpdateManager.schedule_restart(application_path, 1.5)
return result
return enrich_update_result(request, result)
@app.post('/api/settings/upgrade_panel', tags=["Settings"])
@@ -6049,7 +6092,7 @@ async def api_upgrade_panel(request: Request):
UpdateManager.schedule_restart(application_path, 1.5)
result['up_to_date'] = False
result['previous_version'] = CURRENT_VERSION
return result
return enrich_update_result(request, result)
@app.get('/api/settings/tunnels/status', tags=["Settings"])