Monorepo for Tangled tangled.org

markup/sanitizer: build bluemonday policies once at package init

Both policies were rebuilt on every NewSanitizer() call. This included
compiling the chroma syntax-highlight class regex by iterating
chroma.StandardTypes and joining ~200 type names into a regex alternation,
on every invocation — including from inside the pull request HTTP handler,
making it a per-request cost.

Move both policies to package-level vars initialized once in init().
NewSanitizer() is now a pair of pointer assignments. This is safe per the
bluemonday README: "it is safe to use the policy in multiple goroutines".

Signed-off-by: Matías Insaurralde <matias@insaurral.de>

+15 -4
+15 -4
appview/pages/markup/sanitizer.go
··· 10 10 "github.com/microcosm-cc/bluemonday" 11 11 ) 12 12 13 + // shared policies built once at init; safe for concurrent use per bluemonday docs 14 + var ( 15 + sharedDefaultPolicy *bluemonday.Policy 16 + sharedDescriptionPolicy *bluemonday.Policy 17 + ) 18 + 19 + func init() { 20 + sharedDefaultPolicy = buildDefaultPolicy() 21 + sharedDescriptionPolicy = buildDescriptionPolicy() 22 + } 23 + 13 24 type Sanitizer struct { 14 25 defaultPolicy *bluemonday.Policy 15 26 descriptionPolicy *bluemonday.Policy ··· 17 28 18 29 func NewSanitizer() Sanitizer { 19 30 return Sanitizer{ 20 - defaultPolicy: defaultPolicy(), 21 - descriptionPolicy: descriptionPolicy(), 31 + defaultPolicy: sharedDefaultPolicy, 32 + descriptionPolicy: sharedDescriptionPolicy, 22 33 } 23 34 } 24 35 ··· 29 40 return s.descriptionPolicy.Sanitize(html) 30 41 } 31 42 32 - func defaultPolicy() *bluemonday.Policy { 43 + func buildDefaultPolicy() *bluemonday.Policy { 33 44 policy := bluemonday.UGCPolicy() 34 45 35 46 // Allow generally safe attributes ··· 123 134 return policy 124 135 } 125 136 126 - func descriptionPolicy() *bluemonday.Policy { 137 + func buildDescriptionPolicy() *bluemonday.Policy { 127 138 policy := bluemonday.NewPolicy() 128 139 policy.AllowStandardURLs() 129 140