DocTunnel 教學:自行建立檔案分享服務,由上載到伺服器部署
Build Your Own File Sharing Service: From Upload to a Live Server
DocTunnel 示範如何以 Wantzel 建立檔案分享服務,涵蓋上載、分享連結及伺服器部署。伺服器會逐塊將上載內容寫入磁碟,處理 10 GB 檔案時毋須增加記憶體用量。完整影片課程分為 50 節短課,並加入透過 SSH 檢查伺服器、修改前先詢問的 AI 助手。
Sending a large file to someone usually means uploading it to a service, getting a link and sharing it. After a few days the file is gone. This article shows how to build such a service yourself: one program called DocTunnel, written in Wantzel, a strict procedural language that compiles to a single Linux executable. The compiler is a free download.
Why build it yourself? You decide where the files live, how long they stay and who can reach them. And on the way you touch every layer of a web service, from parsing a request to keeping a server running.
The Architecture
The program never faces the internet directly. Caddy, a reverse proxy, handles HTTPS and passes requests to DocTunnel on the server itself. Each upload gets its own folder on disk, a sweeper removes expired uploads, and systemd keeps the program running.
The Steps in Short
-
A server that answers. Route requests by path: the home page, the upload endpoint and the share link
/p/<code>. - Upload without filling memory. The browser sends a multipart request. The server writes it to disk block by block while it arrives, so a 10 GB file needs no more memory than a small one.
- Links nobody can guess. The code in the link comes from the operating system's random source.
- Expiry and cleanup. The sender picks how many days to keep the files. A sweeper deletes what has run out.
- Security. File names from the browser are cleaned, passwords are stored as a salted hash, and wrong guesses are limited.
- Deployment. A small VPS with SSH keys, Caddy in front for HTTPS, and a systemd unit that restarts the program after a crash.
Here is the first step, the server with its three routes:
import http;
var st: int;
procedure app.request;
begin
st := 200;
if http.pathis("/") then
http.add("hello from your own transfer service\n")
else if http.pathis("/upload") and (http.method <> 1) then
http.add("upload: nothing stored yet\n")
else if http.pathstarts("/p/") then begin
http.add("code: ");
http.addb(http.inbuf, http.pathat + 3, http.pathlen - 3);
end else begin st := 404; http.add("not found\n"); end;
http.finish(st, "text/plain");
end;
begin http.serve(8553, 1); end.
And the code that makes a link safe to share. It reads 24 random bytes and maps each one to an alphabet of 32 characters without look-alikes such as l and 1:
import io;
const AB = "abcdefghijkmnpqrstuvwxyz23456789";
var r: array[0..23] of char;
fd, i: int;
begin
fd := sys3(2, sadr("/dev/urandom\x00"), 0, 0);
if fd < 0 then io.fatal("no random source");
if io.read(fd, addr(r[0]), 24) <> 24 then
io.fatal("short read");
for i := 0 to 23 do r[i] := schar(AB, band(ord(r[i]), 31));
sys1(3, fd);
io.out(STDOUT, addr(r[0]), 24);
io.puts(STDOUT, "\n");
end.
Output (different on every run):
mvw3w8ftjvs5fpgwfrgpbjmd
Since 32 is a power of two, band(byte, 31) keeps 5 bits of each byte and every character is equally likely.
The Result
Uploading a 10 GB video file:
After the upload the sender gets two links: one to share, and a private one to see the downloads or delete the upload:
The receiver opens the share link and downloads the file:
What You Learn
Building a file sharing service teaches how uploads travel over HTTP and why streaming matters for large files. It shows what makes a secret link secret, and what it takes to run a program on a server you look after yourself. Near the end, the course adds an AI assistant that checks the server over SSH and asks before it changes anything.
The full step-by-step video series builds DocTunnel in 50 short lessons, each with its source files.
Based on my own video course; drafted with AI assistance from my course material.
來源:DEV Community · dev.to



