forked from
nekomimi.pet/wisp.place-monorepo
Monorepo for Wisp.place. A static site hosting service built on top of the AT Protocol.
1# Wisp Hosting Service
2
3Minimal microservice for hosting static sites from the AT Protocol. Built with Hono and Bun.
4
5## Features
6
7- **Custom Domain Hosting**: Serve verified custom domains
8- **Wisp.place Subdomains**: Serve registered `*.wisp.place` subdomains
9- **DNS Hash Routing**: Support DNS verification via `hash.dns.wisp.place`
10- **Direct File Serving**: Access sites via `/s/:identifier/:site/*` (no DB lookup)
11- **Firehose Worker**: Listens to AT Protocol firehose for new `place.wisp.fs` records
12- **Automatic Caching**: Downloads and caches sites locally on first access or firehose event
13- **SSRF Protection**: Hardened fetch with timeout, size limits, and private IP blocking
14
15## Routes
16
171. **Custom Domains** (`/*`)
18 - Serves verified custom domains (example.com)
19 - DB lookup: `custom_domains` table
20
212. **Wisp Subdomains** (`/*.wisp.place/*`)
22 - Serves registered subdomains (alice.wisp.place)
23 - DB lookup: `domains` table
24
253. **DNS Hash Routing** (`/hash.dns.wisp.place/*`)
26 - DNS verification routing for custom domains
27 - DB lookup: `custom_domains` by hash
28
294. **Direct Serving** (`/s.wisp.place/:identifier/:site/*`)
30 - Direct access without DB lookup
31 - `:identifier` can be DID or handle
32 - Fetches from PDS if not cached
33 - **Automatic HTML path rewriting**: Absolute paths (`/style.css`) are rewritten to relative paths (`/s/:identifier/:site/style.css`)
34
35## Setup
36
37```bash
38# Install dependencies
39bun install
40
41# Copy environment file
42cp .env.example .env
43
44# Run in development
45bun run dev
46
47# Run in production
48bun run start
49```
50
51## Environment Variables
52
53- `DATABASE_URL` - PostgreSQL connection string
54- `PORT` - HTTP server port (default: 3001)
55- `BASE_HOST` - Base domain (default: wisp.place)
56
57## Architecture
58
59- **Hono**: Minimal web framework
60- **Postgres**: Database for domain/site lookups
61- **AT Protocol**: Decentralized storage
62- **Jetstream**: Firehose consumer for real-time updates
63- **Bun**: Runtime and file serving
64
65## Cache Structure
66
67```
68cache/sites/
69 did:plc:abc123/
70 sitename/
71 index.html
72 style.css
73 assets/
74 logo.png
75```
76
77## Health Check
78
79```bash
80curl http://localhost:3001/health
81```
82
83Returns firehose connection status and last event time.
84
85## HTML Path Rewriting
86
87When serving sites via the `/s/:identifier/:site/*` route, HTML files are automatically processed to rewrite absolute paths to work correctly in the subdirectory context.
88
89**What gets rewritten:**
90- `src` attributes (images, scripts, iframes)
91- `href` attributes (links, stylesheets)
92- `action` attributes (forms)
93- `poster`, `data` attributes (media)
94- `srcset` attributes (responsive images)
95
96**What's preserved:**
97- External URLs (`https://example.com/style.css`)
98- Protocol-relative URLs (`//cdn.example.com/script.js`)
99- Data URIs (`data:image/png;base64,...`)
100- Anchors (`/#section`)
101- Already relative paths (`./style.css`, `../images/logo.png`)
102
103**Example:**
104```html
105<!-- Original HTML -->
106<link rel="stylesheet" href="/style.css">
107<img src="/images/logo.png">
108
109<!-- Served at /s/did:plc:abc123/mysite/ becomes -->
110<link rel="stylesheet" href="/s/did:plc:abc123/mysite/style.css">
111<img src="/s/did:plc:abc123/mysite/images/logo.png">
112```
113
114This ensures sites work correctly when served from subdirectories without requiring manual path adjustments.
115
116## Security
117
118### SSRF Protection
119
120All external HTTP requests are protected against Server-Side Request Forgery (SSRF) attacks:
121
122- **5-second timeout** on all requests
123- **Size limits**: 1MB for JSON, 10MB default, 100MB for file blobs
124- **Blocked private IP ranges**:
125 - Loopback (127.0.0.0/8, ::1)
126 - Private networks (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
127 - Link-local (169.254.0.0/16, fe80::/10)
128 - Cloud metadata endpoints (169.254.169.254)
129- **Protocol validation**: Only HTTP/HTTPS allowed
130- **Streaming with size enforcement**: Prevents memory exhaustion from large responses