85 lines
3.2 KiB
Markdown
85 lines
3.2 KiB
Markdown
# 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`). |
|
|
| `STRIP_METADATA` | `1` | Strip embedded EXIF/GPS/author/comments and video metadata server-side. |
|
|
|
|
## 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 "[email protected]" http://localhost:3000/api/upload
|
|
```
|
|
|
|
The returned link looks like `http://localhost:3000/<key>.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.
|