3个版本
0.1.2 | 2024年8月5日 |
---|---|
0.1.1 | 2023年10月20日 |
0.1.0 | 2023年10月19日 |
#109 in HTTP服务器
每月下载量 134次
52KB
386 行
Mini RPS
用Rust编写的微型反向代理服务器
特性 ❤️
动机 💡
在我看来,构建服务器并适应动态市场需求最好的方法是应用Linux哲学。
每个服务器或微服务执行一个特定且定义良好的功能。
因此,我决定编写一个微服务,我可以快速配置它来提供文件,并编排其他服务。
安装 💻
cargo install minirps
或者您可以使用每个版本中提供的预编译二进制文件(目前仅限于通用Linux)。
用法 🎮
minirps -h
简单的静态文件服务器
minirps path/to/static/folder
提供隐藏文件
minirps -a path/to/static/folder
忽略根目录中的Markdown文件
minirps -i "/*.md" path/to/static/folder
忽略任何Markdown文件
minirps -i "/**/*.md" path/to/static/folder
在4000端口而不是3000端口上运行
minirps -p 4000 path/to/static/folder
使用https而不是http
minirps -p 4000 path/to/static/folder -c path/to/cert.pem -k path/to/key.pem
允许所有来源的CORS
minirps -o -p 4000 path/to/static/folder -c path/to/cert.pem -k path/to/key.pem
使用config.toml文件启动服务器
这里通过命令行传递的可能配置的极限已达到。
为了创建更复杂和有趣的示例,我们需要一个config.toml
文件
minirps -f path/to/config.toml
忽略根目录中的任何Markdown文件和以secret_开头的文件
config.toml
assets = "path/to/static/folder"
port = 4000
cert = "path/to/cert.pem"
key = "path/to/key.pem"
ignore = [
"/**/*.md",
"/secret_*"
]
允许我的网站进行CORS
config.toml
assets = "path/to/static/folder"
port = 4000
cert = "path/to/cert.pem"
key = "path/to/key.pem"
cors = [
"https://www.my-website.com"
]
允许来自我的网站的不同来源进行CORS
config.toml
assets = "path/to/static/folder"
port = 4000
cert = "path/to/cert.pem"
key = "path/to/key.pem"
cors = [
"http://www.my-website.com",
"https://www.my-website.com",
"http://www.my-other-website.com",
"https://www.my-other-website.com"
]
允许所有来源的CORS
config.toml
assets = "path/to/static/folder"
port = 4000
cert = "path/to/cert.pem"
key = "path/to/key.pem"
cors = []
将一个反向代理添加到运行在https://127.0.0.1:8000的API服务器
config.toml
assets = "path/to/static/folder"
port = 4000
cert = "path/to/cert.pem"
key = "path/to/key.pem"
cors = []
# GET https://127.0.0.1:4000/api/users => GET https://127.0.0.1:8000/users
[[routes]]
method = "GET"
path = "/api/users"
[[routes.requests]]
method = "GET"
url = "https://127.0.0.1:8000/users"
# PUT https://127.0.0.1:4000/api/users/21 => PUT https://127.0.0.1:8000/users/21
[[routes]]
method = "PUT"
path = "/api/users/:id"
[[routes.requests]]
method = "PUT"
url = "https://127.0.0.1:8000/users/{{params.id}}"
body = "{{body}}"
发送纯文本响应而不是API响应
config.toml
assets = "path/to/static/folder"
port = 4000
cert = "path/to/cert.pem"
key = "path/to/key.pem"
cors = []
# GET https://127.0.0.1:4000/api/users => GET https://127.0.0.1:8000/users
[[routes]]
method = "GET"
path = "/api/users"
[[routes.requests]]
name = "users"
method = "GET"
url = "https://127.0.0.1:8000/users"
[routes.response]
body = """
{% for user in data.users.json %}
{{user.name}}
{% endfor %}"""
headers = { Content-Type = "text/plain" }
# PUT https://127.0.0.1:4000/api/users/21 => PUT https://127.0.0.1:8000/users/21
[[routes]]
method = "PUT"
path = "/api/users/:id"
[[routes.requests]]
name = "result"
method = "PUT"
url = "https://127.0.0.1:8000/users/{{params.id}}"
body = "{{body}}"
[routes.response]
body = "{% if data.result.status == 200 %}SUCCESS!{% else %}ERROR!{% endif %}"
headers = { Content-Type = "text/plain" }
发送HTML模板响应而不是API响应
config.toml
templates = "path/to/templates/folder"
assets = "path/to/static/folder"
port = 4000
cert = "path/to/cert.pem"
key = "path/to/key.pem"
cors = []
# GET https://127.0.0.1:4000/api/users => GET https://127.0.0.1:8000/users
[[routes]]
method = "GET"
path = "/api/users"
[[routes.requests]]
name = "users"
method = "GET"
url = "https://127.0.0.1:8000/users"
[routes.response]
body = "{% include 'users.html' %}"
headers = { Content-Type = "text/html" }
# PUT https://127.0.0.1:4000/api/users/21 => PUT https://127.0.0.1:8000/users/21
[[routes]]
method = "PUT"
path = "/api/users/:id"
[[routes.requests]]
name = "result"
method = "PUT"
url = "https://127.0.0.1:8000/users/{{params.id}}"
body = "{{body}}"
[routes.response]
body = "{% include 'edit.html' %}"
headers = { Content-Type = "text/html" }
示例 🧪
静态服务器与CORS
在这个例子中,创建了一个静态服务器,并添加了一个CORS请求以供展示。
静态服务器
minirps assets
CORS服务器
minirps assets/tests -o -p 4000 -c assets/certs/cert.txt -k assets/certs/key.txt
starwars
在这个例子中使用了minijinja模板来从swapi的《星球大战》API中获取数据。
minirps -f examples/starwars.toml
测试
在这个例子中,构建了一个静态服务器和一些路由,用于测试使用hurl自动反向代理和模板的使用。
minirps -f examples/test.toml
hurl --test examples/test.hurl
文档 📖
config.toml
如果同时存在,则命令行参数优先于配置文件。
命令行参数路径相对于当前工作目录。
config.toml
路径相对于您的目录。
目前,对config.toml
的任何更改都必须重新启动服务器才能应用。
port: 整数?
运行服务器上的可选整数端口号,默认:3000
all: 布尔值
是否显示隐藏文件。
如果通过命令行或config.toml
确认,则将显示。
ignore: [string]?
使用glob表达式忽略的文件列表。
如果命令行上传递了-i选项,它将被追加到列表中。
路由必须与资产文件夹相关,而不是工作目录。
有关glob表达式的完整参考和可能的错误,请查看此库。
cors: [string]?
表示允许的CORS请求来源的字符串数组的可选值。
空数组允许所有来源。
如果未定义此变量,则禁用CORS。
cert: 字符串?
可选字符串,包含https服务器的公钥文件路径。
只有当cert
和key
可用时,服务器才会通过https运行。
key: 字符串?
可选字符串,包含https服务器的私钥文件路径。
只有当cert
和key
可用时,服务器才会通过https运行。
assets: 字符串?
可选字符串,包含静态文件文件夹的路径。
templates: 字符串?
可选字符串,包含minijinja模板文件夹的路径。
routes: [{method: string, path: string, requests: [{...}]?, response: {...}?}]
定义反向代理路由的对象数组。
method
是一个包含http方法之一的字符串- GET
- POST
- DELETE
- PUT
- PATCH
- HEAD
- OPTIONS
- TRACE
- CONNECT
path
是一个与路由关联的路径的字符串,:var
可用于设置路径变量(例如:/api/user/:id)。
routes.requests: [{name: string?, method: string, headers: {header: string}?, url: string, body: string?}]?
Requests是一个可选对象数组,代表需要生成响应而必须发出的请求。
name
是一个可选字符串,如果存在,则用于存储与要发出的请求相关联的响应数据,以便在minijinja模板中使用。method
是一个必需的字符串,包含http方法(或minijinja模板),如路由定义中所述。headers
是一个对象,其键是要设置的请求头,值是包含该头值或用于生成它的 minijinja 模板。headers
是一个对象,其键是要配置的请求头,值是包含该头值或用于生成它的 minijinja 模板。url
是与请求相关联的必需的 minijinja 模板或原始字符串。body
是与请求相关联的可选的 minijinja 模板或原始字符串。
routes.response {status: string?, headers: {header: string}?, body: string?}?
响应以请求数组中最后一个请求的状态、头和响应体开始,或者如果没有,则为空的 200 响应,这里属性是反向代理发送给客户端的响应的修饰符。
status
是一个可选的字符串或 minijinja 模板,表示一个整数以修改响应的状态码。headers
是一个可选的对象,其键是要修改的响应头,值是表示与该头关联的值的字符串或 minijinja 模板。body
是一个可选的字符串或 minijinja 模板,用于替换原始响应体。
可用的 minijinja 模板变量
path: string
客户端在请求中传递的关联路径。
例如: /api/user/:id
=> /api/user/25
。
query: string?
客户端在请求中传递的关联查询字符串或 none
。
例如: https://127.0.0.1:3000/api/users?name=john
=> name=john
headers: {header: string}
客户端在请求中传递的关联头对象。
注意,所有头键都是 小写。
例如:Content-Type: text/plain => {"content-type": "text/plain"}
params: {param: string}
给定路由上与客户端请求关联的路径参数的关联对象。
例如: /api/user/:id
=> https://127.0.0.1:3000/api/user/25
=> {"id": "25"}
vars: {param: string}
与客户端请求关联的查询参数的关联对象。
例如: https://127.0.0.1:3000/api/users?name=john
=> {"name": "john"}
body: string
客户端在请求中传递的体。
json
客户端在请求中传递的体转换为 json。
如果失败,包含作为 json 字符串的体。
data: {name: {status: integer, headers: {header: string}, body: string, json}}
数据对象是存储所有反向代理请求数组的所有结果的地点。只有与它相关联名称的结果才会被存储,并将对下一个请求或响应模板可用。
name
:对象键是传递到requests
数组中的name
。status
:与请求关联的响应状态。headers
:与请求关联的响应头(在这个对象中,头名称始终为小写)body
:与请求关联的响应体字符串。json
:将响应体转换为json(如果失败则为json字符串)并与请求关联。
发布 📦
目前,仅在发布中分发Linux通用版本的二进制文件。
sudo apt install pkg-config libssl-dev musl-tools
rustup update
rustup target add x86_64-unknown-linux-musl
cargo update
cargo build --release --target x86_64-unknown-linux-musl
微服务 💯
我使用的微服务列表以及与minirps
共享你的哲学。
- serialscale:一个用rust编写的IOT服务器,用于通过串行端口读取秤的重量数据。
- rawprinter:一个用rust编写的IOT服务器,用于通过USB连接到原始打印机。
贡献 🤝
这是一个非常简单的项目。任何贡献、任何反馈都将受到极大的欢迎。
支持 ⭐
如果这个项目对你有帮助,请在github上给它一个star,这是一种增加证据并吸引更多贡献者的方式。
致谢 🙏
如果没有这些相关项目,这项工作将无法实现
对为这些项目做出贡献的所有人表示衷心的感谢。
依赖
~15–30MB
~508K SLoC