beautified some ui
This commit is contained in:
@@ -286,6 +286,84 @@ https://videoservice.d1kt.cn/admin
|
||||
不要硬编码进公开代码仓库。SDK 会在评分请求中发送 `X-Client-Key`。公开视频列表和播放
|
||||
接口仍可交给 CDN 缓存,GPU 评分接口则受到密钥保护。
|
||||
|
||||
### 4A. 如果要在服务器本机终结 HTTPS(可选)
|
||||
|
||||
若总出口不做 TLS 终结,而是由服务器本机 nginx 提供 HTTPS,443 的 `server` 块必须
|
||||
包含与 80 块相同的上传相关指令,否则大文件上传会被掐断:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name videoservice.d1kt.cn;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/videoservice.d1kt.cn/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/videoservice.d1kt.cn/privkey.pem;
|
||||
|
||||
client_max_body_size 12g;
|
||||
client_body_timeout 7200s;
|
||||
send_timeout 7200s;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_request_buffering off;
|
||||
proxy_read_timeout 7200s;
|
||||
proxy_send_timeout 7200s;
|
||||
}
|
||||
|
||||
location ~ "^/api/v1/videos/[0-9a-fA-F]{64}/content$" {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Range $http_range;
|
||||
proxy_set_header If-Range $http_if_range;
|
||||
proxy_force_ranges on;
|
||||
proxy_buffering off;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
签发证书并应用:
|
||||
|
||||
```bash
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
sudo certbot --nginx -d videoservice.d1kt.cn
|
||||
```
|
||||
|
||||
### 4B. 上传中断(ClientDisconnect)排查
|
||||
|
||||
后台日志出现 `starlette.requests.ClientDisconnect` 表示浏览器到后端之间某处的连接在
|
||||
请求体传完之前被断开。先确认实际生效的 nginx 配置:
|
||||
|
||||
```bash
|
||||
sudo nginx -T | grep -E "client_max_body_size|client_body_timeout|proxy_request_buffering"
|
||||
```
|
||||
|
||||
最常见的原因是新加的 HTTPS `server` 块漏掉了上传指令:nginx 默认
|
||||
`client_max_body_size` 只有 1 MB,超过会直接返回 413 并断开连接,后端表现为
|
||||
`ClientDisconnect`。其他常见原因:
|
||||
|
||||
- 总出口(网关/CDN)有更小的请求体大小或更短的上传超时,需在网关侧放行。
|
||||
- `client_body_timeout`(默认 60s)过短:网络慢时上传暂停过久会被掐断,按上文设
|
||||
为 7200s。
|
||||
- 浏览器/客户端主动取消或网络中断。
|
||||
|
||||
绕过网关在本机回源验证(能通则问题在网关):
|
||||
|
||||
```bash
|
||||
curl -X PUT -H 'Host: videoservice.d1kt.cn' -H "X-Admin-Key: $ADMIN_KEY" \
|
||||
--data-binary @large.mp4 \
|
||||
'http://127.0.0.1/api/v1/admin/videos/raw?filename=large.mp4' \
|
||||
-o /dev/null -w '%{http_code}\n'
|
||||
```
|
||||
|
||||
API 已对 `ClientDisconnect` 做优雅处理:连接中断时返回 400 并记录一条 WARNING,
|
||||
不再产生 500 堆栈日志。
|
||||
|
||||
## 5. 上传与处理流程
|
||||
|
||||
后台上传后,服务会:
|
||||
|
||||
@@ -22,6 +22,7 @@ from fastapi import (
|
||||
from fastapi.responses import FileResponse, Response
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from starlette.concurrency import run_in_threadpool
|
||||
from starlette.requests import ClientDisconnect
|
||||
|
||||
from .assessment import AssessmentService
|
||||
from .audio_metrics import AudioAnalysisError
|
||||
@@ -96,6 +97,14 @@ def create_app(
|
||||
if static_dir.is_dir():
|
||||
application.mount("/static", StaticFiles(directory=static_dir), name="static")
|
||||
|
||||
@application.exception_handler(ClientDisconnect)
|
||||
async def handle_client_disconnect(request: Request, exc: ClientDisconnect) -> Response:
|
||||
logger.warning(
|
||||
"Upload interrupted: the client or an intermediate proxy closed the "
|
||||
"connection before the request body completed."
|
||||
)
|
||||
return Response(status_code=400, content="Upload connection was interrupted.")
|
||||
|
||||
def require_admin(x_admin_key: Optional[str] = Header(default=None)) -> None:
|
||||
expected = service_settings.admin_api_key
|
||||
if expected and not hmac.compare_digest(x_admin_key or "", expected):
|
||||
|
||||
Reference in New Issue
Block a user