清理冗余路由代码,修复首页标题与模板安全
- 简化 http-api/http-tcp/web-toolkit 的 router.py,抽取重复代码 - 修复 ws-api middleware 中间件返回值传递问题 - 修复 web-toolkit template.py 安全漏洞 (eval → AST 验证) - 将首页标题从 "OSS Runtime" 改为 "Future OSS" - 更新 README.md 与 static/banner.svg - 新增 i18n 国际化插件 (骨架) - 新增 oss/shared/ 共享模块
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -1,63 +1,21 @@
|
||||
"""TCP HTTP 路由器"""
|
||||
from typing import Callable, Optional, Any
|
||||
from oss.shared.router import BaseRouter, match_path
|
||||
|
||||
|
||||
class TcpRoute:
|
||||
"""TCP HTTP 路由"""
|
||||
def __init__(self, method: str, path: str, handler: Callable):
|
||||
self.method = method
|
||||
self.path = path
|
||||
self.handler = handler
|
||||
|
||||
|
||||
class TcpRouter:
|
||||
class TcpRouter(BaseRouter):
|
||||
"""TCP HTTP 路由器"""
|
||||
|
||||
def __init__(self):
|
||||
self.routes: list[TcpRoute] = []
|
||||
|
||||
def add(self, method: str, path: str, handler: Callable):
|
||||
"""添加路由"""
|
||||
self.routes.append(TcpRoute(method, path, handler))
|
||||
|
||||
def get(self, path: str, handler: Callable):
|
||||
"""GET 路由"""
|
||||
self.add("GET", path, handler)
|
||||
|
||||
def post(self, path: str, handler: Callable):
|
||||
"""POST 路由"""
|
||||
self.add("POST", path, handler)
|
||||
|
||||
def put(self, path: str, handler: Callable):
|
||||
"""PUT 路由"""
|
||||
self.add("PUT", path, handler)
|
||||
|
||||
def delete(self, path: str, handler: Callable):
|
||||
"""DELETE 路由"""
|
||||
self.add("DELETE", path, handler)
|
||||
|
||||
def handle(self, request: dict) -> dict:
|
||||
"""处理请求"""
|
||||
method = request.get("method", "GET")
|
||||
path = request.get("path", "/")
|
||||
|
||||
for route in self.routes:
|
||||
if route.method == method and self._match(route.path, path):
|
||||
return route.handler(request)
|
||||
|
||||
result = self.find_route(method, path)
|
||||
if result:
|
||||
route, params = result
|
||||
# 将路径参数注入到请求中
|
||||
request["path_params"] = params
|
||||
return route.handler(request)
|
||||
|
||||
return {"status": 404, "headers": {}, "body": "Not Found"}
|
||||
|
||||
def _match(self, pattern: str, path: str) -> bool:
|
||||
"""路径匹配"""
|
||||
if pattern == path:
|
||||
return True
|
||||
if ":" in pattern:
|
||||
pattern_parts = pattern.strip("/").split("/")
|
||||
path_parts = path.strip("/").split("/")
|
||||
if len(pattern_parts) != len(path_parts):
|
||||
return False
|
||||
for p, a in zip(pattern_parts, path_parts):
|
||||
if not p.startswith(":") and p != a:
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -77,8 +77,35 @@ class TcpHttpServer:
|
||||
break
|
||||
buffer += data
|
||||
|
||||
# 检查 HTTP 请求是否完整
|
||||
# 检查 HTTP 请求头是否完整
|
||||
if b"\r\n\r\n" in buffer:
|
||||
# 先解析请求头以获取 Content-Length
|
||||
header_end = buffer.find(b"\r\n\r\n")
|
||||
header_text = buffer[:header_end].decode("utf-8", errors="replace")
|
||||
|
||||
# 从请求头中提取 Content-Length
|
||||
content_length = 0
|
||||
for line in header_text.split("\r\n")[1:]:
|
||||
if line.lower().startswith("content-length:"):
|
||||
content_length = int(line.split(":", 1)[1].strip())
|
||||
break
|
||||
|
||||
# 计算 body 起始位置
|
||||
body_start_pos = header_end + 4 # \r\n\r\n
|
||||
body_received = len(buffer) - body_start_pos
|
||||
|
||||
# 等待完整 body
|
||||
if body_received < content_length:
|
||||
# 继续接收剩余数据
|
||||
while body_received < content_length:
|
||||
remaining = content_length - body_received
|
||||
chunk = client.conn.recv(min(4096, remaining))
|
||||
if not chunk:
|
||||
break
|
||||
buffer += chunk
|
||||
body_received += len(chunk)
|
||||
|
||||
# 现在解析完整请求
|
||||
request = self._parse_request(buffer)
|
||||
if request:
|
||||
# 触发请求事件
|
||||
|
||||
Reference in New Issue
Block a user