Skip to content

Latest commit

Β 

History

108 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

moarchan

Rust PostgreSQL JavaScript Protocol: HTTP/2 & SSE Docker Compose License: MIT

A high-performance, real-time 4chan clone built from scratch using Rust (2024 Edition), Axum, Tokio, HTTP/2, Server-Sent Events (SSE), PostgreSQL (LISTEN / NOTIFY), and Vanilla JavaScript (strictly following Douglas Crockford's coding standards).


πŸš€ Key Features

  • HTTP/2 & Real-Time SSE Bus: Multiplexed Server-Sent Events distributed horizontally across instances using PostgreSQL LISTEN / NOTIFY with compact JSON descriptors and database hydration fallback.
  • Stream Backpressure & Lag Resilience: Resilient broadcast channel handling catching Tokio stream lag to emit sync-required events, preventing silent socket disconnects on slow connections.
  • Declarative AEAD Cookie Sessions: Cryptographically sealed client sessions utilizing axum-extra's PrivateCookieJar with 512-bit SHA-512 master key expansion and zero runtime database lookup overhead.
  • Finite Board Capacity & Auto-Pruning: Strictly enforced board limits (100 threads per board) with automated asynchronous cascade deletion of orphaned media files ($O(1)$ storage ceiling).
  • Chronological Bumping & Bump Limit: Real-time thread bumping with bumped_at timestamps, chronological reply ordering via PostgreSQL jsonb_agg, sage bypass, and an automated 300-reply bump limit.
  • Classic & Secure Tripcode Engine: Native parser for traditional (#password) and salted secure (##password) tripcodes with dedicated styling.
  • Pluggable Storage Abstraction: Abstracted StorageBackend trait supporting local disk storage and cloud object stores (S3, MinIO, GCS) with non-blocking concurrent file writes and atomic thumbnail rollbacks.
  • High-Fidelity Fast Thumbnails: High-performance integer downsampling using the image crate with strict dimension bomb defenses (10000x10000px validation), magic-byte format verification, and EXIF metadata stripping.
  • Zero-I/O Template Engine: In-memory pre-cached MiniJinja template rendering compiled directly into RAM on startup for sub-millisecond page and item assembly.
  • Transactional Versioned Migrations: Robust, run-once schema migrations (schema_migrations tracking table) executing within atomic transactions, eliminating boot-time UPDATE backfill bottlenecks.
  • IPv6 Subnet-Aware Rate Limiting: Token-bucket IP rate limiter (2 req/sec, burst 10) with /64 subnet masking to prevent rate-limit evasion through IPv6 address rotation.
  • Double-Submit CSRF Protection: Timing-attack resistant CSRF middleware utilizing subtle::ConstantTimeEq, non-HttpOnly cookie distribution, HTML meta injection, and client-side X-CSRF-Token validation.
  • Pure Crockfordian JavaScript: Modular client-side SPA runtime written with zero usage of this, class, var, new (in application code), or void operators.
  • Componentized Frontend Architecture: Decomposed into dedicated ES modules (post-renderer, tag-hover, reply-box, post-actions, post-form) with explicit lifecycle teardowns to prevent memory leaks.
  • In-Place Image Expansion: Clickable thumbnail expansion within the feed and thread views, with filename links directly opening raw full-resolution uploads in a new tab.
  • HTML5 History API Routing: Clean URLs (/g, /g/thread/a1b2c3d4e, static views) with deep-linking support and History API client navigation.
  • Graceful Shutdown & Draining: Integrated SIGINT/SIGTERM signal listening with active TCP connection draining for both cleartext and ALPN TLS HTTP/2 servers.
  • OWASP Hardened: Includes strict Content Security Policy (CSP), Slowloris protection, XSS sanitization, timing-attack resistant password verification (bcrypt), and defensive security headers (nosniff, DENY, mode=block).

⚠️ Note on User Accounts / Authentication:
The login and registration system (/auth, src/routes/auth.rs) is included strictly as a functional demonstration of the session management, private cookie encryption, and bcrypt capabilities. True to traditional imageboard culture, all board browsing, thread creation, and replying remain completely open, anonymous, and account-free by default.


πŸ› οΈ Tech Stack

  • Backend: Rust (2024 Edition)
  • Web Framework: Axum 0.8 / Axum-Extra 0.12 / Tower / Hyper 1.0
  • Async Runtime: Tokio
  • Database Driver: SQLx (PostgreSQL 16+)
  • Template Engine: MiniJinja (In-Memory Pre-cached)
  • Image Processing: image crate (Fast integer downsampling & magic-byte sniffing)
  • Frontend: Vanilla JavaScript (ES6 Modules, Crockfordian), HTML5, CSS3
  • Protocol: HTTP/2 over TLS (ALPN h2) / Cleartext HTTP / Server-Sent Events (SSE)
  • Sessions: AES-256-GCM Encrypted PrivateCookieJar (axum-extra)

πŸ“‹ Prerequisites

  • Rust 1.85+ (Cargo)
  • PostgreSQL 16+ (or Docker)
  • OpenSSL (optional, for local HTTP/2 TLS certificates)

🏁 Quick Start (Local Development)

1. Clone the Repository

git clone https://github.com/joncody/moarchan.git
cd moarchan

2. Create the Local PostgreSQL Database

Log into your local PostgreSQL CLI and create the database:

CREATE DATABASE moarchan;

3. Configure Environment Variables

Create a .env file in the root project directory:

PORT=9001
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=moarchan
POSTGRES_SSLMODE=disable
SESSION_HASH_KEY=12345678901234567890123456789012
SESSION_BLOCK_KEY=abcdefghijklmnopqrstuvwx12345678
UPLOAD_PATH=./static/images/uploads
UPLOAD_URL_PREFIX=/static/images/uploads
VIEWS_PATH=./static/views

(Optional: For local ALPN HTTP/2 over TLS, generate self-signed certificates:)

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost"

4. Build and Run

cargo run --release

Navigate to http://localhost:9001 (or https://localhost:9001 if TLS certs are present) in your browser.


🐳 Running with Docker Compose

If you prefer running the application and database together in containerized environments:

docker-compose up --build

βš™οΈ Environment Configuration Reference

Environment Variable Default Value Description
PORT 9001 Server HTTP port
POSTGRES_HOST localhost PostgreSQL host address
POSTGRES_PORT 5432 PostgreSQL port
POSTGRES_USER postgres PostgreSQL username
POSTGRES_PASSWORD postgres PostgreSQL password
POSTGRES_DB moarchan Database name
POSTGRES_SSLMODE disable SSL mode (disable, require, verify-full)
SESSION_HASH_KEY (32 bytes) Secret key for deriving session master key
SESSION_BLOCK_KEY (32 bytes) Secret key for deriving session master key
UPLOAD_PATH ./static/images/uploads Local filesystem base path for media storage
UPLOAD_URL_PREFIX /static/images/uploads Public URL prefix for uploaded media assets
VIEWS_PATH ./static/views Directory path containing HTML templates
TLS_CERT_PATH (optional) Path to PEM-encoded TLS certificate file
TLS_KEY_PATH (optional) Path to PEM-encoded TLS private key file

πŸ—οΈ Project Architecture

.
β”œβ”€β”€ Cargo.toml            # Project dependencies & build manifest
β”œβ”€β”€ docker-compose.yml    # Container orchestration setup
β”œβ”€β”€ .env                  # Local environment configuration (git-ignored)
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main.rs           # Application bootstrap, graceful shutdown & server launch
β”‚   β”œβ”€β”€ config.rs         # Environment variable configuration loader
β”‚   β”œβ”€β”€ state.rs          # Thread-safe global AppState & cookie key container
β”‚   β”œβ”€β”€ error.rs          # Unified error handling & HTTP response conversion
β”‚   β”œβ”€β”€ db/
β”‚   β”‚   β”œβ”€β”€ mod.rs        # DB module entrypoint
β”‚   β”‚   β”œβ”€β”€ migrations.rs # Versioned transactional schema migrations
β”‚   β”‚   └── queries.rs    # Domain SQL queries & aggregate builders
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”œβ”€β”€ mod.rs        # Middleware module entrypoint
β”‚   β”‚   β”œβ”€β”€ csrf.rs       # Double-submit cookie CSRF middleware
β”‚   β”‚   β”œβ”€β”€ rate_limit.rs # IPv6 /64 subnet-aware token-bucket rate limiter
β”‚   β”‚   └── security.rs   # Content Security Policy (CSP) & defensive headers
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”œβ”€β”€ mod.rs        # Models module entrypoint
β”‚   β”‚   β”œβ”€β”€ auth.rs       # User authentication & session models
β”‚   β”‚   β”œβ”€β”€ post.rs       # Thread, Reply & File models
β”‚   β”‚   └── sse.rs        # Event envelope models
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”œβ”€β”€ mod.rs        # Master Axum router builder
β”‚   β”‚   β”œβ”€β”€ auth.rs       # Login, registration & session handlers (PrivateCookieJar)
β”‚   β”‚   β”œβ”€β”€ pages.rs      # HTML base shell & SPA dynamic render handlers
β”‚   β”‚   └── api/
β”‚   β”‚       β”œβ”€β”€ mod.rs    # API subrouter
β”‚   β”‚       β”œβ”€β”€ threads.rs# Thread creation & auto-pruning endpoint
β”‚   β”‚       β”œβ”€β”€ replies.rs# Reply creation & bump limit endpoint
β”‚   β”‚       β”œβ”€β”€ delete.rs # Post/file deletion endpoint
β”‚   β”‚       └── stream.rs # Real-time SSE stream & lag recovery endpoint
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ mod.rs        # Services module entrypoint
β”‚   β”‚   β”œβ”€β”€ auth.rs       # Bcrypt password verification & hashing
β”‚   β”‚   β”œβ”€β”€ image.rs      # Thumbnailing, magic-byte checking & EXIF stripping
β”‚   β”‚   β”œβ”€β”€ sanitizer.rs  # HTML escaping, tripcode engine & quote parsing
β”‚   β”‚   └── sse.rs        # Distributed Postgres LISTEN/NOTIFY SSE hub
β”‚   └── storage/
β”‚       β”œβ”€β”€ mod.rs        # Pluggable StorageBackend trait
β”‚       └── local.rs      # Concurrent local filesystem storage implementation
└── static/
    β”œβ”€β”€ css/              # Reset, post, thread, reply & screen stylesheet rules
    β”œβ”€β”€ images/           # Application graphics & upload directory
    β”‚   └── uploads/      # Image uploads (git-ignored)
    β”œβ”€β”€ js/
    β”‚   β”œβ”€β”€ frame.js      # Crockfordian SPA runtime (History API + SSE)
    β”‚   β”œβ”€β”€ dom.js        # Lightweight DOM manipulation library
    β”‚   β”œβ”€β”€ components/   # Modular UI components
    β”‚   β”‚   β”œβ”€β”€ topics-map.js     # Board slugs & descriptions map
    β”‚   β”‚   β”œβ”€β”€ post-renderer.js  # JSON-to-DOM HTML builder
    β”‚   β”‚   β”œβ”€β”€ tag-hover.js      # Quote preview tooltips & jump links
    β”‚   β”‚   β”œβ”€β”€ reply-box.js      # Draggable Quick Reply modal
    β”‚   β”‚   β”œβ”€β”€ post-actions.js   # Collapse, hide, & in-place image expansion
    β”‚   β”‚   └── post-form.js      # Form submissions & validation
    β”‚   └── controllers/
    β”‚       β”œβ”€β”€ auth.js   # Auth controller (Demo)
    β”‚       β”œβ”€β”€ main.js   # Homepage controller
    β”‚       └── service.js# Imageboard thread/reply orchestrator
    └── views/            # MiniJinja HTML templates

πŸ“œ License

Distributed under the MIT License. See LICENSE for more information.

About

Real-time anonymous imageboard engine (classic 4chan style) powered by HTTP/2.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages