func (s *Secure) HandlerFuncWithNext(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	responseHeader, r, err := s.processRequest(w, r)
	addResponseHeaders(responseHeader, w)
	if err == nil && next != nil {
		next(w, r)
	}
}
HandlerFuncWithNext is a special implementation for Negroni, but could be used elsewhere.
package secure
import (
	"context"
	"fmt"
	"net/http"
	"regexp"
	"strings"
)
type secureCtxKey string
const (
	stsHeader               = "Strict-Transport-Security"
	stsSubdomainString      = "; includeSubDomains"
	stsPreloadString        = "; preload"
	frameOptionsHeader      = "X-Frame-Options"
	frameOptionsValue       = "DENY"
	contentTypeHeader       = "X-Content-Type-Options"
	contentTypeValue        = "nosniff"
	xssProtectionHeader     = "X-XSS-Protection"
	xssProtectionValue      = "1; mode=block"
	cspHeader               = "Content-Security-Policy"
	cspReportOnlyHeader     = "Content-Security-Policy-Report-Only"
	hpkpHeader              = "Public-Key-Pins"
	referrerPolicyHeader    = "Referrer-Policy"
	featurePolicyHeader     = "Feature-Policy"
	permissionsPolicyHeader = "Permissions-Policy"
	expectCTHeader          = "Expect-CT"
	ctxDefaultSecureHeaderKey = secureCtxKey("SecureResponseHeader")
	cspNonceSize              = 16
)
type SSLHostFunc func(host string) (newHost string)
func defaultBadHostHandler(w http.ResponseWriter, r *http.Request) {
	http.Error(w, "Bad Host", http.StatusInternalServerError)
}
type Options struct {
	BrowserXssFilter bool  
	ContentTypeNosniff bool
	ForceSTSHeader bool
	FrameDeny bool
	IsDevelopment bool
	nonceEnabled bool
	SSLRedirect bool
	SSLForceHost bool
	SSLTemporaryRedirect bool
	STSIncludeSubdomains bool
	STSPreload bool
	ContentSecurityPolicy string
	ContentSecurityPolicyReportOnly string
	CustomBrowserXssValue string  
	CustomFrameOptionsValue string
	PublicKey string
	ReferrerPolicy string
	FeaturePolicy string
	PermissionsPolicy string
	SSLHost string
	AllowedHosts []string
	AllowedHostsAreRegex bool
	HostsProxyHeaders []string
	SSLHostFunc *SSLHostFunc
	SSLProxyHeaders map[string]string
	STSSeconds int64
	ExpectCTHeader string
	SecureContextKey string
}
type Secure struct {
	opt Options
	badHostHandler http.Handler
	cRegexAllowedHosts []*regexp.Regexp
	ctxSecureHeaderKey secureCtxKey
}
func New(options ...Options) *Secure {
	var o Options
	if len(options) == 0 {
		o = Options{}
	} else {
		o = options[0]
	}
	o.ContentSecurityPolicy = strings.ReplaceAll(o.ContentSecurityPolicy, "$NONCE", "'nonce-%[1]s'")
	o.ContentSecurityPolicyReportOnly = strings.ReplaceAll(o.ContentSecurityPolicyReportOnly, "$NONCE", "'nonce-%[1]s'")
	o.nonceEnabled = strings.Contains(o.ContentSecurityPolicy, "%[1]s") || strings.Contains(o.ContentSecurityPolicyReportOnly, "%[1]s")
	s := &Secure{
		opt:            o,
		badHostHandler: http.HandlerFunc(defaultBadHostHandler),
	}
	if s.opt.AllowedHostsAreRegex {
		for _, allowedHost := range o.AllowedHosts {
			regex, err := regexp.Compile(fmt.Sprintf("^%s$", allowedHost))
			if err != nil {
				panic(fmt.Sprintf("Error parsing AllowedHost: %s", err))
			}
			s.cRegexAllowedHosts = append(s.cRegexAllowedHosts, regex)
		}
	}
	s.ctxSecureHeaderKey = ctxDefaultSecureHeaderKey
	if len(s.opt.SecureContextKey) > 0 {
		s.ctxSecureHeaderKey = secureCtxKey(s.opt.SecureContextKey)
	}
	return s
}
func (s *Secure) SetBadHostHandler(handler http.Handler) {
	s.badHostHandler = handler
}
func (s *Secure) Handler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		responseHeader, r, err := s.processRequest(w, r)
		addResponseHeaders(responseHeader, w)
		if err != nil {
			return
		}
		h.ServeHTTP(w, r)
	})
}
func (s *Secure) HandlerForRequestOnly(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		responseHeader, r, err := s.processRequest(w, r)
		if err != nil {
			return
		}
		ctx := context.WithValue(r.Context(), s.ctxSecureHeaderKey, responseHeader)
		h.ServeHTTP(w, r.WithContext(ctx))
	})
}