wmproxy
wmproxy
是由Rust
编写,已实现http/https
代理,socks5
代理, 反向代理,静态文件服务器,内网穿透,配置热更新等, 后续将实现websocket
代理等,同时会将实现过程分享出来, 感兴趣的可以一起造个轮子法
项目 ++wmproxy++
gite: https://gitee.com/tickbh/wmproxy
github: https://github.com/tickbh/wmproxy
了解三种格式
Json
- JSON是一种轻量级的数据交换格式,被广泛使用在Web应用程序之间传输数据。
- JSON使用大括号{}来表示数据结构,使用冒号:来连接键和值。
- JSON支持字符串、数字、布尔值、null、数组和对象等多种数据类型。
- JSON文件通常用于数据交换、存储等场景,也可以用作配置文件。
JSON简单易读存储通用,但JSON原生不支持注释用来做配置文件比较硬伤。
它流行度极高,基本上每个程序员都和他打过交道。
多层级时,对齐和缩进不好控制,容易出错
Yaml
- YAML被设计为一种可读性极强的数据序列化标准,可以用来表达层次化数据。
- YAML使用空格缩进来表示数据层次结构。
- YAML支持浮点数、布尔值、字符串、数组、映射等多种数据类型。
- YAML文件通常用于配置文件、数据交换等场景。
与JSON及TOML相比,结构比较紧凑
但相对用空格缩近,编写及拷贝时出错的机率比JSON及TOML高许多
Toml
TOML 旨在成为一个语义明显且易于阅读的最小化配置文件格式。
TOML 应该能很容易地被解析成各种语言中的数据结构。
- TOML是一种简洁明了的键值对格式,被设计成可以很容易地映射为哈希表。
- TOML使用等号(=)来连接键和值,使用缩进来表示数据层次结构。
- TOML支持整数、浮点数、字符串、布尔值、数组、字典等多种数据类型。
- TOML文件通常用于配置文件、数据交换等场景。
它
易于阅读和编写
,语法灵活
与JSON配置相比,TOML在简洁性方面远远胜出;
与YAML配置相比,TOML在简洁性以及语法灵活性方面远远胜出。
三种格式测试数据的对比
我们用Rust的项目配置文件来做对比,为了展示所有的类型,格式有所变更。它以Toml来做配置文件,我们首先先展示toml的格式
内容包含创建者,创建时间,项目名称,项目依赖等信息,如果我们将其转化成可配置的JSON格式时
toml
create="tickbh" create_time=2023-09-08T10:30:00Z [project] # 项目名称 name="wmproxy" version="1.1" editor=2022 # 项目依赖 [project.dependencies] wenmeng={version = "0.1.21", default-features = false, features = ["std", "tokio"]} webparse={version = "0.1", default-features = false}
复制
行数12行,注释两行,全部顶格开头,原生支持时间格式
json
{ "create": "tickbh", "create_time": "2023-09-08T10:30:00.000Z", "project": { "name": "wmproxy", "version": "1.1", "editor": 2022, "dependencies": { "wenmeng": { "version": "0.1.21", "default-features": false, "features": [ "std", "tokio" ] }, "webparse": { "version": "0.1", "default-features": false } } } }
复制
行数23行,层次的递进比较多,不容易对齐,无法注释,不支持时间格式
yaml
create: tickbh create_time: 2023-09-08T10:30:00.000Z project: # 项目名称 name: wmproxy version: "1.1" editor: 2022 # 项目依赖 dependencies: wenmeng: version: 0.1.21 default-features: false features: - std - tokio webparse: version: "0.1" default-features: false
复制
行数18行,注释两行,原生支持时间格式,到features
这级行,深度相对较高,但是一眼看上去比json
清晰
相对来说JSON比较不适合做比较复杂的配置文件,但
VSCODE
使用的拓展的JSON以支持注释功能。
接下来尝试将nginx.conf格式做转换
以下尝试的将
http {
gzip on;
server {
listen 80; #监听80的服务端口
server_name wm-proxy.com; #监听的域名
location /products {
proxy_pass http://127.0.0.1:8090/proxy;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Origin' '*';
}
location / {
root wmproxy;
index index.html index.htm;
}
}
}
复制
我们也模仿类似的结构,但是对于toml
,yaml
,json
来说,都没有一个key两个值的,要么我们只能用对应的数组,此时我来先来初步重构类似的结构。以下我们以toml结构为例,我们分析table的级数有三级,最外层为http
,中间层为server
为数组,最内层为location
也为数组,headers
我们用之前提到过的mappings
,用proxy
开头来表示重写Reqeust
,其它的来表示重写Response
,文件系统我们用上节提到的file_server
。
我们先定义http
的table,他只有一个属性gzip为on
[http] gzip="on"
复制
其次server
为一个数组,那么我们可以如下定义,有绑定地址和server_name
[[http.server]] bind_addr="127.0.0.1:80" server_name="wm-proxy.com"
复制
再然后location
也为一个数组,定义如下
[[http.server.location]] rule = "/products" reverse_proxy = "http://127.0.0.1:8090/proxy" headers = [ ["+", "Access-Control-Allow-Credentials", "true"], ["+", "Access-Control-Allow-Origin", "*"] ] [[http.server.location]] rule = "/" file_server = { root="wmproxy", browse = true, index=["index.html", "index.htm"] }
复制
那么,最终的结构为如下:
[http] gzip="on" [[http.server]] bind_addr="127.0.0.1:80" server_name="wm-proxy.com" [[http.server.location]] rule = "/products" reverse_proxy = "http://127.0.0.1:8090/proxy" headers = [ ["+", "Access-Control-Allow-Credentials", "true"], ["+", "Access-Control-Allow-Origin", "*"] ] [[http.server.location]] rule = "/" file_server = { root="wmproxy", browse = true, index=["index.html", "index.htm"] }
复制
而yaml的格式结构如下:
http: gzip: on server: - bind_addr: 127.0.0.1:80 server_name: wm-proxy.com location: - rule: /products reverse_proxy: http://127.0.0.1:8090/proxy headers: - - + - Access-Control-Allow-Credentials - "true" - - + - Access-Control-Allow-Origin - "*" - rule: / file_server: root: wmproxy browse: true index: - index.html - index.htm
复制
而json的格式结构如下:
{ "http": { "gzip": "on", "server": [ { "bind_addr": "127.0.0.1:80", "server_name": "wm-proxy.com", "location": [ { "rule": "/products", "reverse_proxy": "http://127.0.0.1:8090/proxy", "headers": [ [ "+", "Access-Control-Allow-Credentials", "true" ], [ "+", "Access-Control-Allow-Origin", "*" ] ] }, { "rule": "/", "file_server": { "root": "wmproxy", "browse": true, "index": [ "index.html", "index.htm" ] } } ] } ] } }
复制
- 自建的好处是比较清晰,可以自定义自己合适的结构,但是编写者需要重新开始学习,而用能用的配置文件需要遵循它的格式定义
- 像toml文件,如果层级很深,他的key值配置会很长,因为他一旦定义一个table,就是从最顶级来解析,但是编写者只要熟悉过这配置文件很快就能写出满意的配置文件
- 而yaml的层级结构相对会需要去看对齐与否,编写的时候需要额外注意,因为弄错了缩进,层级就会发生错误
- 而json最后结尾的会有相当多的花括号,相对比较容易弄错。JSON总体来说不太适合做比较复杂的配置文件
结语
在不考虑自建格式的情况下,如nginx的nginx.conf
,如caddy的Caddyfile
,将会同时兼容toml
及yaml
格式的配置文件。