Skip to content

ohugonnot/sharebox

Repository files navigation

ShareBox

Self-hosted file sharing with built-in video streaming.

PHP 8.1+ SQLite Tests License: MIT

Share files and folders instantly with human-readable links. Stream videos directly in the browser with on-the-fly transcoding -- no pre-processing required.

Admin Panel

Folder Sharing

Video Streaming

Features

  • Zero runtime dependencies -- pure PHP, no framework. Composer used only for dev tooling (PHPUnit)
  • SQLite database -- auto-created on first use, zero configuration
  • Human-readable links -- slugs generated from filenames (e.g., /dl/batman-begins-2005-x7k2)
  • Password protection -- optional, bcrypt-hashed
  • Expiration -- set links to auto-expire after a given duration
  • System dashboard -- real-time server metrics in the admin panel
    • 4 metric cards: CPU (%), RAM, Disk (usage + I/O busy%), Network (upload/download MB/s)
    • Color-coded status pills (green/orange/red) visible even when collapsed
    • 7-day bandwidth history chart (Chart.js, gradient area fills, dark tooltips)
    • Active torrent list via rtorrent SCGI XML-RPC (filtered ≥ 50 KB/s, sorted by speed)
    • Adaptive polling: 10 s when expanded, 60 s pill-only when collapsed
    • CPU & HDD temperature monitoring (coretemp + drivetemp kernel module)
    • Accordion and graph state persisted in localStorage
  • Video streaming -- built-in player with ffmpeg transcoding
    • Probe-first stream selection -- ffprobe before playback: H.264 → remux (near-zero CPU), HEVC/AV1 → transcode
    • Smart remux for H.264: repackage to fMP4 without re-encoding video, audio transcoded to AAC
    • Full transcode for HEVC/x265/AV1 and incompatible codecs (libx264 ultrafast)
    • PGS/VOBSUB burn-in -- image subtitles (BluRay PGS, DVD VOBSUB) burned into the stream via filter_complex; scale2ref ensures correct positioning regardless of source resolution or anamorphic SAR
    • Adaptive quality: 480p, 720p, 1080p
    • Seek support in all stream modes (keyframe-accurate)
    • Audio track selection
    • Subtitle track selection: text tracks extracted to WebVTT (JS overlay), image tracks burned in
    • ffprobe results cached in SQLite (instant reload, no re-probe on unchanged files)
    • vmtouch page-cache warming for files < 2 GB (reduces I/O latency at stream start)
    • A/V sync hardening: aresample async=3000 (no first_pts=0 in remux — preserves video PTS alignment), -g 50, -thread_queue_size 512, -max_muxing_queue_size 1024
    • Probe fallback proactive restart -- if ffprobe resolves within 5 s of a native fallback start and the optimal mode differs (e.g. HEVC detected), stream restarts immediately in the correct mode instead of waiting for a browser error cascade
    • Stall watchdog with exponential backoff -- retry timeout grows as base × 2^n (cap 2 min), differentiated by mode: remux 10 s, transcode 20 s, burn-in 30 s; stall counter resets after 30 s of uninterrupted playback
    • Resync button -- one-click A/V resync at current position without reloading the page
    • Keyboard shortcuts -- Space/K play-pause, ←/→ seek ±10 s (OSD feedback ⏪/⏩), ↑/↓ volume ±5%, F fullscreen, M mute, 0–9 jump to N×10%, ? keyboard help overlay; Ctrl/Meta/Alt modifier bypasses all shortcuts so browser shortcuts (Ctrl+F, etc.) remain unaffected
    • Keyboard help overlay -- press ? (or Escape to close) to display all shortcuts; built with DOM APIs, no innerHTML
    • Instant tap response -- single tap triggers play/pause immediately (no 250 ms delay); double-tap (< 300 ms) undoes the tap and toggles fullscreen
    • Playback speed -- 0.5×, 0.75×, 1×, 1.5×, 2× cycle via speed button; persisted in localStorage
    • Volume slider -- compact range input with orange fill; localStorage writes debounced 500 ms (slider and scroll wheel share the same timer); volume, mute, playback speed and per-file subtitle track selection persisted in localStorage
    • iOS fullscreen -- player.webkitEnterFullscreen() on iOS Safari (requestFullscreen on <div> is unsupported on WebKit); fullscreen button icon synced via webkitbeginfullscreen / webkitendfullscreen events
    • Seekbar tooltip -- hover preview shows timecode at cursor position
    • Binary search subtitle cue lookup (O(log n) on seek, O(1) amortized forward)
    • rAF throttle on timeupdate -- all seek-bar DOM writes go through requestAnimationFrame
  • Folder sharing -- browsable directory listing with per-file download
  • ZIP download -- download entire folders as a single ZIP archive
  • QR code generation -- pure JavaScript, no external library
  • Email sharing -- send download links directly via email
  • Dark theme UI -- clean, modern, mobile-responsive interface
  • Efficient file serving -- nginx X-Accel-Redirect (sendfile) support
  • Admin panel -- protected by HTTP basic auth, manage all share links
  • CSRF protection -- token-based protection on all admin actions
  • Security hardened -- session fixation prevention, mail header injection protection, ZIP size limits
  • PHPUnit test suite -- 69 tests covering security, slug generation, file format utilities, dashboard APIs
  • SQLite probe cache -- probe_cache table stores ffprobe results keyed by path+mtime; net_speed table stores 1-min bandwidth samples with 7-day rolling purge

Requirements

Requirement Minimum
PHP 8.1+
SQLite 3.x (via PHP PDO)
ffmpeg / ffprobe Required for video streaming
Web server nginx (recommended) or Apache
Cron (optional) For bandwidth history graph: * * * * * www-data php /srv/share/cron/record_netspeed.php

PHP extensions needed: pdo_sqlite, session, json (usually enabled by default).

Quick Start

One-line installer (Debian/Ubuntu)

curl -fsSL https://raw.githubusercontent.com/ohugonnot/sharebox/main/install.sh | sudo bash

The installer will:

  • Install all dependencies (PHP, ffmpeg, web server)
  • Ask for your files directory, admin username and password
  • Auto-detect and configure nginx or Apache
  • Set up HTTP basic auth and permissions
  • Get you running in under 2 minutes

Manual installation

Click to expand manual steps

1. Clone the repository

git clone https://github.com/ohugonnot/sharebox.git /var/www/sharebox
cd /var/www/sharebox

2. Create your configuration

cp config.example.php config.php

Edit config.php and set BASE_PATH to the directory you want to share files from.

3. Set permissions

# The data/ directory must be writable by the web server
mkdir -p data
chown www-data:www-data data

4. Configure your web server

See Nginx Setup or Apache Setup below.

5. Protect the admin panel

Create an htpasswd file for basic auth:

apt install apache2-utils   # if not already installed
htpasswd -c /etc/sharebox.htpasswd admin

Web Server Configuration

Nginx

Copy nginx.conf.example to your nginx configuration and adapt paths as needed.

Key points:

  • The admin panel (/share) is protected by HTTP basic auth.
  • Public download URLs (/dl/...) are unauthenticated.
  • X-Accel-Redirect is used for efficient file serving (the internal location).
  • The data/ directory is blocked from direct access.
cp nginx.conf.example /etc/nginx/sites-available/sharebox.conf
# Edit the file, then:
ln -s /etc/nginx/sites-available/sharebox.conf /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

Apache

ShareBox ships with an .htaccess file that handles URL rewriting for Apache. Make sure:

  1. mod_rewrite is enabled:

    a2enmod rewrite
  2. Your virtual host allows .htaccess overrides:

    <Directory /var/www/sharebox>
        AllowOverride All
    </Directory>
  3. Protect the admin panel with basic auth. The .htaccess file includes rules for this -- create the password file:

    htpasswd -c /etc/sharebox.htpasswd admin
  4. Reload Apache:

    systemctl reload apache2

Note: Apache does not support X-Accel-Redirect. ShareBox will fall back to serving files directly through PHP when XACCEL_PREFIX is empty. Set XACCEL_PREFIX to '' in your config.php when using Apache.


Configuration

All configuration is in config.php:

// Root directory for file browsing and sharing
define('BASE_PATH', '/path/to/your/files/');

// SQLite database path (auto-created)
define('DB_PATH', __DIR__ . '/data/share.db');

// X-Accel-Redirect prefix for nginx (set to '' for Apache)
define('XACCEL_PREFIX', '/internal-download');

// Base URL for download links
define('DL_BASE_URL', '/dl/');
Constant Description
BASE_PATH Absolute path to the directory tree you want to share from. All shared files must be under this path.
DB_PATH Path to the SQLite database file. Default: data/share.db relative to the app.
XACCEL_PREFIX Nginx internal redirect prefix. Must match the location block in your nginx config. Set to '' for Apache.
DL_BASE_URL URL prefix for public download links. Must match your web server rewrite rules.
MAX_ZIP_SIZE Maximum total size for ZIP downloads (bytes). Default: 10 GB.

Security Notes

  • The admin panel (index.php, ctrl.php) must be protected by HTTP basic auth at the web server level. There is no built-in login system.
  • The data/ directory contains the SQLite database and must not be publicly accessible. Both the nginx config and .htaccess block access to it.
  • Path traversal is prevented: all file paths are resolved with realpath() and validated against BASE_PATH.
  • Share passwords are hashed with bcrypt (password_hash / password_verify).
  • Password brute-force protection -- failed attempts increment a per-token session counter; sleep(1) on each failure, requests blocked after 10 attempts until the session is reset.
  • Public download URLs (/dl/...) are the only unauthenticated endpoints.
  • PHP execution is disabled in download-related locations to prevent code injection.
  • CSRF tokens verified with hash_equals on all POST actions.
  • session_regenerate_id(true) after password authentication to prevent session fixation.
  • Mail header sanitisation prevents header injection attacks.
  • ZIP download size is capped by MAX_ZIP_SIZE (default 10 GB).
  • Internal PHP files (db.php, config.php, functions.php) are blocked by nginx.
  • HTTP security headers: X-Frame-Options, X-Content-Type-Options, Referrer-Policy.
  • Subtitle extraction endpoint (?subtitle=N) serves same-origin only -- no Access-Control-Allow-Origin header emitted.
  • HTTPS is strongly recommended. Use Let's Encrypt or a similar CA for production deployments.

Project Structure

sharebox/
├── install.sh          # One-line automated installer
├── config.php          # Your local configuration (not tracked)
├── config.example.php  # Example configuration template
├── db.php              # SQLite database layer (auto-creates tables)
├── ctrl.php            # JSON API (browse, create, delete, email)
├── index.php           # Admin panel UI
├── download.php        # Public download handler & video player
├── app.js              # Admin panel JavaScript
├── dashboard.php               # System dashboard HTML (included in index.php)
├── dashboard.js                # Dashboard JS — polling, Chart.js, localStorage
├── api/
│   ├── dashboard_helpers.php   # Testable pure parsers (/proc/*, hwmon)
│   ├── sysinfo.php             # CPU / RAM / Disk / I/O (500 ms window)
│   ├── speed.php               # Instantaneous network speed (8 s cache)
│   ├── netspeed_history.php    # 7-day hourly-aggregated bandwidth history
│   └── active_torrents.php     # rtorrent SCGI XML-RPC interface
├── cron/
│   └── record_netspeed.php     # 1-min cron → net_speed table, 7-day purge
├── style.css           # Styles (dark theme)
├── favicon.svg         # App icon
├── nginx.conf.example  # Nginx configuration template
├── functions.php       # Shared utility functions (slug, path validation, mime)
├── .htaccess           # Apache rewrite rules
├── composer.json       # Dev dependencies (PHPUnit)
├── phpunit.xml         # Test configuration
├── tests/              # PHPUnit test suite
│   ├── SecurityTest.php
│   ├── SlugTest.php
│   ├── FormatAndMimeTest.php
│   ├── SemaphoreTest.php
│   ├── DashboardSysinfoTest.php
│   ├── DashboardSpeedTest.php
│   └── DashboardTorrentsTest.php
├── data/               # SQLite database (auto-created, gitignored)
│   └── share.db
└── LICENSE

Testing

composer install
vendor/bin/phpunit

The test suite covers:

  • Security — token regex validation, path traversal prevention (including symlinks)
  • Slug generation — film names, accents, truncation, uniqueness, collision avoidance
  • File utilities — size formatting, MIME type detection, media type classification
  • Concurrency — stream slot acquisition and release

License

MIT

About

Self-hosted file sharing with built-in video streaming

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors