# File Drop A minimal, self-hosted private file host. Drop a file, get a secret, unguessable link. Images, videos and audio render directly in the browser; everything else downloads. - **Backend** — Rust (Axum + Tokio) - **Frontend** — Svelte (Vite + Tailwind) - **Storage** — local filesystem, no database ## Quick start ```bash # 1. Build the frontend (outputs frontend/dist) cd frontend npm install npm run build cd .. # 2. Run the server (from the project root) cargo run --release --manifest-path backend/Cargo.toml ``` Then open http://localhost:3000. > `STORAGE_DIR` and `STATIC_DIR` are relative to where you run the server. > Run it from the project root, or set absolute paths in `.env`. ## Configuration Copy `backend/.env.example` to `.env` and edit it. | Variable | Default | Description | | ---------------------- | ----------------- | ---------------------------------------------- | | `HOST` / `PORT` | `0.0.0.0` / `3000`| Bind address. | | `STORAGE_DIR` | `./storage` | Files and metadata directory. | | `STATIC_DIR` | `./frontend/dist` | Built frontend directory. | | `MAX_FILE_SIZE` | `10GB` | Maximum upload size. | | `FILE_TTL_MS` | `172800000` | File lifetime (48 h max). | | `KEY_LENGTH` | `8` | Share key length (`a-z0-9`). | | `PUBLIC_BASE_URL` | — | Public URL for absolute links. | | `RATE_LIMIT_ENABLED` | `1` | Per-IP rate limiting. | | `RATE_LIMIT_MAX` | `300` | Max requests per window. | | `RATE_LIMIT_WINDOW_MS` | `60000` | Window in milliseconds. | | `TRUST_PROXY` | `0` | Enable behind a proxy (`X-Forwarded-For`). | ## API | Method | Route | Description | | -------- | ------------------ | --------------------------------------------- | | `POST` | `/api/upload` | Upload a file (`multipart/form-data`). | | `GET` | `/:key` | Download (inline for media). | | `POST` | `/api/auth/:key` | Submit the password for a protected file. | | `DELETE` | `/api/files/:id` | Delete a file (`X-Delete-Key` header). | | `GET` | `/api/health` | Service status. | Example: ```bash curl -F "file=@photo.png" http://localhost:3000/api/upload ``` The returned link looks like `http://localhost:3000/.png`. Append `?dl=1` to force a download instead of inline display. ## Structure ``` backend/ Rust server (Axum) frontend/ Svelte interface (Vite + Tailwind) scripts/ tests storage/ data (created on first run) ``` ## Tests ```bash cargo build # in backend/ bash scripts/e2e-test.sh ``` The test covers upload, download, password auth, invalid keys, name sanitization and deletion.