ahserver/aidocs/p2p_middleware.md
2025-10-05 12:07:12 +08:00

7.0 KiB
Raw Blame History

以下是为提供的 Python 代码编写的 Markdown 格式技术文档,涵盖了类的功能、依赖、中间件逻辑以及各方法的说明。


P2pLayer 技术文档

概述

P2pLayer 是一个基于 aiohttp 的中间件组件,用于在 Web 请求处理流程中集成点对点P2P加密通信功能。该模块通过条件启用 P2P 加密层,并在请求/响应过程中实现握手、解码和编码操作,以保障通信安全。

此模块依赖于 p2psc 库中的 PubkeyHandlerP2psc 类,实现公钥管理和端到端加密逻辑。


依赖项

  • aiohttp:异步 HTTP 客户端/服务器框架。
  • p2psc.pubkey_handler.PubkeyHandler:负责管理本地公钥与远程节点身份认证。
  • p2psc.p2psc.P2psc:核心 P2P 安全通信类,支持加密握手与数据加解密。
  • getConfig():全局配置获取函数(外部定义,需确保可用)。

⚠️ 注意:getConfig() 函数未在此文件中定义,应由项目其他部分提供,返回包含配置树的对象。


类定义

class P2pLayer

功能

P2pLayer 封装了 P2P 加密通信的初始化与中间件逻辑。根据配置决定是否启用加密传输,并在启用时拦截请求/响应流进行加解密处理。


初始化 (__init__)

def __init__(self)

描述

初始化 P2pLayer 实例并根据配置决定是否启用 P2P 加密功能。

流程

  1. 初始化 self.p2pcrypt = False
  2. 调用 getConfig() 获取系统配置。
  3. 检查配置项 config.website.p2pcrypt
    • 若为 True,则启用 P2P 加密(设置 self.p2pcrypt = True),并初始化相关组件;
    • 否则跳过初始化,后续中间件将直接透传请求。
  4. 如果启用了加密:
    • 创建 PubkeyHandler 实例用于密钥管理;
    • 使用 handler 及其自身 ID 初始化 P2psc 实例。

属性

属性 类型 说明
p2pcrypt bool 是否启用 P2P 加密模式
handler PubkeyHandler 公钥处理器,管理本地/远程身份
p2p P2psc P2P 安全通信核心实例

提示:仅当 p2pcryptTrue 时,handlerp2p 才会被创建。


中间件:p2p_middle

@web.middleware
async def p2p_middle(self, request, handler)

描述

Aiohttp 异步中间件,用于拦截进入的 HTTP 请求并执行 P2P 加密相关处理。

执行逻辑

条件 行为
not self.p2pcrypt 直接调用原始 handler不进行任何加密处理
请求头含 P2pHandShake 调用 self.p2p_handshake(request) 进行密钥交换
请求头含 P2pdata 解密请求 → 处理 → 加密响应
其他情况 直接调用 handler明文通行

详细流程

开始
│
├─ 是否禁用 p2pcrypt
│    └─ 是 → 直接返回 handler(request)
│
├─ 是否存在 "P2pHandShake" 头?
│    └─ 是 → 返回 await p2p_handshake(request)
│
├─ 是否存在 "P2pdata" 头?
│    ├─ 是 → 
│    │     1. await p2p_decode_request(request)
│    │     2. resp = await handler(decoded_request)
│    │     3. return await p2p_encode_response(resp)
│
└─ 默认 → 返回 await handler(request)

注意事项

  • 当前代码存在拼写错误:
    • if not p2pscrypr: → 应为 if not self.p2pcrypt:
    • resturen → 应为 return
    • request.header.get → 应为 request.headers.get
  • 正确代码应如下:
@web.middleware
async def p2p_middle(self, request, handler):
    if not self.p2pcrypt:
        return await handler(request)

    if request.headers.get('P2pHandShake', None):
        return await self.p2p_handshake(request)

    if request.headers.get('P2pdata', None):
        request = await self.p2p_decode_request(request)
        resp = await handler(request)
        return await self.p2p_encode_response(resp)

    return await handler(request)

方法说明

p2p_handshake(request)

async def p2p_handshake(self, request)

描述

处理客户端发起的 P2P 安全握手请求(如密钥交换)。当前为空实现(pass),需子类或后续扩展完成具体协议逻辑。

参数

  • request (aiohttp.web.Request)HTTP 请求对象

返回值

  • 通常应返回 aiohttp.web.Response 对象,携带握手响应数据(如公钥、会话密钥等)

示例场景

  • TLS-like 密钥协商
  • Diffie-Hellman 或 Noise 协议集成

p2p_decode_request(request)

async def p2p_decode_request(self, request)

描述

对接收到的加密请求体进行解密和解析,还原为标准 request 对象。

参数

  • request:携带加密数据的原始请求

返回值

  • 解密后的 request 对象(可能包装新 body 或附加上下文字段)

待实现内容

  • 读取请求体
  • 使用 self.p2p.decrypt() 解密
  • 重构 JSON/body 数据
  • 替换 request._payload 或使用自定义 Request 子类

p2p_encode_response(response)

async def p2p_encode_response(self, response)

描述

将正常的 HTTP 响应内容加密后封装,返回给客户端。

参数

  • response (aiohttp.web.Response):原始响应对象

返回值

  • 加密后的响应对象(通常修改 body 并添加头部如 Content-Encoding: p2p

当前实现

return response

🔴 当前为占位实现,未实际加密。需要补充:

  • 序列化响应内容
  • 使用 self.p2p.encrypt() 加密
  • 设置 Content-Type 或自定义头标识加密类型
  • 构造新的 StreamResponseResponse 返回

配置要求

确保配置结构中包含以下字段:

config = {
    "website": {
        "p2pcrypt": True  # 或 False控制是否启用 P2P 加密
    }
}

可通过环境变量、YAML 文件或其他方式加载。


使用示例(伪代码)

app = web.Application(middlewares=[p2player.p2p_middle])
p2player = P2pLayer()
web.run_app(app)

已知问题 / 待修复 Bug

问题 位置 说明
拼写错误 p2pscrypr 第10行 应为 self.p2pcrypt
resturen 错误 第12行 应为 return
request.header.headers 第15行 属性名错误
p2p_handshake 无实现 第20行 需补充握手逻辑
加解密方法为空 第2429行 仅为骨架,需具体实现

总结

P2pLayer 提供了一个可插拔的 P2P 加密通信中间件框架,适用于需要端到端安全传输的去中心化 Web 服务。虽然目前大部分功能尚未实现,但其设计清晰,具备良好的扩展性。

建议下一步:

  • 修复语法错误
  • 实现握手与加解密逻辑
  • 添加单元测试与集成测试
  • 支持超时、重试、会话缓存等机制

📌 版本信息v0.1(草案)
📅 最后更新2025-04-05