mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-10 17:23:25 +08:00
完成 WebSocket 与 workspace 架构优化收尾,并修复全量回归阻塞。
本次将握手鉴权、Origin 校验、限流、重连补偿、发送背压与观测字段打通,同时修复 gateway 异常路径与备份清理兼容问题,确保工具历史压缩语义一致并恢复全量测试通过。 Made-with: Cursor
This commit is contained in:
parent
09836dddfa
commit
7253f6795d
12 changed files with 536 additions and 24 deletions
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import os
|
||||
import time
|
||||
from typing import Any
|
||||
|
||||
|
|
@ -11,6 +12,15 @@ MAX_PAYLOAD_BYTES = 26_214_400
|
|||
MAX_BUFFERED_BYTES = 52_428_800
|
||||
TICK_INTERVAL_MS = 15_000
|
||||
PREAUTH_HANDSHAKE_TIMEOUT_MS = 15_000
|
||||
WS_REQUIRE_AUTH = str(os.getenv("OCLAW_WS_REQUIRE_AUTH") or "1").strip().lower() not in ("0", "false", "no", "off")
|
||||
WS_ALLOWED_ORIGINS = [s.strip() for s in str(os.getenv("OCLAW_WS_ALLOWED_ORIGINS") or "").split(",") if s.strip()]
|
||||
WS_RATE_LIMIT_WINDOW_MS = int(os.getenv("OCLAW_WS_RATE_LIMIT_WINDOW_MS") or "60000")
|
||||
WS_RATE_LIMIT_CONN_PER_WINDOW = int(os.getenv("OCLAW_WS_RATE_LIMIT_CONN_PER_WINDOW") or "120")
|
||||
WS_RATE_LIMIT_IP_PER_WINDOW = int(os.getenv("OCLAW_WS_RATE_LIMIT_IP_PER_WINDOW") or "240")
|
||||
WS_RATE_LIMIT_USER_PER_WINDOW = int(os.getenv("OCLAW_WS_RATE_LIMIT_USER_PER_WINDOW") or "360")
|
||||
WS_SEND_QUEUE_MAX_MESSAGES = int(os.getenv("OCLAW_WS_SEND_QUEUE_MAX_MESSAGES") or "256")
|
||||
WS_SEND_QUEUE_MAX_BYTES = int(os.getenv("OCLAW_WS_SEND_QUEUE_MAX_BYTES") or str(MAX_BUFFERED_BYTES))
|
||||
WS_EVENT_REPLAY_MAX = int(os.getenv("OCLAW_WS_EVENT_REPLAY_MAX") or "256")
|
||||
|
||||
|
||||
def now_ms() -> int:
|
||||
|
|
@ -24,6 +34,20 @@ def error_shape(code: str, message: str, *, details: Any | None = None) -> dict[
|
|||
return out
|
||||
|
||||
|
||||
def origin_is_allowed(origin: str | None, host: str | None) -> bool:
|
||||
value = str(origin or "").strip()
|
||||
if not value:
|
||||
return True
|
||||
allowlist = list(WS_ALLOWED_ORIGINS)
|
||||
if allowlist:
|
||||
return value in allowlist
|
||||
host_value = str(host or "").strip()
|
||||
if not host_value:
|
||||
return False
|
||||
lower = value.lower()
|
||||
return lower.startswith(f"https://{host_value.lower()}") or lower.startswith(f"http://{host_value.lower()}")
|
||||
|
||||
|
||||
def decode_base64_payload_ws(s: str | None) -> bytes | None:
|
||||
raw = str(s or "").strip()
|
||||
if not raw:
|
||||
|
|
@ -73,8 +97,18 @@ __all__ = [
|
|||
"MAX_BUFFERED_BYTES",
|
||||
"TICK_INTERVAL_MS",
|
||||
"PREAUTH_HANDSHAKE_TIMEOUT_MS",
|
||||
"WS_REQUIRE_AUTH",
|
||||
"WS_ALLOWED_ORIGINS",
|
||||
"WS_RATE_LIMIT_WINDOW_MS",
|
||||
"WS_RATE_LIMIT_CONN_PER_WINDOW",
|
||||
"WS_RATE_LIMIT_IP_PER_WINDOW",
|
||||
"WS_RATE_LIMIT_USER_PER_WINDOW",
|
||||
"WS_SEND_QUEUE_MAX_MESSAGES",
|
||||
"WS_SEND_QUEUE_MAX_BYTES",
|
||||
"WS_EVENT_REPLAY_MAX",
|
||||
"now_ms",
|
||||
"error_shape",
|
||||
"origin_is_allowed",
|
||||
"decode_base64_payload_ws",
|
||||
"normalize_ws_attachments",
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue