MCPcopy
hub / github.com/PatchMon/PatchMon / CORS

Function CORS

server-source-code/internal/middleware/cors.go:27–134  ·  view source on GitHub ↗

CORS returns a middleware that sets CORS headers and enforces origin restrictions. When dynamicResolver is non-nil and returns (origin, true), that origin is used for the request (e.g. per-host: scheme + "://" + X-Forwarded-Host). When it returns ("", false), the static origin string is used (singl

(origin string, dynamicResolver OriginResolver)

Source from the content-addressed store, hash-verified

25// Internal requests (health checks, agent connections) that bypass nginx
26// won't have X-Forwarded-Host and are not affected.
27func CORS(origin string, dynamicResolver OriginResolver) func(http.Handler) http.Handler {
28 origins := parseOrigins(origin)
29 allowedHosts := buildAllowedHosts(origins)
30 wildcard := hasWildcard(origins)
31
32 return func(next http.Handler) http.Handler {
33 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
34 var effectiveOrigins []string
35 var effectiveAllowedHosts map[string]bool
36 effectiveWildcard := wildcard
37
38 if dynamicResolver != nil {
39 if dynOrigin, ok := dynamicResolver(r); ok && dynOrigin != "" {
40 effectiveOrigins = []string{dynOrigin}
41 effectiveAllowedHosts = buildAllowedHosts(effectiveOrigins)
42 effectiveWildcard = false
43 }
44 }
45 if len(effectiveOrigins) == 0 {
46 effectiveOrigins = origins
47 effectiveAllowedHosts = allowedHosts
48 }
49
50 reqOrigin := r.Header.Get("Origin")
51
52 allowOrigin := ""
53 for _, o := range effectiveOrigins {
54 if o == "*" {
55 allowOrigin = "*"
56 break
57 }
58 if o == reqOrigin {
59 allowOrigin = reqOrigin
60 break
61 }
62 }
63
64 // Enforce allowed hosts via X-Forwarded-Host on all requests when present.
65 // Blocks access from disallowed URLs before the login page loads.
66 // Internal requests (health checks, agents) have no X-Forwarded-Host and pass through.
67 if !effectiveWildcard {
68 if fwdHost := r.Header.Get("X-Forwarded-Host"); fwdHost != "" {
69 if !effectiveAllowedHosts[strings.ToLower(fwdHost)] {
70 // Set CORS headers so the browser allows the client to read this 403.
71 reflectOrigin := reqOrigin
72 if reflectOrigin == "" {
73 reflectOrigin = EffectiveOrigin(r, fwdHost)
74 }
75 if reflectOrigin != "" {
76 w.Header().Set("Access-Control-Allow-Origin", reflectOrigin)
77 }
78 w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
79 w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-API-ID, X-API-KEY, X-Device-ID")
80 w.Header().Set("Access-Control-Allow-Credentials", "true")
81 w.Header().Set("Content-Type", "application/json")
82 w.WriteHeader(http.StatusForbidden)
83 _, _ = w.Write([]byte(`{"error":"CORS_ORIGIN mismatch. Access this app via the URL configured in CORS_ORIGIN (.env or Database settings).","code":"cors_mismatch"}`))
84 return

Callers

nothing calls this directly

Calls 8

parseOriginsFunction · 0.85
buildAllowedHostsFunction · 0.85
hasWildcardFunction · 0.85
EffectiveOriginFunction · 0.85
isLoopbackFunction · 0.85
WriteMethod · 0.80
GetMethod · 0.45
SetMethod · 0.45

Tested by

no test coverage detected