实现一个简单的fileserver

背景

当我们希望把某个文件夹暴露到网络上,形成一个简单的 static server 时,常用的做法是 nginx 指定 root 地址,例如:

1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ /index.html?$args;
}
}

nginx 有很多强大的功能,毕竟是一个 生产级 超强网关。

但有时候,我们只需要一个很简单的命令行工具,快速方便地实现启动一个 http server,核心思想就是: 简单、方便、基础能力。

一定要用起来非常简单啊!!!

设计

一开始有很多奇奇怪怪的想法,既希望使用 cli 的模式让使用起来很简单,又希望能具备 使用 config 甚至 使用 db 一样强大……

最终的结果就是:不知该如何取舍,反倒成了四不像……

经过反思与总结,写这类工具项目,一定要搞清楚 自己的核心应用场景 ! 第一版就只满足核心场景,而且是尽量优雅地满足,在此基础上,再增加扩展功能。

基本功能

  • 直接使用二进制文件,启动一个 http server,要能指定 home dir

这个最基础的能力,从 cli 接口上可以这么用:

1
easyserver serve .
  • 增加一些控制项
    • 要能控制 host、port、https(domain)
    • 要能指定基本的 user:password 和 读写权限
1
easyserver serve . --addr 0.0.0.0:8080 --https files.longalong.cn,path/to/cert,path/to/key --user long:longpass:w:/
  • 要能指定 匿名访问及权限

    1
    easyserver serve . --any /path/to/expose:w,/path2/to/read:r
  • 要能指定配置文件

    1
    easyserver serve . -c /path/to/config.yaml
  • 要能后台运行 (暂不实现)

    1
    easyserver serve . -d

实践

于是,在只实现基础功能的指导思想下,实现了一个基础版本:

https://github.com/iamlongalong/easyserver

先做一个最基本的版本,仅实现下面的基本功能:

  • 提供一个简单的 http server,可以指定端口、ip、根目录
  • 可以指定一个上传目录,可以上传文件到指定目录
  • 可以指定 user 和 password,可以通过 basic auth 访问
  • 可以为 user 指定目录的权限,可以指定为只读、只写、读写
  • user 可以生成 token,可以指定 token 的有效期、可用次数、可用路径、可用操作类型(r/w)
  • 可以通过 token 访问,可以指定 token 的有效期、write可用次数、可用路径、可用操作类型(r/w)
  • 可以指定 https 的证书文件
  • 可以通过 config 文件配置,也可以通过命令行参数配置

后面大概率会加上的功能:

  • 一个简单的 dashboard,用于创建 token、查看 token、删除 token
  • dashboard 中可以 list、delete 文件及目录、上传文件及目录

其他

先前的一些思考: 写一个上传文件的服务


The most formidable weapon against errors of every kind is reason.
Thomas Paine