;; lib/dream/headers.sx — Dream-on-SX security headers + cache-control helpers. ;; Depends on types.sx. ;; ── security headers middleware ──────────────────────────────────── (define dream-security-defaults {:x-frame-options "DENY" :referrer-policy "no-referrer" :x-content-type-options "nosniff" :hsts false}) (define dr/apply-security (fn (opts resp) (let ((r1 (dream-add-header (dream-add-header (dream-add-header resp "x-content-type-options" (get opts :x-content-type-options)) "x-frame-options" (get opts :x-frame-options)) "referrer-policy" (get opts :referrer-policy)))) (if (get opts :hsts) (dream-add-header r1 "strict-transport-security" "max-age=31536000; includeSubDomains") r1)))) (define dream-security-headers-with (fn (opts) (fn (next) (fn (req) (dr/apply-security opts (next req)))))) (define dream-security-headers (dream-security-headers-with dream-security-defaults)) ;; ── cache-control response helpers ───────────────────────────────── (define dream-cache (fn (resp seconds) (dream-add-header resp "cache-control" (str "public, max-age=" seconds)))) (define dream-private-cache (fn (resp seconds) (dream-add-header resp "cache-control" (str "private, max-age=" seconds)))) (define dream-no-store (fn (resp) (dream-add-header resp "cache-control" "no-store"))) (define dream-no-cache (fn (resp) (dream-add-header resp "cache-control" "no-cache, no-store, must-revalidate"))) ;; cache-control middleware: stamp a max-age on every response (define dream-cache-for (fn (seconds) (fn (next) (fn (req) (dream-cache (next req) seconds)))))