I port handlers to an error handler that calls my AddSafeHeader function.
I based it on http://golang.org/doc/articles/error_handling.html but it does not use ServeHTTP, so it works with appstats:
http.Handle("/", appstats.NewHandler(util.ErrorHandler(rootHandler)))
Here:
package httputil import ( "appengine" "net/http" "html/template" ) func AddSafeHeaders(w http.ResponseWriter) { w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("X-XSS-Protection", "1; mode=block") w.Header().Set("X-Frame-Options", "SAMEORIGIN") w.Header().Set("Strict-Transport-Security", "max-age=2592000; includeSubDomains") } // Redirect to a fixed URL type redirectHandler struct { url string code int } func (rh *redirectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { Redirect(w, r, rh.url, rh.code) } func Redirect(w http.ResponseWriter, r *http.Request, urlStr string, code int) { AddSafeHeaders(w) http.Redirect(w, r, urlStr, code) } // RedirectHandler returns a request handler that redirects // each request it receives to the given url using the given // status code. func RedirectHandler(url string, code int) http.Handler { return &redirectHandler{url, code} } func ErrorHandler(fn func(appengine.Context, http.ResponseWriter, *http.Request)) func(appengine.Context, http.ResponseWriter, *http.Request) { return func(c appengine.Context, w http.ResponseWriter, r *http.Request) { defer func() { if err, ok := recover().(error); ok { c.Errorf("%v", err) w.WriteHeader(http.StatusInternalServerError) errorTemplate.Execute(w, err) } }() AddSafeHeaders(w) fn(c, w, r) } } // Check aborts the current execution if err is non-nil. func Check(err error) { if err != nil { panic(err) } } var errorTemplate = template.Must(template.New("error").Parse(errorTemplateHTML)) const errorTemplateHTML = ` <html> <head> <title>XXX</title> </head> <body> <h2>An error occurred:</h2> <p>{{.}}</p> </body> </html> `
source share