From a1f69662006ea6c22b710274b1ba92a1711053a7 Mon Sep 17 00:00:00 2001 From: Grendgi Date: Mon, 15 Jun 2026 11:20:34 +0300 Subject: [PATCH] Add portal header helpers --- middleware/headers.go | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 middleware/headers.go diff --git a/middleware/headers.go b/middleware/headers.go new file mode 100644 index 0000000..177bfc8 --- /dev/null +++ b/middleware/headers.go @@ -0,0 +1,45 @@ +package middleware + +import ( + "net/http" + "strings" +) + +// HeaderBool reads portal-proxy boolean headers. +// Contract: "1", "true", "yes" and "on" are true; everything else is false. +func HeaderBool(r *http.Request, name string) bool { + switch strings.ToLower(strings.TrimSpace(r.Header.Get(name))) { + case "1", "true", "yes", "on": + return true + default: + return false + } +} + +// HeaderCSV returns a trimmed non-empty CSV list from a portal-proxy header. +func HeaderCSV(r *http.Request, name string) []string { + raw := strings.TrimSpace(r.Header.Get(name)) + if raw == "" { + return nil + } + parts := strings.Split(raw, ",") + out := make([]string, 0, len(parts)) + for _, part := range parts { + if v := strings.TrimSpace(part); v != "" { + out = append(out, v) + } + } + return out +} + +// HeaderScope returns a lower-cased scope constrained to allowed values. +// The fallback is returned when the header is empty or unknown. +func HeaderScope(r *http.Request, name, fallback string, allowed ...string) string { + value := strings.ToLower(strings.TrimSpace(r.Header.Get(name))) + for _, option := range allowed { + if value == strings.ToLower(strings.TrimSpace(option)) { + return value + } + } + return fallback +}