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

273 lines
8.5 KiB
Markdown

# server18004 🚀
A high-performance, production-ready QR code generation server written in Rust. It utilizes the [Axum](https://github.com/tokio-rs/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
```mermaid
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:
```bash
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:
```bash
# 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:
```toml
# 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.
```text
# 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:
```bash
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)
```bash
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)
```bash
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:
```json
{
"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
```bash
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
```bash
curl -X POST http://localhost:4083/generate \
-H "Content-Type: application/json" \
-d '{
"text": "Hello World",
"format": "base64",
"base64_source": "svg"
}'
```
**Response JSON**:
```json
{
"data": "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMyAzMyIgc2hhcGUtcmVuZGVyaW5nPSJjcmlzcEVkZ2VzIj4...",
"format": "base64",
"source": "svg"
}
```
---
### 3. Domain Management API (Port 4083)
#### GET `/domains`
Retrieves a list of all currently allowed domains.
```bash
curl http://localhost:4083/domains
```
**Response**:
```json
{
"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.
```bash
curl -X POST http://localhost:4083/domains/add \
-H "Content-Type: application/json" \
-d '{"domain": "newdomain.com"}'
```
**Response**:
```json
{
"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.
```bash
curl -X POST http://localhost:4083/domains/remove \
-H "Content-Type: application/json" \
-d '{"domain": "newdomain.com"}'
```
**Response**:
```json
{
"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.
```bash
curl -i http://localhost:4083/health
```
**Response**:
```http
HTTP/1.1 200 OK
content-type: text/plain; charset=utf-8
content-length: 2
```
---
## 🧪 Testing
The codebase has a comprehensive suite of unit tests verifying domain manipulation, Host/IP extraction, and QR encoders.
To run the tests:
```bash
cargo test
```