Skip to content

工作流程

本文档介绍 PostForwarder 接收、处理并转发请求的完整流程。

整体流程

手机端 ──POST──> http://<电脑IP>:1403/任意路径
  body: from=10329362791&content=%7B%22id%22%3A%22message%22...%7D


          PostForwarder 提取 content= 后的内容
          URL 解码:%7B → {、%22 → "、%E7%9F%AD%E4%BF%A1 → 短信


          POST http://127.0.0.1:47300/api/activities
          body: {"id":"message","title":"10329362791","kind":"短信"}
          Content-Type: application/json; charset=utf-8


          目标服务返回响应 → 原样回传给手机端

详细步骤

1. 接收请求

PostForwarder 在 0.0.0.0:<端口> 上监听所有网卡的请求。支持以下 HTTP 方法:

  • GET
  • POST
  • PUT
  • DELETE
  • PATCH

虽然支持所有方法,但主要设计用于处理 POST 请求。

2. IP 白名单校验

收到请求后,首先检查来源 IP 是否在白名单中:

  • 在白名单中:继续处理
  • 不在白名单中:返回 403 Forbidden
json
{
  "error": "forbidden",
  "detail": "IP 192.168.1.200 not in whitelist"
}

安全提示

白名单留空时,所有请求都会被拒绝。请务必将手机 IP 加入白名单。

3. 提取并解码 content 字段

程序读取请求体,查找 content= 参数:

  1. 使用 parse_qs 解析 application/x-www-form-urlencoded 格式的请求体
  2. 提取 content 字段的值
  3. parse_qs 会自动完成 URL 解码:
    • %7B{
    • %22"
    • %E7%9F%AD%E4%BF%A1短信

解码完成后,将 Content-Type 设置为 application/json; charset=utf-8,准备转发。

解析失败

如果请求体解析失败(例如不是 URL 编码格式),程序会原样转发请求体,不进行解码。

4. 转发到目标服务

将处理后的请求转发到固定目标地址 http://127.0.0.1:47300/api/activities

  • 请求方法:与原始请求相同
  • 请求头:去掉 hop-by-hop 头(connection、host、content-length 等)
  • 请求体:解码后的 content 内容
  • 超时:30 秒
  • 不跟随重定向

5. 回传响应

目标服务的响应会被原样回传给手机端:

  • 状态码:保持目标服务返回的状态码
  • 响应头:去掉 hop-by-hop 和 content-encoding 头
  • 响应体:原样返回

日志示例

正常转发

[14:23:01] [INFO] 服务已启动  监听 0.0.0.0:1403  转发 -> http://127.0.0.1:47300/api/activities  白名单IP: 192.168.1.100
[14:23:15] [INFO] [收到] POST /sms  来源 192.168.1.100  body=from=10329362791&content=%7B%22id%22%3A...
[14:23:15] [ OK ] [提取content] 已URL解码,转发内容={"id":"message","title":"10329362791",...}
[14:23:15] [ OK ] [转发] POST /sms -> http://127.0.0.1:47300/api/activities  状态 200  resp={"status":"ok"}

非白名单 IP

[14:24:00] [WARN] [拒绝] 来源 IP 192.168.1.200 不在白名单

转发失败

[14:25:30] [ERR ] [转发失败] http://127.0.0.1:47300/api/activities -> HTTPConnectionPool(host='127.0.0.1', port=47300): Max retries exceeded

基于 VitePress 构建