Posted on ::

I often need to send files to people — photos, documents, archives — and I got tired of the usual suspects: WeTransfer limits you, SwissTransfer is great but you depend on a third party, and all of them impose size caps, retention limits, and account management overhead.

So I wrote filewebx. It is a self-hosted CGI Bash system for private file exchange, using Capability URLs: you upload a file, get back a non-guessable link, share it. No logins, no passwords, no accounts.

It is your own private WeTransfer / MASV / Smash / SwissTransfer, on your own server.

What it does🔗

  • No accounts needed: The URL is the authentication. Your secret admin URL (e.g: https://your.site/yJDdYNEXmB) is your dashboard. Share it with nobody, and it is secure.
  • Guest accounts: Create isolated spaces for other people by just giving them a link. They can upload and get their own shareable links without seeing yours.
  • Auto-expiry: Files expire after a configurable delay (100 days by default). A daily cron job cleans them up.
  • Nice interface with for instance an upload progress bar, easy copying of the url, nice colored logs that work without JavaScript frameworks; Just plain HTML + CSS + JS served by a Bash CGI.
  • Slug URLs: Download links are readable: https://your.site/_/OLw6bZrh65lj/my-photo.jpg instead of raw url-encoded gibberish.
  • Geolocalized logs: See where downloads come from, with IP colors assigned via golden-angle hue sampling to spot patterns at a glance.
  • Quotas: Reserve free disk space. Per-guest quotas available.

How it works🔗

Three bash scripts, one web server, a single directory for data. Uploads go to data/, metadata is stored as bash associative arrays via declare -p (from my colas-bash-lib). The download script (_) logs access and serves the file. The admin script handles the UI, guest management, and cleaning.

The whole thing is plain files — no database, no Docker, no snap, flatpak, no dependencies beyond iconv and a CGI-capable web server (tested with Apache).

Why bash?🔗

Because for a CGI system that runs once per request, startup time does not matter, and bash makes deployment trivial: copy three files, rename one to your admin password, done. No compilation, no npm install, no virtualenv. No dependencies on library that can break at any time in the future. It works now, it will still work in twenty years and more. Also, the bash associative array metadata format (declare -p) is surprisingly practical as simple database — it is both human-readable and machine-parseable without a custom serializer.

Guest accounts🔗

You can create guest accounts from the admin tab. A guest only sees its own files. Mark a guest as "admin" to get a link back to the main admin account — useful for creating separate namespaces for different audiences (work, family, surfing buddies).

Non-admin guests cannot access the main account, see other guests, or create new guests. Perfect for giving to people who just need to send you a file.

Deploy🔗

  1. Create a directory on your server with data/ and cgi/ subdirectories.
  2. Copy filewebx as your admin password name into cgi/.
  3. Copy filewebdl as _ into cgi/.
  4. Copy cgibashopts into cgi/.
  5. Set up a virtual host, add a cron job for daily cleanup.
  6. Done.

See the README for full install instructions and Apache config samples. Configuration is done via a single bash-syntax file: set validity, passlen, freequota, guestquotas, and a few more.

What I like about it🔗

  • It is the simplest thing that works: data is plain files, so I can ls, grep, rsync everything without special tools.
  • Capability URLs mean I never have to manage a user database. The random tokens are generated from /dev/urandom — 12 characters give about 10^14 combinations.
  • The log coloring with perceptually-spaced HSL hues makes browsing download history genuinely pleasant.

The code is at github.com/ColasNahaboo/filewebx, MIT license. Contributions, issues, and ideas welcome.

Table of Contents