repos
/ orchard main

orchard

mirror

Every site I host, in one repo, along with the Cloudflare Tunnel and Caddy that front them. It's all Go, Vite, and SQLite, and it runs on a desktop at home with nothing listening on an inbound port.

blogbuncaddycloudflare-tunneldockergogolanghomelabhtml-templatemonorepoself-hostedseosqlitestatic-sitetypstuptime-monitoringviteweb-analytics

1.6 KB · 59 lines · Go Raw History
 1package main
 2
 3import (
 4	"net/http"
 5	"strings"
 6
 7	"auth.bythewood.me/web"
 8)
 9
10// reqContext is where a request came from, as far as the edge can tell.
11//
12// The country and city headers are trustworthy here only because the tunnel is
13// the only way in: no container in this repo publishes a host port, so nothing
14// reaches this process without passing cloudflared and Caddy first. The day one
15// of them is directly reachable, a client can set CF-IPCountry to whatever it
16// likes and the session list starts lying.
17//
18// CF-IPCountry arrives by default. The rest need the "Add visitor location
19// headers" managed transform turned on for the zone, and stay empty without it,
20// which is why nothing below treats an empty one as an error.
21type reqContext struct {
22	IP      string
23	Country string
24	City    string
25	UA      string
26	Ray     string
27}
28
29func requestContext(r *http.Request) reqContext {
30	return reqContext{
31		IP:      web.ClientIP(r),
32		Country: strings.TrimSpace(r.Header.Get("CF-IPCountry")),
33		City:    strings.TrimSpace(r.Header.Get("CF-IPCity")),
34		// Truncated: a user agent is display-only here and some are enormous.
35		UA:  truncate(r.UserAgent(), 300),
36		Ray: r.Header.Get("CF-Ray"),
37	}
38}
39
40// Where reads as a place a person recognises, or as the address when the
41// transform is off and there is nothing better to say.
42func (c reqContext) Where() string {
43	switch {
44	case c.City != "" && c.Country != "":
45		return c.City + ", " + c.Country
46	case c.Country != "":
47		return c.Country
48	default:
49		return c.IP
50	}
51}
52
53func truncate(s string, n int) string {
54	if len(s) <= n {
55		return s
56	}
57	return s[:n]
58}