# HTTP API 接口文档 本文档根据 `src/http` 下各 handler 的 `handle_request/4` 实现整理。 ## 通用说明 - HTTP 服务端口由应用配置 `sdlan.http_server.port` 决定。 - 响应 `Content-Type` 为 `application/json;charset=utf-8`。 - 当响应体大小大于等于 1024 字节且请求头 `Accept-Encoding` 包含 `gzip` 时,响应会启用 gzip 压缩。 - GET 参数来自 URL query string。 - POST 请求体支持两种格式: - `Content-Type: application/json`:请求体会按 JSON object 解析,数字保持为 JSON number。 - `Content-Type: application/x-www-form-urlencoded`:请求体会按表单解析,参数值为 binary/string;涉及整型参数的接口建议使用 JSON 请求体。 - 统一成功返回格式: ```json { "result": "" } ``` - 统一失败返回格式: ```json { "error": { "code": -1, "message": "错误描述" } } ``` - handler 未匹配到 URL、Method 或参数结构时,通常返回 HTTP 200,并返回如下错误格式: ```json { "error": { "code": -1, "message": "url: /path not found" } } ``` ## binlog_handler 路由配置:`/binlog` ### POST /binlog 接收 binlog 通知,目前只记录请求参数并返回固定结果。 **Method**:`POST` **参数**:无必填参数。请求体可为 JSON object 或 form。 | 参数 | 位置 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | --- | | 任意字段 | body | object/string/number/boolean/array | 否 | 当前实现不读取具体字段,仅打印完整请求体参数。 | **成功返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | result | string | 固定为 `"ok"`。 | 示例: ```json { "result": "ok" } ``` ## test_handler 路由配置:`/test/[...]` ### POST /test/auth_access_token 测试用 access token 校验接口,目前返回固定结果。 **Method**:`POST` **参数**:无必填参数。请求体可为 JSON object 或 form。 | 参数 | 位置 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | --- | | 任意字段 | body | object/string/number/boolean/array | 否 | 当前实现不读取具体字段。 | **成功返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | result | string | 固定为 `"ok"`。 | 示例: ```json { "result": "ok" } ``` ### GET /test/get_all_networks 测试用获取全部网络 ID。 **Method**:`GET` **参数**:无。 **成功返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | result | array<integer> | 网络 ID 列表。当前实现固定返回 `[8]`。 | 示例: ```json { "result": [8] } ``` ### GET /test/get_network 测试用获取单个网络详情。 **Method**:`GET` **参数**: | 参数 | 位置 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | --- | | id | query | string(integer) | 是 | 网络 ID。实现中会通过 `binary_to_integer/1` 转为 integer;当前仅内置 ID `8`。 | **成功返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | result | object | 网络详情对象。 | | result.id | integer | 网络 ID。 | | result.name | string | 网络名称。 | | result.domain | string | 网络域名。 | | result.ipaddr | string | 网络地址段,CIDR 格式。 | | result.owner_id | integer | 所属用户 ID。 | | result.algorithm | string | 加密算法。 | | result.disabled_clients | array<string> | 禁用的客户端 ID 列表。 | 示例: ```json { "result": { "id": 8, "name": "test1", "domain": "punchnet.cn", "ipaddr": "10.211.179.0/24", "owner_id": 1234, "algorithm": "chacha20", "disabled_clients": [] } } ``` ## api_handler 路由配置:`/api/[...]` 注意:当前 `api_handler` 的实现匹配路径为 `/test/auth_token`,但 Cowboy 路由只会把 `/api/[...]` 请求分发给 `api_handler`。因此按当前路由配置,该接口不可达;直接请求 `/test/auth_token` 会被分发到 `test_handler`,也不会命中此实现。 ### POST /test/auth_token 获取测试 auth token 信息,返回第一个网络 ID。 **Method**:`POST` **当前可达性**:不可达,原因见本节说明。 **参数**:无必填参数。请求体可为 JSON object 或 form。 | 参数 | 位置 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | --- | | 任意字段 | body | object/string/number/boolean/array | 否 | 当前实现不读取具体字段,仅打印完整请求体参数。 | **成功返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | result | object | 返回数据对象。 | | result.network_id | integer | `network_bo:get_all_networks/0` 返回列表中的第一个网络 ID。 | 示例: ```json { "result": { "network_id": 8 } } ``` ## network_handler 路由配置:`/network/[...]` ### POST /network/create 启动或确保指定网络已启动。 **Method**:`POST` **参数**: | 参数 | 位置 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | --- | | id | body | integer | 是 | 网络 ID,需大于 0。建议使用 JSON number。 | 请求示例: ```json { "id": 8 } ``` **成功返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | result | string | 固定为 `"success"`。 | 示例: ```json { "result": "success" } ``` **失败返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | error.code | integer | 固定为 `-1`。 | | error.message | string | 固定为 `"error"`。 | ### POST /network/delete 删除指定网络;如果网络未启动,也视为删除成功。 **Method**:`POST` **参数**: | 参数 | 位置 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | --- | | id | body | integer | 是 | 网络 ID,需大于 0。建议使用 JSON number。 | 请求示例: ```json { "id": 8 } ``` **成功返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | result | string | 固定为 `"success"`。 | 示例: ```json { "result": "success" } ``` **失败返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | error.code | integer | 固定为 `-1`。 | | error.message | string | 固定为 `"error"`。 | ### POST /network/exit_node_control 向指定客户端下发出口节点控制命令,并等待客户端 ACK。 **Method**:`POST` **参数**: | 参数 | 位置 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | --- | | id | body | integer | 是 | 网络 ID,需大于 0。建议使用 JSON number。 | | action | body | integer | 是 | 出口节点动作,传入 `SDLCommand.ExitNodeControl.action`。历史文档约定:`0` 表示关闭,`1` 表示开启。 | | client_id | body | string | 是 | 目标客户端 ID。 | | remark | body | string | 是 | 下发备注,用于跟踪命令;可传空字符串。 | | timeout | body | integer | 是 | 等待 ACK 的超时时间,单位秒。实现中会转换为毫秒。 | 请求示例: ```json { "id": 8, "action": 1, "client_id": "client-id", "remark": "trace remark", "timeout": 10 } ``` **成功返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | result | string | 正常 ACK 时固定为 `"success"`。 | 示例: ```json { "result": "success" } ``` **其他返回**: | 场景 | 返回格式 | 字段类型 | 说明 | | --- | --- | --- | --- | | 网络不存在 | `{"result":"network not found"}` | result: string | 当前实现将网络不存在作为 result 返回,而不是 error。 | | 命令发送失败 | `{"error":{"code":-1,"message":"..."}}` | code: integer, message: string | message 为底层返回的 Reason,需为可 JSON 编码值。 | | 客户端 ACK 失败 | `{"error":{"code":,"message":""}}` | code: integer, message: string | Code 和 Message 来自 `SDLCommandAck`。 | | 等待 ACK 超时 | `{"error":{"code":-1,"message":"任务执行超时"}}` | code: integer, message: string | 超过 `timeout` 秒未收到 ACK。 | ## node_handler 路由配置:`/node/[...]` ### POST /node/disable 禁用指定网络中的客户端节点。 **Method**:`POST` **参数**: | 参数 | 位置 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | --- | | network_id | body | integer | 是 | 网络 ID,需大于 0。建议使用 JSON number。 | | client_id | body | string | 是 | 客户端 ID。 | 请求示例: ```json { "network_id": 8, "client_id": "client-id" } ``` **成功返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | result | string | 固定为 `"success"`。 | 示例: ```json { "result": "success" } ``` **失败返回**: | 字段 | 类型 | 说明 | | --- | --- | --- | | error.code | integer | 固定为 `-1`。 | | error.message | string | 当前实现中网络不存在时为 `"network not found"`。 |