| 33 | } |
| 34 | |
| 35 | func CSPMiddleware(next http.Handler) http.Handler { |
| 36 | // To use the same nonces in all responses, move the Nonces |
| 37 | // struct creation to here, outside the handler. |
| 38 | |
| 39 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 40 | // Create a new Nonces struct for every request when here. |
| 41 | // move to outside the handler to use the same nonces in all responses |
| 42 | nonceSet := Nonces{ |
| 43 | Htmx: generateRandomString(16), |
| 44 | ResponseTargets: generateRandomString(16), |
| 45 | Tw: generateRandomString(16), |
| 46 | HtmxCSSHash: "sha256-pgn1TCGZX6O77zDvy0oTODMOxemn0oj0LeCnQTRj7Kg=", |
| 47 | } |
| 48 | |
| 49 | // set nonces in context |
| 50 | ctx := context.WithValue(r.Context(), NonceKey, nonceSet) |
| 51 | // insert the nonces into the content security policy header |
| 52 | cspHeader := fmt.Sprintf("default-src 'self'; script-src 'nonce-%s' 'nonce-%s' ; style-src 'nonce-%s' '%s';", |
| 53 | nonceSet.Htmx, |
| 54 | nonceSet.ResponseTargets, |
| 55 | nonceSet.Tw, |
| 56 | nonceSet.HtmxCSSHash) |
| 57 | w.Header().Set("Content-Security-Policy", cspHeader) |
| 58 | |
| 59 | next.ServeHTTP(w, r.WithContext(ctx)) |
| 60 | }) |
| 61 | } |
| 62 | |
| 63 | func TextHTMLMiddleware(next http.Handler) http.Handler { |
| 64 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |