USTCLUG 的一个重要服务是它的 开源软件镜像。但是我们这里要讨论的,是另一种自己在本地搭建的文件服务,目的是加速对远程静态文件的访问。这篇文章来源于帮同学解决的一个小问题。

目的

某些课程作业附带的代码示例会通过 HTTP 的方式获取运行需要的输入数据,但是如果这个数据不巧放在某台访问速率很低的服务器上(例如不少用 .edu 域名的国外大学的课程网站上),则会使得作业的运行时间大大加长——通过只有几 KB/s 的网络下载数十 MB 的数据总不是个好主意。更有可能的是,根据作业内容,样例代码还需要做一些修改,这时候每次调试运行代码时都要去下载一次输入数据,简直难以忍受。本文将针对 Windows 用户,讲解如何在手工下载一次相关的文件后,在本地快速搭建一个 HTTP 服务器提供数据文件,以避免反复访问慢速的源地址。对于不能修改访问地址的情况,也提供了相应的对策。

为何不写针对 Linux 用户的教程呢?这是因为,由于有 Apache 和 Nginx 这类成熟好用的服务器软件,再加上 Linux 操作系统优秀的包管理器,结合网上的教程,用几分钟的时间在 Linux 平台上快速建立并运行一个 HTTP 服务器应该不是难事。而在 Windows 上,配置 IIS 这类大而笨重的服务器非常麻烦,使用 Apache/Nginx 之类的服务器软件又由于操作习惯的不同,也不方便。

使用 Python http.server

对比下面的(老旧的)EasyWebSvr,使用 Python 很容易完成一个简单的 HTTP 服务器搭建。

如果你已经安装了 Python,则可以直接使用

python3 -m http.server <port>

来以当前目录为根目录,<port> 为端口运行一个 HTTP 服务器。

如果需要指定别的目录 <path> 作为 HTTP 服务的根目录,可以使用

python3 -m http.server <port> --directory <path>

如果需要 bind 到特定的地址(对于本地服务而言,应该使用 127.0.0.1),可以使用下面的命令。bind 是指将一个网络地址(IP 和端口)与服务器软件中的套接字关联的过程,使得该服务器能接收指定地址上的网络数据。Python 的 http.server 默认值为 0.0.0.0,代表所有人都可以访问。如果只需要本地访问,则可以使用本地回环地址 127.0.0.1

python3 -m http.server <port> --bind 127.0.0.1

使用 EasyWebServer

获取一个 HTTP 服务器

首先当然是要获取一个 HTTP 服务器了,这里我们选择的是 EasyWebSvr。这个服务器是一个体积超小(只有数十 KB)、单文件、几乎不需要配置的小型 HTTP 服务器,甚至支持 CGI 和 PHP。EasyWebSvr 是一个历史久远的开源项目,使用 MSVC 作为开发环境,而且很容易下载到它的编译好的版本(搜索 EasyWebSvr 就可以了)。下载后你将得到一个 EasyWebSvr.exe 和一些其他的文件。不用理会其他的文件(事实上它们是不必要的),直接将 EasyWebSvr.exe 复制到一个空文件夹里面就可以了。

提示:根据代码,EasyWebSvr 会 bind 到 0.0.0.0,这可能会导致安全问题。如果需要 bind 到 127.0.0.1,可能需要修改代码并重新构建。

准备数据

  • 从原始的地址上手工下载一份要被访问的数据,放到上面所说的那个空文件夹里面。
  • 运行 EasyWebSvr.exe,可以看到一个小窗口。
  • 点击右下角的锤子按钮(菜单),选择最下面的 设置 一项。
  • 在弹出的设置对话框里面,选择 主目录 为当前 EasyWebSvr.exe 所在的目录。
  • 文档 选项卡里面勾选 允许目录浏览总是显示目录内容
  • 点击 确定 结束并保存配置。
  • 然后在主窗口里面点击右下方的红色按钮(在菜单按钮的边上),正常应该看到它变成蓝绿色(这时候如果有 Windows 防火墙提示,请选择允许)。
  • 此时服务器就配置好了,打开浏览器输入 http://localhost 即可看到文件列表。

修改原先的代码

  • 例如原先提供的代码中数据文件的 URL 是 http://some.site.edu/path/to/file/data.csv,而这份数据就和 EasyWebSvr.exe 在同一文件夹下,则将代码中的地址修改为 http://localhost/data.csv 就可以使用本地的文件服务了!
  • 服务器最小化后会显示一个小托盘图标,右键点击它可以显示各种选项,包括重新显示主窗口。
  • 使用完后,点击蓝绿色图标,它会变成红色,此时服务器就关闭了。

特殊情况

代码不支持修改地址

如果代码不支持修改地址(这很少见),那么也可以按照原来的 URL 在本地建立文件夹,类似下面这样:

EasyWebSvr.exe
path/                -> 建立这个目录
    to/              -> 建立这个目录
        file/        -> 建立这个目录
            data.csv -> 数据文件在这里

然后修改 hosts 文件(一般在 C:\Windows\System32\drivers\etc 里面,需要管理员权限,具体请看相关教程),加上一句

127.0.0.1 some.site.edu

然后以管理员权限运行

ipconfig /flushdns

即可。可以通过浏览器访问 http://some.site.edu/path/to/file/data.csv 来确认。这一操作会修改所有对 some.site.edu 的请求,因此用完后请删去在 hosts 中加入的那一行,然后再运行一次 ipconfig /flushdns

原地址有非 80 的端口号

如果你拿到的地址使用了别的端口(例如 some.site.edu:8080)且不能修改,那么请在 EasyWebServer 的设置页面 端口号 处输入对应的端口号 8080,对应的访问地址就是 localhost:8080

提示端口已被占用

这可能是因为有其他应用在使用 80 端口。通过 netstat -ano 命令可以查看机器上正被使用的端口号和对应的进程 ID。如果不希望关闭占用 80 端口的程序,那么和上面非 80 端口一样,将我们的 HTTP 文件服务器换到一个别的端口就好了,例如 8080 或者 8000,然后再次点红色圆球图标开启服务器。这时候记得访问地址也要加上对应的端口号。