beap

Package Version Hex Docs Guide

Beatrix — Beap HTTPFS

Beap

Share files. Dirwalk on the browser :)

Beap is a small HTTP file server for your terminal, in the spirit of python -m http.server, with what that one lacks: uploads (drag and drop, with real progress, streamed to disk at any size), copyable links and curl commands, and a clean, responsive interface. It is written in Bea, runs on the Erlang VM, and needs no internet connection: the page, its stylesheet and its script are all built in.

Demo

Install

Beap is built with Bea, which needs Erlang/OTP and Gleam:

git clone <this repository> beap && cd beap
bea run -- --help             # run from the source
bea pack -o ~/.local/bin/beap # or build a standalone executable (gleepack)

Run

beap                          # share the current directory on 127.0.0.1:8000
beap 127.0.0.1 8000           # host and port, as arguments
beap --port 9000
beap --host 0.0.0.0 --port 8000   # reachable from other devices
beap --dir ./shared
beap --no-upload              # read-only
beap --max-upload 2G          # largest upload accepted (default 10G)
bea run -- --dir ~/Downloads  # the same, from the source
OptionDefault
--host HOST127.0.0.1interface to listen on: 0.0.0.0 for all IPv4 ones, :: for IPv6
--port PORT80000 picks a free port
--dir DIR.directory to share
--no-uploaduploads onshare read-only
--max-upload SIZE10Gper file: bytes, or K, M, G, T (multiples of 1024)
-h, --help

Options also take the --port=9000 form. On start, Beap prints the shared directory, the addresses to open (with the machine’s network addresses when bound to all interfaces) and whether uploads are on.

In the browser

Open the address Beap prints. Folders come first, then files, by name; a folder opens with a click, and the breadcrumbs lead back up. Each file has:

To upload into the folder shown, drop files anywhere on the page or use Browse files. Each upload shows its progress (sent, total, percentage) and can be cancelled; the listing refreshes when they are done. A file that exists already is never replaced: the upload is saved as notes (1).txt.

From a terminal

curl -fL -O 'http://127.0.0.1:8000/files/archive.tar.gz'          # download
curl -fL -C - -O 'http://127.0.0.1:8000/files/archive.tar.gz'     # resume one
curl -T archive.tar.gz 'http://127.0.0.1:8000/upload/'            # upload
curl -T archive.tar.gz 'http://127.0.0.1:8000/upload/backups/'    # into a folder
curl -T notes.txt 'http://127.0.0.1:8000/upload/renamed.txt'      # under a name

curl -T streams the file; curl --data-binary @file -X PUT works too, but curl reads all of the file into memory first. A successful upload answers 201 Created with the name it was saved under and its URL.

Request
GET /, GET /files/<folder>/the folder’s page
GET /files/<file>the file, as a download (Range supported)
PUT /upload/<folder>/<name>saves the body as <folder>/<name>

How uploads work

The body of a PUT is read from the socket 64 KiB at a time, and each piece is on its way to the disk before the next is read: memory stays flat whatever the size, and a disk slower than the network slows the sender down instead of filling memory. The browser sends files the same way (a raw PUT, not a form), so its progress is the transfer’s.

An upload is written to a new file in .beap-uploads/, in the shared directory, which is never listed or served. Once complete and flushed to disk, it gets its name with a hard link, atomically and never over an existing file, then the temporary file goes. A failed, cancelled or interrupted upload leaves nothing behind, and leftovers from a killed server are cleared when it starts again.

Security

Limitations

Development

bea check
bea test           # unit and end-to-end tests (uploads of 256 MiB to $TMPDIR)
bea format src

Beap is a tool, not a library: src/beap.bea holds main, and everything else is in src/beap/internal/, which Gleam keeps out of the package’s public API and documentation. There: config (command line), server, router (requests to responses), paths (safe path resolution), fs (listings), upload (streaming uploads), share (links and curl commands), html and assets (the interface), and runtime/ (the few Erlang functions Beap needs: exclusive files, link reading, and a workaround for ewe 9.0.0 keeping uploads in memory).

✨ Search Document