Skip to content

Commit 41843fe

Browse files
committed
update post for sfz
1 parent c3760ca commit 41843fe

File tree

1 file changed

+122
-1
lines changed

1 file changed

+122
-1
lines changed

src/notes/static-server/README.md

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,127 @@
33

44
我选择了这个 [zfz](https://github.com/weihanglo/sfz/blob/master/src/main.rs)。之所以选择这个项目,是因为它足够小,并且不复杂。用 Rust 实现一些工具的功能,一定能带来很大的收获。我们开始吧!
55

6+
在了解 sfz 之前,我们应该先了解它的用法。终端输入 `sfz --help` 看看都有什么帮助信息。
7+
8+
```shell
9+
$ sfz --help
10+
sfz 0.7.0
11+
Weihang Lo <me@weihanglo.tw>
12+
13+
A simple static file serving command-line tool.
14+
15+
USAGE:
16+
sfz [OPTIONS] [path]
17+
18+
ARGS:
19+
<path> Path to a directory for serving files [default: .]
20+
21+
OPTIONS:
22+
-a, --all Serve hidden and dot (.) files
23+
-b, --bind <address> Specify bind address [default: 127.0.0.1]
24+
-c, --cache <seconds> Specify max-age of HTTP caching in seconds [default: 0]
25+
-C, --cors Enable Cross-Origin Resource Sharing from any origin (*)
26+
--coi Enable Cross-Origin isolation
27+
-h, --help Print help information
28+
-I, --no-ignore Don't respect gitignore file
29+
-L, --follow-links Follow symlinks outside current serving base path
30+
--no-log Don't log any request/response information.
31+
-p, --port <port> Specify port to listen on [default: 5000]
32+
--path-prefix <path> Specify an url path prefix, helpful when running behing a reverse proxy
33+
-r, --render-index Render existing index.html when requesting a directory.
34+
-V, --version Print version information
35+
-Z, --unzipped Disable HTTP compression
36+
37+
```
38+
39+
前面几行主要是应用的名字、版本、作者、描述等信息。我们着重看下 OPTIONS 下对应的参数及其用法。
40+
41+
```
42+
-a, --all 服务点(`.`)前缀的隐藏文件在内的所有文件。
43+
-b, --bind <address> 指定 bind 的服务地址 [默认: 127.0.0.1]
44+
-c, --cache <seconds> 指定 http 缓存的最大秒数,默认 0
45+
-C, --cors 启用跨域资源访问,任意请求来源
46+
--coi 启用跨域 isolation
47+
-h, --help 打印帮助信息
48+
-I, --no-ignore 忽略 gitignore 文件
49+
-L, --follow-links 跟随链接符号所指向的路径 Follow symlinks outside current serving base path
50+
--no-log 不打印请求、响应日志信息
51+
-p, --port <port> 指定端口号 [默认: 5000]
52+
--path-prefix <path> 指定一个 url 路径前缀,在反向代理的场景中会很有帮助
53+
-r, --render-index 请求一个路径时,按照 index.html 文件渲染返回
54+
-V, --version 打印版本信息
55+
-Z, --unzipped 禁用 http 压缩
56+
```
57+
58+
## 主要思路
59+
虽然该工具具备一些“周边”功能,但我们不能脱离主题 —— 围绕实现一个静态资源服务器来分析源代码,因此我们需要有自己的思路,带着自己的想法和问题,去看源代码。下面就是一个参考的思路:
60+
61+
* cli 程序的结构
62+
* 服务器的启动和实现
63+
* 目录和文件的读取
64+
* 渲染
65+
* 响应请求
66+
* 压缩
67+
68+
所以这篇笔记的思路就按照上方的几个重点来开展。
69+
70+
### cli 程序的结构
71+
和很多命令行程序一样,sfz 也是基于 [clap](https://crates.io/crates/clap) 开发的。作者使用了一种很好的方式,将应用的定义、参数、解析分开在不同的 mod 中,这样看起来不那么零乱了。
72+
73+
#### 参数模式
74+
首先是 app 的定义,位于 src/cli/app.rs 文件中。由于 app 的生命周期贯穿整个 sfz 的使用,因此有如下定义:
75+
76+
```rust
77+
fn app() -> clap::Command<'static>
78+
```
79+
80+
函数体中是一些参数的模式:
81+
82+
```rust
83+
let arg_port = Arg::new("port")
84+
.short('p')
85+
.long("port")
86+
.default_value("5000")
87+
.help("Specify port to listen on")
88+
.value_name("port");
89+
```
90+
91+
参数的匹配独立到 app 函数中,有利于后期的管理和维护,如果要增加或更新,直接修改 app 函数即可。
92+
93+
#### 参数的解析
94+
参数解析位于 src/cli/args.rs 文件,命令行参数虽然是看似零乱的标记,但通过匹配拿到后,可以将其放在一个特定的结构中,sfz 就是如此:
95+
96+
```rust
97+
#[derive(Debug, Clone, Eq, PartialEq)]
98+
pub struct Args {
99+
pub address: String,
100+
pub port: u16,
101+
pub cache: u64,
102+
pub cors: bool,
103+
pub coi: bool,
104+
pub compress: bool,
105+
pub path: PathBuf,
106+
pub all: bool,
107+
pub ignore: bool,
108+
pub follow_links: bool,
109+
pub render_index: bool,
110+
pub log: bool,
111+
pub path_prefix: Option<String>,
112+
}
113+
```
114+
115+
-- todo
116+
117+
118+
### 服务器的启动和实现
119+
120+
121+
### 目录和文件的读取
122+
### 渲染
123+
### 渲染
124+
### 压缩
125+
### 响应请求
126+
6127
## 错误处理
7128
由于是一个命令行工具,所以作者对[错误处理](https://www.cnblogs.com/ishenghuo/p/15864482.html)采用了比较直接的方式: `Box<dyn std::error::Error>`,并且,错误的抛出是直接打印然后退出进程:
8129

@@ -17,4 +138,4 @@ fn handle_err<T>(err: Box<dyn std::error::Error>) -> T {
17138

18139

19140
## 参考
20-
* https://github.com/weihanglo/sfz
141+
* https://github.com/weihanglo/sfz

0 commit comments

Comments
 (0)