This commit is contained in:
Anaïs Saraiva
2026-08-25 12:32:54 +02:00
parent b1b4f03814
commit 1b3b45b348
12 changed files with 193 additions and 95 deletions
+40 -41
View File
@@ -1,84 +1,83 @@
# File Drop
Un hébergeur de fichiers privé, auto-hébergé et minimal. On dépose un fichier,
on reçoit un lien secret et intraçable. Les images, vidéos et sons s'affichent
directement dans le navigateur ; les autres fichiers se téléchargent.
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)
- **Stockage** — système de fichiers local, sans base de données
- **Storage** — local filesystem, no database
## Démarrage rapide
## Quick start
```bash
# 1. Construire le frontend (produit frontend/dist)
# 1. Build the frontend (outputs frontend/dist)
cd frontend
npm install
npm run build
cd ..
# 2. Lancer le serveur (depuis la racine du projet)
# 2. Run the server (from the project root)
cargo run --release --manifest-path backend/Cargo.toml
```
Ouvrir ensuite http://localhost:3000.
Then open http://localhost:3000.
> Les chemins `STORAGE_DIR` et `STATIC_DIR` sont relatifs au dossier de
> lancement. Lance donc le serveur depuis la racine du projet (ou règle ces
> variables en absolu dans `.env`).
> `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
Copier `backend/.env.example` vers `.env` puis l'adapter.
Copy `backend/.env.example` to `.env` and edit it.
| Variable | Défaut | Rôle |
| ---------------------- | ----------------- | ----------------------------------------- |
| `HOST` / `PORT` | `0.0.0.0` / `3000`| Adresse d'écoute. |
| `STORAGE_DIR` | `./storage` | Dossier des fichiers et métadonnées. |
| `STATIC_DIR` | `./frontend/dist` | Dossier du frontend construit. |
| `MAX_FILE_SIZE` | `10GB` | Taille maximale d'envoi. |
| `FILE_TTL_MS` | `172800000` | Durée de vie d'un fichier (48 h max). |
| `KEY_LENGTH` | `8` | Longueur de la clé de partage (`a-z0-9`). |
| `PUBLIC_BASE_URL` | — | URL publique pour les liens absolus. |
| `RATE_LIMIT_ENABLED` | `1` | Limite de requêtes par IP. |
| `RATE_LIMIT_MAX` | `300` | Requêtes max par fenêtre. |
| `RATE_LIMIT_WINDOW_MS` | `60000` | Fenêtre en millisecondes. |
| `TRUST_PROXY` | `0` | Activer derrière un proxy (`X-Forwarded-For`). |
| 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
| Méthode | Route | Rôle |
| --------- | -------------------- | ------------------------------------------- |
| `POST` | `/api/upload` | Envoi d'un fichier (`multipart/form-data`). |
| `GET` | `/:key` | Téléchargement (inline pour les médias). |
| `POST` | `/api/auth/:key` | Mot de passe d'un fichier protégé. |
| `DELETE` | `/api/files/:id` | Suppression (en-tête `X-Delete-Key`). |
| `GET` | `/api/health` | État du service. |
| 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. |
Exemple :
Example:
```bash
curl -F "[email protected]" http://localhost:3000/api/upload
```
Le lien renvoyé est de la forme `http://localhost:3000/<clé>.png`. Ajouter
`?dl=1` force le téléchargement au lieu de l'affichage.
The returned link looks like `http://localhost:3000/<key>.png`. Append `?dl=1`
to force a download instead of inline display.
## Structure
```
backend/ serveur Rust (Axum)
frontend/ interface Svelte (Vite + Tailwind)
backend/ Rust server (Axum)
frontend/ Svelte interface (Vite + Tailwind)
scripts/ tests
storage/ données (généré au premier lancement)
storage/ data (created on first run)
```
## Tests
```bash
cargo build # dans backend/
cargo build # in backend/
bash scripts/e2e-test.sh
```
Le test couvre l'envoi, le téléchargement, l'authentification par mot de passe,
les clés invalides, la sanitisation des noms et la suppression.
The test covers upload, download, password auth, invalid keys, name
sanitization and deletion.