2 个不稳定版本
0.2.0 | 2024年2月18日 |
---|---|
0.1.0 | 2023年2月25日 |
11 在 #json-response
25MB
2K SLoC
包含 (ELF 库, 9.5MB) _plugins/librandom_product_code.so, (ELF 库, 7.5MB) _plugins/librnd_vehicleid.so, (ELF 库, 4MB) _plugins/libtest_plugin.so, (ELF 可执行文件/库, 5.5MB) binary/fips, (ELF 库, 3.5MB) _plugins/libpluginname.so, (rust 库, 180KB) binary/libfips.rlib
假数据注入代理服务器 - 简称 Fips - 快速实现模拟和代理
关于
Fips 提供了三种不同的功能:它可以作为一个假数据服务器,也可以作为一个简单的代理服务器,还可以两者结合,即时操作响应 - 由您自己的规则定义。因此,如果您希望快速设置端点并在应用程序中测试它,Fips 是最佳选择 - 后端工作目前被阻塞?没问题。启动应用程序并托管一个模拟端点,同时将您的其他端点代理到实际后端。
安装
- 安装 rust 和 cargo。
- 检出此仓库。
- 进入它并运行
cargo run
- 或者如果您希望生成可执行文件,运行cargo build
。
命令行参数
另请参阅 fips(.exe) --help
# Start fips on this port
--port: 8888
# Load plugins from this directory, detault is the current directory.
--plugins: .
# Load configuration files from this directory. default is the current directory.
--config: .
快捷键
Tab 切换到下一个标签
Shift+ Tab 切换到上一个标签
c 清除日志输出
r 重新加载配置文件
Esc 退出
用法
Fipss 配置放在 .yaml
或 .yml
文件中。它们在启动时从 --config
目录加载。对于每个请求,Fips 都会检查配置文件,看是否有任何配置对象与当前请求 URI 匹配。如果匹配,则根据配置明确应用四种模式之一。
❗ 请注意以下事项:
- Fips 使用正则表达式来匹配路径。配置路径中的
/foo/bar
也会匹配/foo/bar/baz
,因此如果您关心这一点,则需要尽可能具体。 - 如果多个规则匹配,则只应用第一个匹配的规则。
- 规则按照出现的顺序应用 - 顺序很重要!
- 配置文件不检查拼写,如果因为拼写/缩进错误无法读取配置文件,服务器将崩溃。为了支持您创建配置,fips提供了一个JSON模式。您可以使用
--write-schema
命令行参数创建它。请参阅vscode json-schema的设置(点击查看)和vscode yaml-schema的设置(点击查看),了解如何将vscode指向创建的模式文件。 - 对象操作使用dotpath crate。语法如下。
示例配置在config.yaml
有关更多示例配置,请参阅examples
目录。
- 任何到达Fips的URI为
/foo/bar
的请求将返回['this is a lot of fun']
- Mock:
path: ^/foo/bar/$
rules:
- path:
item: ['this is a lot of fun']
- 任何针对
/foo/*anything*/bar/
的请求将被代理到localhost:4041
的服务器,将转发Authorization
头。
- Proxy:
path: ^/foo/.*/bar/$
forwardUri: 'https://127.0.0.1:4041'
forwardHeaders:
- 'Authorization'
- 任何针对
/foo/*anything*/bar/
的请求将被代理到localhost:4041
的服务器,将返回content-type
头。最后我们将在响应中追加另一个user
。
- Fips:
path: ^/foo/.*/bar/$
forwardUri:
"https://127.0.0.1:4041"
backwardHeaders:
- "content-type"
rules:
- path: ">>"
{
"firstname": "Morty",
"lastname": "Smith",
"status": "cloned himself"
}
每个规则类型的所有配置参数
Fips函数(模拟和代理组合)的配置选项
# A a regex to match incoming requests. if a match is found, this rule will be applied
path: String
# This name will be displayed for debugging purposes
name: String
# Sleep for ms
sleep: u64
# Add these headers to the response
headers: HashMap<String, String>,
# Only apply a rule if the method matches these
matchMethods: Vec<String>
# Only apply a rule with this probability. It's best to have a fallback rule defined
matchProbability: Option<f32>
# Only apply a rule if the request body contains the given string
matchBodyContains: Option<String>
# Forward any incoming request to this uri and return the response
forwardUri: String
# Forward matching headers on the request
forwardHeaders: Vec<String>
# Return these headers from the original response
backwardHeaders: Vec<String>,
# Set the response status
responseStatus: u16
# Apply these transformations on the response (see rules further below)
rules: Vec<Rules>
代理函数的配置选项
# A a regex to match incoming requests. if a match is found, this rule will be applied
path: String
# This name will be displayed for debugging purposes
name: String
# Sleep for ms
sleep: u64
# Add these headers to the response
headers: HashMap<String, String>,
# Only apply a rule if the method matches these
matchMethods: Vec<String>
# Only apply a rule with this probability. It's best to have a fallback rule defined
matchProbability: Option<f32>
# Only apply a rule if the request body contains the given string
matchBodyContains: Option<String>
# Forward any incoming request to this uri and return the response
forwardUri: String
# Forward matching headers on the request
forwardHeaders: Vec<String>
# Return these headers from the original response
backwardHeaders: Vec<String>,
模拟函数的配置选项
# A a regex to match incoming requests. if a match is found, this rule will be applied
path: String
# This name will be displayed for debugging purposes
name: String
# Sleep for ms
sleep: u64
# Add these headers to the response
headers: HashMap<String, String>,
# Only apply a rule if the method matches these
matchMethods: Vec<String>
# Only apply a rule with this probability. It's best to have a fallback rule defined
matchProbability: Option<f32>
# Only apply a rule if the request body contains the given string
matchBodyContains: Option<String>
# Forward any incoming request to this uri and return the response
forwardUri: String
# Set the response status
responseStatus: u16
# Add these items to the response body
body: Serde<Value>
托管静态文件的配置选项
# A a regex to match incoming requests. if a match is found, this rule will be applied
path: String
# This name will be displayed for debugging purposes
name: String
# Sleep for ms
sleep: u64
# Add these headers to the response
headers: HashMap<String, String>,
# Only apply a rule if the method matches these
matchMethods: Vec<String>
# Only apply a rule with this probability. It's best to have a fallback rule defined
matchProbability: Option<f32>
# Only apply a rule if the request body contains the given string
matchBodyContains: Option<String>
# host files from this directory
staticBaseDir: String
规则
# The json_dotpath (see more at Object manipulation on the response)
path: String,
# Any json serializeable item that is added to the response at the paths location
item: Serde<Value>
响应上的对象操作
{
"fruit": [
{ "name": "lemon", "color": "yellow" },
{ "name": "apple", "color": "green" }
]
}
- "" ... 整个对象
- "fruit" ... 水果数组
- "fruit.0" ... 第一个水果对象,{"name": "lemon", "color": "yellow"}
- "fruit.1.name" ... 第二个(索引从0开始)水果的名称,"apple"
- < ... 第一个元素
- > ... 最后一个元素
- - 或 << ... 预先添加
- + 或 >> ... 追加
- <n, 例如 <5 ... 在第n个元素之前插入
- >n, 例如 >5 ... 在第n个元素之后插入
扩展
Fipss的一个重要特性是其扩展系统。Fips导出Rust宏export_plugin
。您的扩展可以使用此宏来注册插件。插件名称将与您的配置匹配。如果发生匹配,则模式将被替换为您的插件输出。所有与您的OS匹配的插件,在Fips二进制文件相关的plugins
目录中,将自动在启动时加载。
示例插件实现
use fips::{PluginRegistrar, Function, InvocationError};
use fake::{faker::name::raw::NameWithTitle, locales::EN, Fake};
use serde_json::Value
pub struct Random;
impl Function for Random {
fn call(&self, args: Vec<Value>) -> Result<String, InvocationError> {
let random_fake_name: String = NameWithTitle(EN).fake();
let json_serializable = format!("{{\"bar\": [\"{}\"]}}", random_fake_name).to_owned();
Ok(json_serializable)
}
}
fips::export_plugin!(register);
extern "C" fn register(registrar: &mut dyn PluginRegistrar) {
registrar.register_function("{{Name}}", Box::new(Random));
}
上述代码在Fips插件注册表中注册了插件。当找到匹配的规则时,将匹配插件的name
,json serializeable(!)
的返回值将用于替换匹配规则中的模式。
示例config.yaml
- Mock:
path: ^/randomname/$
rules:
body:
foo: '{{Name}}'
示例输出为curl localhost:8888/randomname/ | jq
{
"foo": {
"bar": ["Ms. Destiney Metz"]
}
}
您还可以通过配置文件传递参数给插件。如果这样做,插件必须配置为配置yaml中的对象
- Mock:
path: ^/randomname/$
rules:
item:
foo:
plugin: '{{Name}}',
args: [ "foo", 1, "bar" ]
示例输出为curl localhost:8888/randomname/ | jq
{
"foo": {
"bar": ["Ms. Destiney Metz"]
}
}
许可
本项目的许可协议为 MIT 许可协议
依赖项
约15-27MB
约422K SLoC