Site Serving Engine
Relevant source files
The following files were used as context for generating this wiki page:
The Site Serving Engine is the core system responsible for routing and delivering member-generated static content. It manages thousands of individual websites hosted on subdomains of the primary platform.
The engine uses a dual-router architecture to separate the platform's administrative and social functions from the actual member site delivery. It handles subdomain parsing, file system resolution, security guardrails, and the injection of dynamic platform widgets into static HTML pages.
Architecture and Request Routing
The engine operates behind a Caddy reverse proxy that provides wildcard TLS termination via DNS-01 challenges. Once a request reaches the Express application, the server identifies the target site based on the Host header.
Sources: PLAN.md:12-25, src/server.js:105-115
Dual-Router System
The application branches logic into two distinct Express routers:
- Main Router: Handles
puppypad.orgfor signups, dashboards, browse pages, and administration. - Site Router: Handles
name.puppypad.orgfor member content delivery and built-in site widgets.
Sources: src/server.js:107-121, PLAN.md:12-25
The diagram shows the logic path from an incoming request to the final delivery of member content or system errors.
Static File Resolution Logic
The engine resolves URLs to physical files within the data/sites/{username} directory. It includes specific logic for "Clean URLs" and directory indexing.
Sources: src/server.js:230-265, src/util.js:56-65
Resolution Steps
The server follows a prioritized lookup sequence for every request:
- Widget Matching: If the path starts with
/_hw/, the engine routes the request to built-in widget handlers. - Directory Check: If the path is a directory, the engine appends
index.html. - Direct File Match: The engine attempts to serve the file as named.
- Clean URL Fallback: If no extension is provided and the file is missing, the engine appends
.htmlto find a matching page. - Custom Error Page: If the file is missing, the engine looks for
not_found.htmlin the site root before falling back to the system 404.
Sources: src/server.js:240-260, PLAN.md:85-86
Security Guardrails
The engine enforces strict path safety to prevent directory traversal attacks. The safeRel utility validates that all requested paths remain within the member's allocated folder.
Sources: src/util.js:46-54, src/server.js:236-238
| Guardrail | Description | File Reference |
|---|---|---|
| Path Normalization | Converts backslashes to forward slashes and removes redundant segments. | src/util.js:47 |
| Reserved Folders | Blocks member access to the /_hw directory. | src/util.js:51 |
| Traversal Block | Rejects any path containing .. or starting with .. | src/util.js:49 |
| Nosniff Header | Sets X-Content-Type-Options: nosniff on every response. | src/server.js:103 |
Resource Management and Performance
The engine monitors and limits resource consumption to ensure platform stability across all hosted sites.
Bandwidth and Throttling
Every site has a daily bandwidth cap defined in BANDWIDTH_MB. The engine tracks bytes served per UTC day in the database and returns a 429 Too Many Requests error once the limit is reached.
Sources: src/server.js:31-33, src/server.js:211-224
Hotlink Protection
The engine throttles requests for media files (images, audio, video) when the Referer header originates from an external domain. This prevents external sites from consuming a member's bandwidth.
Sources: src/server.js:42, src/server.js:233-235
The sequence shows the hotlink protection mechanism for media assets.
Built-in Widgets and Metadata
The engine provides dynamic features for static sites via the /_hw/ path prefix. These are served as SVGs or iframes to avoid running arbitrary scripts on the main domain.
Sources: src/widgets.js:1-15, src/server.js:160-170
Widget Types
- Hit Counter: An SVG image that updates on every unique hourly view.
- Guestbook: A themed iframe allowing visitors to leave messages.
- Status Line: A short, mono-spaced SVG badge showing the member's current status.
- Last Updated: A badge derived from the
updated_atfield in the user database.
Sources: src/widgets.js:30-60, src/server.js:160-185
Open Graph Integration
The engine automatically injects Open Graph metadata into HTML files. If a member's page has a <head> but lacks an og:image, the engine adds a link to the site's most recent screenshot for social media previews.
Sources: src/server.js:134-142
Configuration Options
The serving behavior is controlled by environment variables that define limits and site metadata.
Sources: src/server.js:11-30
| Variable | Default | Purpose |
|---|---|---|
QUOTA_MB | 500 | Total disk space per member. |
BANDWIDTH_MB | 1024 | Daily bandwidth limit per site. |
MAX_FILE_MB | 5 | Maximum size for a single uploaded file. |
NEW_SITE_HOURS | 24 | Cooldown before a site appears in public directories. |
BASE_URL | - | The root domain of the platform. |
Summary
The Site Serving Engine provides a secure environment for hosting static files by using a dual-router system and strict path validation. It balances static delivery with dynamic features through SVG-based widgets and manages resource consumption via automated bandwidth and hotlink tracking. Re-indexing logic for clean URLs and custom 404 pages ensures a modern browsing experience for legacy-style homepages.
Sources: PLAN.md:5-10, src/server.js:470-480