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.

Architecture of DocTunnel: browsers talk HTTPS to Caddy, Caddy passes requests to the doctunnel program, which stores uploads on disk; a sweeper removes expired uploads, systemd keeps the program running and an AI assistant checks the server over SSH

The Steps in Short

  1. A server that answers. Route requests by path: the home page, the upload endpoint and the share link /p/<code>.
  2. 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.
  3. Links nobody can guess. The code in the link comes from the operating system's random source.
  4. Expiry and cleanup. The sender picks how many days to keep the files. A sweeper deletes what has run out.
  5. Security. File names from the browser are cleaned, passwords are stored as a salted hash, and wrong guesses are limited.
  6. 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:

A 10 GB file being uploaded to DocTunnel with a full progress bar under the Sending button

After the upload the sender gets two links: one to share, and a private one to see the downloads or delete the upload:

The page after an upload: a share link and a separate private admin link, each with a Copy button

The receiver opens the share link and downloads the file:

The download page that a receiver sees: a list of files and how many days they stay available

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.