开发 OneTiny 时的一点思路

需求

下载链接

自从买了台二手 Surface 二合一电脑以后,的确效率上去了,可以手写真香,手终于能跟上脑子了。 一开始拿来当出门用的备用机,轻便,但是使用久了以后,渐渐开始有和主力机之间传输文件的需求。 最简单的就是拿个 U 盘拷过来拷过去,一次两次还好,多了就烦了。

于是经过搜索我发现了 Python 可以通过在命令行输入 python -m http.server 8000 来暂时开启一个共享目录,同一局域网内的主机就可以访问到这个目录的内容。 但是这条命令在 Linux 中可以,在 Windows 下不能执行。

想想这玩意本质就是开启一个 HTTP 服务,指定当前目录为 HTTP 服务的根目录。刚好学了 Gin 框架,而 Golang 又可以编译独立的可执行文件,还可以交叉编译,于是说干就干开始干活。

思路

开启一个 HTTP 服务以后,当有人访问时,需要返回目录下的内容。 返回的页面采用最简单的效果,基本没有 CSS 。

v0.1 版非常简单,程序启动的时候通过 -r 指定目录,没有的话默认当前目录;通过 -p 可以指定程序运行的端口。

当有人访问时,也就是程序接收到请求,读取目录下所有文件包括目录,交给 HTML 生成器 generateHTML 生成 HTML 内容,然后返回给访问者。

如果用户点击的是目录,则遍历该目录、生成 HTML,返回; 如果用户点击的是文件,则触发下载行为,将文件传输给访问者。

v0.1.1 版时重构了 获取IP 函数,解决了 Windows 下给出的无效 IP 的问题,并修复了下载文件异常的问题。

到这里 OneTiny 作为一个局域网 FTP 工具已经可以提供稳定的服务了。

但是只能单向下载文件还不够,如果能上传就好了,有来有回。

于是 v0.2 版新增了上传功能,并且在 HTML 部分增加了显示文件大小、返回上一级目录的链接。

这一版在新增功能的时候做了一部分重构。由于 0.1 版直接获取请求路径中的参数导致代码耦合度非常高,所以创建了一个 FileStruction 的模型,用于存储文件的绝对路径、相对路径、文件大小等信息。

v0.2.1 版的时候觉得,有时候开放一个目录供人下载文件,但不希望对方上传文件上来,所以需要一个开关来设置是否允许上传。于是增加了 -a 的参数,默认不可以上传,除非加上 -a 参数才会在客户端展示的时候展示出上传框。

v0.2.2 版对整个程序做了较大幅度的重构,将一些全局的变量移动到 config 包,然后把启动 Gin 实例的部分移动到 start 包,并做了对 -p-r 参数的校验,避免用户指定系统预留的端口,或者输入一个不存在的目录作为访问根目录。还另外增加了 color 包用于控制台彩色打印(windows 除外)。

后记

这是我的第一个规范使用 Git 维护的独立项目,源自自身实际需求。 虽然市面上有许多现成的好看的功能更强大的 FTP 工具,但是我觉得那些太复杂,且需要安装等等。 我更愿意使用一个简简单单的只负责在局域网内的设备间传输文件的工具,除了必要的功能不添加太多复杂的功能,所以连界面也采用最简单的 “裸 HTML” 。 (我也不喜欢把时间花在写出华丽的界面上,而更愿意把时间拿来完善和增强本身的功能)

简单、专注、无需安装,这些是 OneTiny 的特点,也是 OneTiny 的局限。 我希望除了图形界面版本,OneTiny 能一直保持这种大道至简的风格,专注与局域网 FTP 这个职责即可。

Давай!

Todo

  • 上传功能
  • 自动检查更新功能
  • 密码验证功能(防止局域网内监听)
  • 增加图形界面(使用 fyne
  • 限定访问层级
  • 限定允许上传位置
  • 大文件多线程下载
  • 断点续传

版本历史

2021-06-16 0.2.1 -> 0.2.2
  1. Refactor: 对gin实例启动部分进行重构,移动至 start 包内;新增 config 包
  2. Style:控制台增加彩色打印(windows除外)
  3. Fix: 增加 flag 参数的验证
2021-06-16 v0.2 -> v0.2.1
  • Feat: 新增 允许上传 flag -a
2021-06-11 v0.1.1 -> v0.2
  1. Feat: 新增上传功能
  2. Style: 文件列表增加 文件大小,增加返回上一级目录链接
2021-06-11 v0.1 -> v0.1.1
  1. Fix: 修复了下载文件异常
  2. Refactor: 重构了获取IP函数
2021-06-11 nil -> v0.1
  1. 首个版本,具有局域网内单向共享文件的功能,未具有上传功能。
  2. 可通过 -p 指定端口,通过 -r 指定目录