EchoAPI 是一个用于API测试的HTTP工具,包含HTTP客户端和服务端。服务端可以根据请求header中的字段匹配对应的响应报文并返回,支持用例管理和批量重放。
- HTTP服务端: 接收请求,根据
X-Case-IDheader匹配对应的响应 - HTTP客户端: 发送请求,支持指定case-id,以BurpSuite风格展示完整HTTP报文
- 用例管理: 支持两种格式管理请求-响应对
- YAML格式:结构化格式,易于编辑
- 原始HTTP格式:每个用例一个文件,请求部分可直接复制到BurpSuite
- 灵活配置: 支持各种HTTP方法、路径、请求头和响应体
- Docker支持: 提供Docker Compose配置,快速构建测试环境
pip install -r requirements.txt# 使用默认配置(自动加载cases.yaml和cases/文件夹)
python server.py
# 指定IP和端口
python server.py --host 127.0.0.1 --port 8080
# 指定用例配置文件
python server.py --cases my_cases.yaml
# 启用调试模式
python server.py --debug服务端默认运行在 http://0.0.0.0:23941
单个用例请求:
# 发送GET请求(使用默认服务器 localhost:23941)
# 如果不指定method和path,会自动从用例文件中读取
python client.py case1
# 指定服务器IP和端口
# 可以直接读取 cases.yaml 中的 case ; 以及 cases 文件夹下的 example
python client.py case1 --host 192.168.1.100 --port 8080
python client.py example1 --host 192.168.1.100 --port 8080
# 手动指定请求参数(会覆盖用例文件中的配置)
python client.py case1 --method GET --path /api/users
# 发送POST请求
python client.py case2 --method POST --path /api/users --json '{"name":"Charlie","email":"charlie@example.com"}'
# 美化输出JSON响应
python client.py case1 --pretty重放所有用例:
# 不指定case_id,自动重放所有用例
python client.py
# 指定用例文件或文件夹
python client.py --cases cases.yaml
python client.py --cases cases/
# 指定服务器地址
python client.py --host 192.168.1.100 --port 8080重放所有用例时会显示每个用例的执行结果和汇总信息:
Found 5 case(s). Starting replay...
================================================================================
[✓] 获取用户列表: GET /api/users -> 200 OK
[✓] 创建用户: POST /api/users -> 201 Created
[✗] 用户不存在: GET /api/users/999 -> 404 Not Found
[✓] 文本响应: GET /api/status -> 200 OK
[✓] 获取用户列表示例: GET /api/users -> 200 OK
================================================================================
Summary: 4 succeeded, 1 failed, 5 total
注意:输出中显示的是用例的description(如果提供了),如果没有description则显示case_id。
-
修改docker-compose.yaml配置(如需要):
- 修改端口映射:
"23941:23941" - 修改目录挂载:
/root/apisec_test/:/root/apisec_test - 确保挂载目录包含项目文件
- 修改端口映射:
-
启动容器:
docker-compose up -d
-
进入容器:
docker exec -it python-apisec-test /bin/bash -
在容器内运行服务端:
cd /root/apisec_test pip install -r requirements.txt python server.py -
在容器内或宿主机使用客户端:
# 在容器内 python client.py case1 --pretty # 在宿主机(如果已安装依赖) python client.py case1 --host <容器IP> --port 23941 --pretty
docker-compose down--host, -H: 监听IP地址 (默认: 0.0.0.0)--port, -p: 监听端口 (默认: 23941)--cases, -c: 用例配置文件路径或文件夹 (默认: cases.yaml)- 可以是YAML文件:
cases.yaml - 可以是文件夹:
cases/(包含原始HTTP格式的用例文件)
- 可以是YAML文件:
--cases-dir: 额外的用例文件夹路径(原始HTTP格式),可与--cases同时使用--debug: 启用调试模式
注意:不加参数时,服务端默认同时加载cases.yaml和cases/文件夹(如果存在)。
case_id: 用例ID(可选,不指定时重放所有用例)--host: 服务器IP地址 (默认: localhost)--port: 服务器端口 (默认: 23941)--url, -u: 服务器完整URL(如果指定了此参数,会覆盖--host和--port)--method, -m: HTTP方法(仅当指定单个用例时有效,会覆盖用例文件中的配置)--path, -p: 请求路径(仅当指定单个用例时有效,会覆盖用例文件中的配置)--header, -H: 请求头,格式: Key:Value(仅当指定单个用例时有效)--data, -d: 请求体数据(仅当指定单个用例时有效)--json, -j: JSON格式的请求体(仅当指定单个用例时有效)--pretty: 美化输出JSON响应--cases, -c: 用例文件或文件夹路径(用于加载所有用例,默认: cases.yaml和cases/)
注意:
- 如果指定了
case_id,会执行单个用例请求。如果不指定method/path等参数,会自动从用例文件中读取请求配置 - 如果不指定
case_id,会重放所有用例,显示每个用例的执行结果和汇总信息
from client import HTTPClient
client = HTTPClient(base_url='http://localhost:23941')
# 发送请求
response = client.send_request(
case_id='case1',
method='GET',
path='/api/users',
headers={'Accept': 'application/json'}
)
print(response.status_code)
print(response.json())编辑 cases.yaml 文件来添加或修改用例:
cases:
my_case:
description: 用例描述(可选,用于说明用例用途)
request:
method: GET
path: /api/endpoint
headers:
Accept: application/json
body: null
response:
status_code: 200
headers:
Content-Type: application/json
body:
data: "response data"YAML格式说明:
-
description (可选): 用例描述,用于说明用例的用途。如果不提供,输出时会使用case_id
-
Request (请求)
method: HTTP方法 (GET, POST, PUT, DELETE等)path: 请求路径headers: 请求头字典body: 请求体(可以是null、字符串或对象)
-
Response (响应)
status_code: HTTP状态码headers: 响应头字典body: 响应体(可以是字符串或对象)
在 cases/ 文件夹下创建用例文件,每个用例一个文件。文件名(不含扩展名)作为用例ID。
用例文件格式:
- 上半部分:HTTP请求(可直接复制到BurpSuite)
- 下半部分:HTTP响应
- 用空行、
===、---或响应状态行(HTTP/1.1)分隔
示例文件 cases/example1.txt:
# Description: 获取用户列表示例
GET /api/users HTTP/1.1
Host: localhost:23941
Accept: application/json
X-Case-ID: example1
HTTP/1.1 200 OK
Content-Type: application/json
{
"users": [
{"id": 1, "name": "Alice"}
]
}
原始HTTP格式说明:
- 可以在文件开头使用注释添加描述:
# Description: 用例描述 - 如果不提供description,输出时会使用文件名(case_id)
- 请求部分:标准HTTP请求格式,可直接复制到BurpSuite
- 响应部分:标准HTTP响应格式
- 分隔方式:空行、
===、---或响应状态行(HTTP/1.1)
使用原始HTTP格式:
# 只使用文件夹格式
python server.py --cases cases/
# 同时使用YAML和文件夹格式(默认行为)
python server.py注意事项:
- 请求部分必须包含
X-Case-IDheader,值应该与文件名(用例ID)一致 - 请求格式应该符合标准HTTP请求格式,可以直接复制到BurpSuite
- 响应部分会自动解析JSON格式的body,其他格式保持为字符串
- 客户端发送HTTP请求时,在header中添加
X-Case-ID字段 - 服务端接收请求,提取
X-Case-ID值 - 服务端在用例库中查找对应的用例
- 服务端返回用例中配置的响应报文
客户端以BurpSuite风格展示完整的HTTP报文:
请求示例:
================================================================================
REQUEST
================================================================================
GET /api/users HTTP/1.1
Host: localhost:23941
Accept: application/json
X-Case-ID: case1
================================================================================
RESPONSE
================================================================================
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 123
{
"users": [
{
"id": 1,
"name": "Alice",
"email": "alice@example.com"
}
]
}
================================================================================
EchoAPI/
├── server.py # HTTP服务端
├── client.py # HTTP客户端
├── case_manager.py # 用例管理器
├── cases.yaml # YAML格式用例配置文件
├── cases/ # 原始HTTP格式用例文件夹
│ ├── example1.txt # 示例用例文件
│ └── example2.txt # 示例用例文件
├── requirements.txt # Python依赖
├── docker-compose.yaml # Docker Compose配置
└── README.md # 说明文档
- 确保服务端在客户端发送请求前已启动
X-Case-IDheader是必需的,如果缺失会返回400错误- 如果指定的case-id不存在,会返回404错误
- 响应体如果是对象,会自动转换为JSON格式
- 服务端启动前会自动检查端口占用,如有冲突会自动关闭占用进程
- 默认情况下,服务端会同时加载
cases.yaml和cases/文件夹中的用例