This commit is contained in:
anlicheng 2026-04-27 15:38:50 +08:00
parent 342b27211d
commit d353cf8bef

386
docs/api.md Normal file
View File

@ -0,0 +1,386 @@
# HTTP API 接口文档
本文档根据 `src/http_handler` 下各 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": "<any>"
}
```
- 统一失败返回格式:
```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&lt;integer&gt; | 网络 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&lt;string&gt; | 禁用的客户端 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":<Code>,"message":"<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"`。 |