# Black Hole Share A lightweight, ephemeral file sharing service built with Rust and Actix-Web. Upload images or text with a configurable TTL (1-60 minutes) and share via a unique link. Content is automatically purged after expiration. ## Features - **Ephemeral sharing** – uploads auto-delete after the specified duration - **Image & text support** – drag/drop, paste, or file picker for images; paste text directly - **Zero database** – assets stored as JSON files on disk - **Dark theme UI** – clean, responsive interface with zoom overlay - **Statistics dashboard** – real-time stats at `/stats.html` (active assets, uploads, response times) - **Access logging** – request and asset events logged to `data/logs/access.log` with IP, timing, and metadata ## Quick Start ### Local Development ```bash # Run from repo root (paths resolve to data/html/, data/logs/, data/storage/) cargo run --release ``` Server starts at `http://0.0.0.0:8080` by default. > **Note:** All paths are relative to the repo root: `data/html/`, `data/logs/`, `data/storage/`. ### Docker ```bash docker-compose up --build ``` Exposes port `8080` mapped to container port `80`. Volume mounts `./data:/data`. ## Configuration | Environment Variable | Default | Description | | -------------------- | --------- | --------------- | | `BIND_ADDR` | `0.0.0.0` | Address to bind | | `BIND_PORT` | `8080` | Port to bind | ## API ### Upload ```http POST /api/upload Content-Type: application/json { "duration": 5, "content_type": "text/plain", "content": "Hello, world!" } ``` - `duration` – TTL in minutes (1-60) - `content_type` – MIME type (`text/plain` or `image/*`) - `content` – raw text or base64-encoded image data **Response:** ```json { "link": "/bhs/550e8400-e29b-41d4-a716-446655440000" } ``` ### Fetch ```http GET /api/content/{id} ``` Returns the original content with appropriate MIME type, or `404` if expired/missing. ### Statistics ```http GET /api/stats ``` **Response:** ```json { "active_assets": 5, "total_uploads": 42, "total_deleted": 37, "storage_bytes": 1048576, "image_count": 3, "text_count": 2, "total_requests": 150, "recent_activity": [...] } ``` ## Project Structure ``` ├── src/ │ ├── main.rs # HTTP server, routing, background cleanup │ ├── api.rs # Upload/fetch endpoints │ ├── data_mgt.rs # Asset model, persistence, expiration │ └── logs.rs # Request and asset event logging ├── data/ │ ├── html/ # Frontend (index.html, view.html, stats.html, style.css) │ ├── logs/ # Access logs │ └── storage/ # Stored assets (auto-created) ├── Dockerfile ├── docker-compose.yaml └── Cargo.toml ``` ## Runtime Layout The server uses paths relative to the repo root under `data/`: - `data/html/` – frontend assets (index.html, view.html, style.css) - `data/logs/` – access logs - `data/storage/` – uploaded assets (auto-created) - **Local dev:** Run from repo root with `cargo run --release` - **Docker:** Volume mounts `./data:/data`, container WORKDIR is `/` ## License MIT