icsboyx 81656ec0da
Some checks failed
Build & Publish / check (push) Successful in 3s
Build & Publish / build_publish (push) Failing after 54s
test
2026-01-09 21:35:07 +01:00
2026-01-06 10:10:36 +01:00
2026-01-06 10:10:36 +01:00
2026-01-06 10:10:36 +01:00
2026-01-06 10:10:36 +01:00
2026-01-09 21:35:07 +01:00
wip
2026-01-06 17:35:17 +01:00

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

# 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

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

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:

{ "link": "/bhs/550e8400-e29b-41d4-a716-446655440000" }

Fetch

GET /api/content/{id}

Returns the original content with appropriate MIME type, or 404 if expired/missing.

Statistics

GET /api/stats

Response:

{
  "active_assets": 5,
  "total_uploads": 42,
  "total_deleted": 37,
  "storage_bytes": 1048576,
  "image_count": 3,
  "text_count": 2,
  "avg_response_ms": 0.85,
  "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

Description
Black Hole Share
Readme MIT 1 MiB
Languages
HTML 43.7%
Rust 35.5%
CSS 19.8%
Dockerfile 1%