I am making simple web app using http/server and I use following code for handling routes (credit to this post):
package retable
import (
"context"
"fmt"
"net/http"
"regexp"
"strconv"
"strings"
)
var routes = []route{
newRoute("GET", "/", home),
}
func newRoute(method, pattern string, handler http.HandlerFunc) route {
return route{method, regexp.MustCompile("^" + pattern + "$"), handler}
}
type route struct {
method string
regex *regexp.Regexp
handler http.HandlerFunc
}
func Serve(w http.ResponseWriter, r *http.Request) {
var allow []string
for _, route := range routes {
matches := route.regex.FindStringSubmatch(r.URL.Path)
if len(matches) > 0 {
if r.Method != route.method {
allow = append(allow, route.method)
continue
}
ctx := context.WithValue(r.Context(), ctxKey{}, matches[1:])
route.handler(w, r.WithContext(ctx))
return
}
}
if len(allow) > 0 {
w.Header().Set("Allow", strings.Join(allow, ", "))
http.Error(w, "405 method not allowed", http.StatusMethodNotAllowed)
return
}
http.NotFound(w, r)
}
type ctxKey struct{}
func getField(r *http.Request, index int) string {
fields := r.Context().Value(ctxKey{}).([]string)
return fields[index]
}
func home(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "home\n")
}
How to serve static files from local "static/" folder on "/" endpoint if other route registration on this endpoint already exists?
As written, your code expects an exact match for the pattern provided when constructing a route. (See the ^ and $ when constructing the regex.) So you will not be able to handle /static/ requests in the /-pattern's handler.
You may be able to achieve what you want if you make changes to your existing code though. Some options below.
Option 1
Include the static pattern in routes:
var routes = []route{
newRoute("GET", "/", home),
newRoute("GET", "/static/(.+)", static),
}
Define an example static HTTP handler function:
func static(w http.ResponseWriter, r *http.Request) {
log.Println("received static request for ", getField(r, 0))
}
You may want to use a combination of the following to faciliate serving static files:
http.StripPrefix
http.FileServer
http.Dir / http.FS, which embed plays well with
Option 2
Modify newRoute to not use ^ and $ when constructing the regex. However, this may affect expectations elsewhere in your code. Particularly, the / pattern will match all requests, so the ordering of the routes slice becomes important.
return route{method, regexp.MustCompile(pattern), handler}
Then in home:
func home(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.URL.Path, "/static/") {
log.Println("received static request", r.URL.Path)
// TODO: actually respond with file
return
}
fmt.Fprint(w, "home\n")
}
Footnote
As a footnote, I would recommend using http.ServeMux / http.DefaultServeMux instead of your Serve implementation. These are battle-tested, will likely be more performant, and may likely have less-surprising behavior than your code.
For instance, http.ServeMux/http.DefaultServeMux clean paths, which the code in the question does not do. So, for example, with the original code as in the question, a request for
curl localhost:8080//
will result in a 404 due to the double slash instead of reaching the home handler.
Related
I am fairly new to Go and have not been able to find any information on this, maybe it is just not possible at this time.
I am trying to delete or replace a mux route (using http.NewServeMux, or gorilla's mux.Router). My end goal is to be able to enable/disable a route or set of routes without having to restart the program.
I can probably accomplish this on a handler to handler basis and just return 404 if that feature is "disabled", but I would rather find a more general way to do this since I would like to implement it for every route in my application.
Or would I be better off just keeping track of disabled url patterns and using some middleware to prevent handler execution?
If someone can at least point me in the right direction, I will absolutely post code examples of a solution assuming there is one. Thanks!
There's no built in way, but it is easy enough to implement play.
type HasHandleFunc interface { //this is just so it would work for gorilla and http.ServerMux
HandleFunc(pattern string, handler func(w http.ResponseWriter, req *http.Request))
}
type Handler struct {
http.HandlerFunc
Enabled bool
}
type Handlers map[string]*Handler
func (h Handlers) ServeHTTP(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
if handler, ok := h[path]; ok && handler.Enabled {
handler.ServeHTTP(w, r)
} else {
http.Error(w, "Not Found", http.StatusNotFound)
}
}
func (h Handlers) HandleFunc(mux HasHandleFunc, pattern string, handler http.HandlerFunc) {
h[pattern] = &Handler{handler, true}
mux.HandleFunc(pattern, h.ServeHTTP)
}
func main() {
mux := http.NewServeMux()
handlers := Handlers{}
handlers.HandleFunc(mux, "/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("this will show once"))
handlers["/"].Enabled = false
})
http.Handle("/", mux)
http.ListenAndServe(":9020", nil)
}
Yes you can.
One way to do it is to have a sturct that implement http.Handle interface with the method
ServeHTTP.
Then have the struct contain another muxer like gorilla's
and finally have an atomic Switch to enable/ disable the subrouting
This is a working example of what I mean:
package main
import (
"fmt"
"github.com/gorilla/mux"
"net/http"
"sync/atomic"
)
var recording int32
func isRecording() bool {
return atomic.LoadInt32(&recording) != 0
}
func setRecording(shouldRecord bool) {
if shouldRecord {
atomic.StoreInt32(&recording, 1)
} else {
atomic.StoreInt32(&recording, 0)
}
}
type SwitchHandler struct {
mux http.Handler
}
func (s *SwitchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if isRecording() {
fmt.Printf("Switch Handler is Recording\n")
s.mux.ServeHTTP(w, r)
return
}
fmt.Printf("Switch Handler is NOT Recording\n")
w.WriteHeader(http.StatusNotFound)
fmt.Fprintf(w, "NOT Recording\n")
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/success/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Recording\n")
})
handler := &SwitchHandler{mux: router}
setRecording(false)
http.Handle("/", handler)
http.ListenAndServe(":8080", nil)
}
According to https://github.com/gorilla/mux/issues/82 it is suggested to swap the router instead of deleting routes. Existing connections will stay open.
I am trying to use gorilla mux and httputil.ReverseProxy together, but when trying to get the mux.Vars it is empty. According to https://golang.org/src/net/http/httputil/reverseproxy.go?s=2744:2819#L93 it seems like the http.Request pointer is a shallow copy of the original request, which should still work.
Any ideas?
https://play.golang.org/p/JpjNvEMIFB
package main
import (
"github.com/gorilla/mux"
"log"
"net/http"
"net/http/httputil"
"net/url"
)
type route struct {
match string
base string
}
var routes = []route{
// proxy http://localhost:3000/api/foo/bar => https://api.bar.com/5/foo/bar
route{match: "/api/{path}", base: "https://api.bar.com/5"},
route{match: "/sales/{path}", base: "https://sales.bar.com/3"},
}
func NewProxy(r *route) http.Handler {
director := func(req *http.Request) {
out, _ := url.Parse(r.base)
req.URL.Scheme = out.Scheme
req.URL.Host = out.Host
req.URL.Path = out.Path + "/" + mux.Vars(req)["path"] // mux Vars are empty here
}
return &httputil.ReverseProxy{Director: director}
}
func main() {
for _, route := range routes {
http.Handle(route.match, NewProxy(&route))
}
log.Println("Listening on port 8080")
http.ListenAndServe(":8080", nil)
}
You have two different problems here.
The first one, you are not using a mux.Router, so gorilla/mux has not the opportunity to pre-process your request. In other words, the requests are going directly from http package to your reverse proxies. This issue has an easy fix:
r := mux.NewRouter()
for _, route := range routes {
r.Handle(route.match, NewProxy(&route))
}
http.Handle("/", r)
The second problem is more tricky than the first one. This issue is related to how is mux package implemented. If you look mux.Vars() implementation, you will see that it uses something called Context. A Context, as described in the official documentation, is something that stores values shared during a request lifetime. A simplified Context implementation will be:
type Context map[*http.Request]interface{}
func (c Context) Set(req *http.Request, v interface{}) {
c[req] = v
}
func (c Context) Get(req *http.Request) interface{} {
return c[req]
}
As you see, given a http.Request, we can store values in a context. Later we can retrieve these values using the same Context and the same http.Request. mux uses a global Context to store the vars parsed in routing process so that you can use the standard http.request. But, because httputil.ReverseProxy passes a copy of the actual request and Context links values by request, this new Request has no values in the Context.
To fix it, you can implement your own ReverseProxy based on httputil.ReverseProxy:
type MyReverseProxy struct {
httputil.ReverseProxy
Director func(inr, outr *http.Request)
}
func (p *MyReverseProxy) ServeHTTP(rw http.ResponseWriter, inr *http.Request) {
p.ReverseProxy.Director = func(outr *http.Request) {
p.Director(inr, outr)
}
p.ReverseProxy.ServeHTTP(rw, inr)
}
func NewProxy(r *route) http.Handler {
director := func(inr, outr *http.Request) {
out, _ := url.Parse(r.base)
outr.URL.Scheme = out.Scheme
outr.URL.Host = out.Host
outr.URL.Path = out.Path + "/" + mux.Vars(inr)["path"]
log.Printf("IN VARS: %#v\n", mux.Vars(inr)) // Now inr has proper vars
log.Printf("OUT VARS: %#v\n", mux.Vars(outr))
}
return &MyReverseProxy{Director: director}
You can even use context and keep Director declaration:
type MyReverseProxy struct {
httputil.ReverseProxy
Director func(req *http.Request)
}
func (p *MyReverseProxy) ServeHTTP(rw http.ResponseWriter, inr *http.Request) {
p.ReverseProxy.Director = func(outr *http.Request) {
context.Set(outr, "in_req", inr)
p.Director(outr)
}
p.ReverseProxy.ServeHTTP(rw, inr)
}
func NewProxy(r *route) http.Handler {
director := func(outr *http.Request) {
out, _ := url.Parse(r.base)
inr := context.Get(outr, "in_req").(*http.Request)
outr.URL.Scheme = out.Scheme
outr.URL.Host = out.Host
outr.URL.Path = out.Path + "/" + mux.Vars(inr)["path"]
log.Printf("IN VARS: %#v\n", mux.Vars(inr)) // Now inr has proper vars
log.Printf("OUT VARS: %#v\n", mux.Vars(outr))
}
return &MyReverseProxy{Director: director}
}
Both implementations seem tricky to me. They have to change httputil.ReverseProxy's Director in every call. So, I probably accept that mux is not a good choice here, and instead I will use some simpler solution:
var routes = []route{
route{match: "/api/", base: "https://api.bar.com/5"},
route{match: "/sales/", base: "https://sales.bar.com/3"},
}
func NewProxy(r *route) http.Handler {
director := func(req *http.Request) {
out, _ := url.Parse(r.base)
req.URL.Scheme = out.Scheme
req.URL.Host = out.Host
req.URL.Path = out.Path + "/" + strings.TrimPrefix(req.URL.Path, r.match)
}
return &httputil.ReverseProxy{Director: director}
}
You can read mux source code to implement a complex solution based on regular expressions.
I would like to map each route and it's request type (GET, POST, PUT, ...) to generate something like a sitemap.xml in JSON for my restful API.
Goji uses functions to create a new route. I could store the paths and handlers in a map.
My approach would be something like this, except that the compiler gives the following initialization loop error, because sitemap and routes refer to each other (the routemap contains the handler sitemap that should marhsall itself).
main.go:18: initialization loop:
main.go:18 routes refers to
main.go:41 sitemap refers to
main.go:18 routes
Can this be achieved in a more idiomatic way?
package main
import (
"encoding/json"
"net/http"
"github.com/zenazn/goji"
"github.com/zenazn/goji/web"
)
var routes = []Route{
Route{"Get", "/index", hello},
Route{"Get", "/sitemap", sitemap},
}
type Route struct {
Method string `json:"method"`
Pattern string `json:"pattern"`
Handler web.HandlerType `json:"-"`
}
func NewRoute(method, pattern string, handler web.HandlerType) {
switch method {
case "Get", "get":
goji.DefaultMux.Get(pattern, handler)
case "Post", "post":
goji.DefaultMux.Post(pattern, handler)
// and so on...
}
}
func hello(c web.C, w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello world"))
}
func sitemap(c web.C, w http.ResponseWriter, r *http.Request) {
// BUG: sitemap tries to marshall itself recursively
resp, _ := json.MarshalIndent(routes, "", " ")
// some error handling...
w.Write(resp)
}
func main() {
for _, r := range routes {
NewRoute(r.Method, r.Pattern, r.Handler)
}
goji.Serve()
}
The easiest way to avoid the initialization loop is to break the loop by delaying one of the initializations.
E.g.:
var routes []Route
func init() {
routes = []Route{
Route{"Get", "/index", hello},
Route{"Get", "/sitemap", sitemap},
}
}
With this change your code compiles.
[Edit after chat:]
A fully edited and runnable example that also addresses your question about the switch follows:
package main
import (
"encoding/json"
"net/http"
"github.com/zenazn/goji"
"github.com/zenazn/goji/web"
)
var routes []Route
func init() {
// Initialzed in init() to avoid an initialization loop
// since `routes` refers to `sitemap` refers to `routes`.
routes = []Route{
Route{"Get", "/index", hello},
Route{"Get", "/sitemap", sitemap},
//Route{"Post", "/somewhereElse", postHandlerExample},
}
}
type Route struct {
Method string `json:"method"`
Pattern string `json:"pattern"`
Handler web.HandlerType `json:"-"`
}
var methods = map[string]func(web.PatternType, web.HandlerType){
"Get": goji.Get,
"Post": goji.Post,
// … others?
}
func (r Route) Add() {
//log.Println("adding", r)
methods[r.Method](r.Pattern, r.Handler)
}
func hello(c web.C, w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello world"))
}
func sitemap(c web.C, w http.ResponseWriter, r *http.Request) {
resp, err := json.MarshalIndent(routes, "", " ")
if err != nil {
http.Error(w, "Can't generate response properly.", 500)
return
}
w.Write(resp)
}
func main() {
for _, r := range routes {
r.Add()
}
goji.Serve()
}
Available as a gist.
I'll note there is nothing wrong with a switch like you had it,
and in this case if there are only two methods a map may be overkill.
A previous version of the example
didn't use a map and explicitly specified both the function and method name (which were expected to match).
Also this version doesn't check for invalid method names (which if routes is always hard coded and never changed at runtime is reasonable). It would be straight forward to do fn, ok := methods[r.Method] and do something else if/when !ok if desired.
How do I add the username of the current user, or other variables, to the end of the URL path in Go?
I tried using a http.Redirect(w, "/home/"+user, http.StatusFound), but that would create an infinite redirect loop.
Go:
func homeHandler(w http.ResponseWriter, r *http.Request) {
randIndex = rand.Intn(len(cityLibrary))
ImageDisplay()
WeatherDisplay()
dispdata = AllApiData{Images: imagesArray, Weather: &WeatherData{Temp: celsiusNum, City: cityLibrary[randIndex], RainShine: rainOrShine}}
//http.Redirect(w, "/"+cityLibrary[randIndex], http.StatusFound) --> infinite redirect loop
renderTemplate(w, "home", dispdata)
}
func main() {
http.HandleFunc("/", homeHandler)
http.Handle("/layout/", http.StripPrefix("/layout/", http.FileServer(http.Dir("layout"))))
http.ListenAndServe(":8000", nil)
}
In this code, I'm trying to append the value of "City" to the end of the root URL. Should I be using regexp?
It seems this is happening because you don't have a /{city}/ handler and the / handler is matching all the requests being redirected to cities :
Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both "/images/" and "/images/thumbnails/", the latter handler will be called for paths beginning "/images/thumbnails/" and the former will receive requests for any other paths in the "/images/" subtree.
Note that since a pattern ending in a slash names a rooted subtree, the pattern "/" matches all paths not matched by other registered patterns, not just the URL with Path == "/".
What you need to do is put in the city url handler, if you need to handle RegEx patterns take a look at this or you could use a more powerful router like gorilla's mux.
what just using Go without gorilla? I know how to do it in Gorilla but I'm just wondering how its done in Go.
You make your own custom handlers with as mentioned in the previously mentioned answer :
https://stackoverflow.com/a/6565407/220710
type route struct {
pattern *regexp.Regexp
handler http.Handler
}
type RegexpHandler struct {
routes []*route
}
func (h *RegexpHandler) Handler(pattern *regexp.Regexp, handler http.Handler) {
h.routes = append(h.routes, &route{pattern, handler})
}
func (h *RegexpHandler) HandleFunc(pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request)) {
h.routes = append(h.routes, &route{pattern, http.HandlerFunc(handler)})
}
func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for _, route := range h.routes {
if route.pattern.MatchString(r.URL.Path) {
route.handler.ServeHTTP(w, r)
return
}
}
// no pattern matched; send 404 response
http.NotFound(w, r)
}
To use this then you would do something like this :
import regexp
...
rex := RegexpHandler{}
rex.HandlerFunc(regexp.MustCompile("^/(\w+?)/?"), cityHandler) // cityHandler is your regular handler function
rex.HandlerFunc(regexp.MustCompile("^/"), homeHandler)
http.Handle("/", &rex)
http.ListenAndServe(":8000", nil)
I'm trying to set an http header for multiple handlers. My first thought was to make a custom write function that would set the header before writing the response like the code sample at the bottom.
However, when I pass a pointer to the http.ResponseWriter and try to access it from my function it tells me that "type *http.ResponseWriter has no Header method".
What is the best way to set headers for multiple handlers, and also why isn't the pointer working the way I want it to?
func HelloServer(w http.ResponseWriter, req *http.Request) {
type Message struct {
Name string
Body string
Time int64
}
m := Message{"Alice", "Hello", 1294706395881547000}
b, _ := json.Marshal(m)
WriteJSON(&w, b)
}
func WriteJSON(wr *http.ResponseWriter, rawJSON []byte) {
*wr.Header().Set("Content-Type", "application/json")
io.WriteString(*wr, string(rawJSON))
}
func main() {
http.HandleFunc("/json", HelloServer)
err := http.ListenAndServe(":9000", nil)
if err != nil {
log.Fatal("ListenAndServer: ", err)
}
}
I'm not sure about the multiple handlers thing, but I do know why the code you wrote is failing. The key is that the line:
*wr.Header().Set("Content-Type", "application/json")
is being interpreted, because of operator precedence, as:
*(wr.Header().Set("Content-Type", "application/json"))
Since wr has the type *http.ResponseWriter, which is a pointer to and interface, rather than the interface itself, this won't work. I assume that you knew that, which is why you did *wr. I assume what you meant to imply to the compiler is:
(*wr).Header().Set("Content-Type", "application/json")
If I'm not mistaken, that should compile and behave properly.
You don't need to use *wr as it already references a pointer.
wr.Header().Set("Content-Type", "application/json") should be sufficient.
If you want to set "global" headers for every request, you can create a function that satisfies http.HandleFunc (go.auth has a good example) and then wrap your handlers like so:
http.HandleFunc("/hello", Defaults(helloHandler))
Also take a look at the net/http documentation, which has further examples.
I wrap my handlers with an error handler
which calls my AddSafeHeader function.
I based it on http://golang.org/doc/articles/error_handling.html
but it doesn't 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>
`
http.ResponseWriter is an interface.
You should probably not be using a pointer to an interface. In net/http/server.go, the unexported response struct is the actual type that implements ResponseWriter when the server calls your handler, and importantly, when the server actually calls the handler's ServeHTTP, it passes a *response. It's already a pointer, but you don't see that because ResonseWriter is an interface. (the response pointer is created here, by (c *conn).readRequest. (The links will likely be for the wrong lines the future, but you should be able to locate them).
That's why the ServeHTTP function required to implement Handler is:
ServeHTTP(w ResponseWriter, r *Request)
i.e. not a pointer to ResponseWriter, as this declaration already permits a pointer to a struct that implements the ResponseWriter interface.
As I am new to Go, I created a minimal contrived example, based on elithrar's answer, which shows how to easily add headers to all your routes / responses. We do so, by creating a function that satisfies the http.HandlerFunc interface, then wraps the route handler functions:
package main
import (
"encoding/json"
"log"
"net/http"
"github.com/gorilla/mux"
)
// Hello world.
func Hello(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode("Hello World")
}
// HelloTwo world
func HelloTwo(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode("Hello Two World")
}
// JSONHeaders conforms to the http.HandlerFunc interface, and
// adds the Content-Type: application/json header to each response.
func JSONHeaders(handler http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
handler(w, r)
}
}
func main() {
router := mux.NewRouter()
// Now, instead of calling your handler function directly, pass it into the wrapper function.
router.HandleFunc("/", JSONHeaders(Hello)).Methods("GET")
router.HandleFunc("/hellotwo", JSONHeaders(HelloTwo)).Methods("GET")
log.Fatal(http.ListenAndServe(":3000", router))
}
Results:
$ go run test.go &
$ curl -i localhost:3000/
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 28 Feb 2019 22:27:04 GMT
Content-Length: 14
"Hello World"
What i end up doing:
// Accepts a user supplied http.HandlerFunc and then modifies it in various ways. In this case, it adds two new headers.
func CommonlHandler(h http.HandlerFunc) http.HandlerFunc {
return func (rs http.ResponseWriter, rq *http.Request) {
rs.Header().Add("Server", "Some server")
rs.Header().Add("Cache-Control", "no-store")
h(rs, rq)
}
// somewhere down the line, where you're setting up http request handlers
serveMux := http.NewServeMux()
serveMux.HandleFunc("/", CommonHandler(func(rs http.ResponseWriter, rq *http.Request) {
// Handle request as usual. Since it's wrapped in the CommonHandler and we've set some headers there, responses to requests to "/" will contain those headers.
// Be mindful what modifications you're doing here. If, for ex., you decide you want to apply different caching strategy than the Common one, since this will be passed to the CommonHandler, your changes will be overwritten and lost. So it may be a good idea to introduce checks in CommonHandler to determine whether the header exists, before you decide to create it.
}))
serveMux.HandleFunc("/contact", CommonHandler(func(rs http.ResponseWriter, rq *http.Request) {
// handle another request as usual
}))