Files
server18004/README.md
2026-05-18 11:45:56 +03:00

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 png crate with Compression::Fast and FilterType::NoFilter for low-latency output.
    • AVIF Generator: Leverages the speed of the ravif encoder operating in Speed 10 (Fastest) mode with Lossless quality, backed by a custom 4x RGBA scaling loop.
  • Smart Reverse-Proxy Support:
    • Resolves client hostnames by inspecting X-Forwarded-Host, X-Real-Host, and standard Host headers. Compatible with Nginx, HAProxy, and Apache reverse-proxy setups.
    • Detects request schema (HTTP vs HTTPS) using the X-Forwarded-Proto header.
  • 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.

🛠️ 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:
    1. The server reads the hostname from the incoming headers (checking X-Forwarded-Host, then X-Real-Host, then Host).
    2. The first subdomain is stripped (e.g., qr.example.com becomes example.com).
    3. The base domain is checked against the allowlist. If it's not present (and doesn't match the default domain), a 403 Forbidden response is returned.
    4. If allowed, it generates a QR code encoding <scheme>://<base-domain><path><query> (e.g., https://example.com/some/path?ref=123).

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+xml payload containing a QR code that redirects to https://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/png payload containing a QR code encoding https://example.com/app/download.

AVIF Format (Port 4084)

curl -i -H "Host: qr.example.com" http://localhost:4084/promo
  • Result: Returns an image/avif payload containing a QR code encoding https://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