8.5 KiB
server18004 🚀
A high-performance, production-ready QR code generation server written in Rust. It utilizes the Axum web framework and is highly optimized for maximum execution speed, minimal memory footprint, and low-latency rendering.
The server leverages a multi-port paradigm to separate public restricted QR rendering from internal/unrestricted administration and generation APIs.
🌟 Key Features
- Multi-Port Isolation:
- Port 4081 (SVG): Restricted vector QR generation via catch-all/fallback handler.
- Port 4082 (PNG): Restricted high-speed raster QR generation.
- Port 4084 (AVIF): Restricted high-speed modern AVIF QR generation.
- Port 4083 (API): Unrestricted administration API for domain management and custom generation.
- High-Performance Graphic Encoders:
- PNG Generator: Features custom 4x manual bit-multiplication scaling to a 1-bit Grayscale raster buffer, completely bypassing expensive image scaling filters. Leverages the standard
pngcrate withCompression::FastandFilterType::NoFilterfor low-latency output. - AVIF Generator: Leverages the speed of the
ravifencoder operating in Speed 10 (Fastest) mode with Lossless quality, backed by a custom 4x RGBA scaling loop.
- PNG Generator: Features custom 4x manual bit-multiplication scaling to a 1-bit Grayscale raster buffer, completely bypassing expensive image scaling filters. Leverages the standard
- Smart Reverse-Proxy Support:
- Resolves client hostnames by inspecting
X-Forwarded-Host,X-Real-Host, and standardHostheaders. Compatible with Nginx, HAProxy, and Apache reverse-proxy setups. - Detects request schema (HTTP vs HTTPS) using the
X-Forwarded-Protoheader.
- Resolves client hostnames by inspecting
- Domain Restricted Generation:
- Fallback endpoints validate the requester's base domain against an allowlist.
- A designated default domain (e.g.,
18004.pro) is always allowed.
- Runtime Domain Management:
- Read-optimized, thread-safe memory storage (
Arc<RwLock<HashSet<String>>>). - Dynamic API additions/removals with immediate, safe file persistence.
- Read-optimized, thread-safe memory storage (
🛠️ Port & Routing Architecture
graph TD
subgraph Restricted Ports (Allowlist Validation)
P1[Port 4081: SVG] -->|Catch-all| H_SVG[Handle SVG]
P2[Port 4082: PNG] -->|Catch-all| H_PNG[Handle PNG]
P4[Port 4084: AVIF] -->|Catch-all| H_AVIF[Handle AVIF]
end
subgraph Unrestricted Port
P3[Port 4083: API] -->|POST /generate| API_GEN[Custom QR Generation]
P3 -->|POST /domains/add| API_ADD[Add Domain]
P3 -->|POST /domains/remove| API_REM[Remove Domain]
P3 -->|GET /domains| API_LST[List Domains]
P3 -->|GET /health| API_HLT[Health Check]
end
1. Restricted Endpoints (Ports 4081, 4082, 4084)
These ports use fallback routes (catch-all). Any request path and query string will be automatically translated into a QR code pointing to the origin host & path.
- How it works:
- The server reads the hostname from the incoming headers (checking
X-Forwarded-Host, thenX-Real-Host, thenHost). - The first subdomain is stripped (e.g.,
qr.example.combecomesexample.com). - The base domain is checked against the allowlist. If it's not present (and doesn't match the default domain), a
403 Forbiddenresponse is returned. - If allowed, it generates a QR code encoding
<scheme>://<base-domain><path><query>(e.g.,https://example.com/some/path?ref=123).
- The server reads the hostname from the incoming headers (checking
2. Unrestricted Endpoints (Port 4083)
A standard REST API for programmatic QR generation (without domain restrictions) and runtime control over the allowed domains.
📦 Installation & Setup
Requirements
- Rust (Cargo) 1.70+
Local Development
To run the server locally:
cargo run -- --config-path ./server.conf --domains-path ./domains.conf
Production Deployment
The project comes with a robust installer (install.sh) that builds the release binary, creates a dedicated, unprivileged system user (qrserver), registers config templates, and configures a systemd service:
# 1. Build and install with root/sudo privileges
sudo ./install.sh
# 2. Start and enable the service
sudo systemctl enable --now server18004
# 3. Verify the status and view logs
sudo systemctl status server18004
sudo journalctl -u server18004 -f
⚙️ Configuration
Server Configuration (/etc/server18004/server.conf)
An easy-to-use TOML file configuring server ports and the default domain:
# Port for restricted SVG QR code generation
port_svg = 4081
# Port for restricted PNG QR code generation
port_png = 4082
# Port for unrestricted JSON API
port_api = 4083
# Port for restricted AVIF QR code generation
port_avif = 4084
# Default domain that is always allowed on restricted ports
default_domain = "example.com"
Domains Allowlist (/etc/server18004/domains.conf)
A simple line-based text file. Comments starting with # and blank lines are ignored.
# Allowed base domains
example.com
mycompany.org
testdomain.dev
📖 Sample Usage & API Specifications
1. Fallback QR Code Generation (Restricted Ports)
When navigating to or requesting any path from the restricted ports, a QR code is returned directly.
SVG Format (Port 4081)
Assuming example.com is in the allowed domain list:
curl -i -H "Host: qr.example.com" http://localhost:4081/welcome?user=john
- Result: Returns an
image/svg+xmlpayload containing a QR code that redirects tohttps://example.com/welcome?user=john.
PNG Format (Port 4082)
curl -i -H "Host: qr.example.com" http://localhost:4082/app/download
- Result: Returns an
image/pngpayload containing a QR code encodinghttps://example.com/app/download.
AVIF Format (Port 4084)
curl -i -H "Host: qr.example.com" http://localhost:4084/promo
- Result: Returns an
image/avifpayload containing a QR code encodinghttps://example.com/promo.
2. Programmatic API (Port 4083)
The API port allows custom QR generation with flexible format settings and base64 options.
POST /generate
Generates a QR code for arbitrary text content.
Payload Schema:
{
"text": "Your string here",
"ecl": "L", // Error Correction Level: L, M, Q, H (Default: L)
"format": "svg", // Output: svg, png, avif, base64, base64url (Default: svg)
"base64_source": "png", // For base64: png, svg, avif (Default: png)
"module_size": 10 // Optional custom scaling factor
}
Example 1: Direct PNG Output
curl -X POST http://localhost:4083/generate \
-H "Content-Type: application/json" \
-d '{
"text": "https://rust-lang.org",
"format": "png",
"ecl": "M"
}' --output qr.png
Example 2: Base64 Encoded JSON Response
curl -X POST http://localhost:4083/generate \
-H "Content-Type: application/json" \
-d '{
"text": "Hello World",
"format": "base64",
"base64_source": "svg"
}'
Response JSON:
{
"data": "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMyAzMyIgc2hhcGUtcmVuZGVyaW5nPSJjcmlzcEVkZ2VzIj4...",
"format": "base64",
"source": "svg"
}
3. Domain Management API (Port 4083)
GET /domains
Retrieves a list of all currently allowed domains.
curl http://localhost:4083/domains
Response:
{
"success": true,
"message": "3 domain(s) configured",
"domains": ["example.com", "mycompany.org", "testdomain.dev"]
}
POST /domains/add
Adds a domain to the allowlist and immediately persists it to the configuration file on disk.
curl -X POST http://localhost:4083/domains/add \
-H "Content-Type: application/json" \
-d '{"domain": "newdomain.com"}'
Response:
{
"success": true,
"message": "Domain 'newdomain.com' added successfully",
"domains": ["example.com", "mycompany.org", "testdomain.dev", "newdomain.com"]
}
POST /domains/remove
Removes a domain from the allowlist and updates the file on disk.
curl -X POST http://localhost:4083/domains/remove \
-H "Content-Type: application/json" \
-d '{"domain": "newdomain.com"}'
Response:
{
"success": true,
"message": "Domain 'newdomain.com' removed successfully",
"domains": ["example.com", "mycompany.org", "testdomain.dev"]
}
GET /health
Simple health check endpoint for proxy checking or system monitors.
curl -i http://localhost:4083/health
Response:
HTTP/1.1 200 OK
content-type: text/plain; charset=utf-8
content-length: 2
OK
🧪 Testing
The codebase has a comprehensive suite of unit tests verifying domain manipulation, Host/IP extraction, and QR encoders.
To run the tests:
cargo test