I want to trace complete execution of an HTTP request in golang. For any non trivial operation the request will eventually call many different functions. I would like to have logs from the entire execution stack tagged with a unique request id. e.g.
http.Handle("/my-request", myrequesthandler)
func myrequestHandler(w http.ResponseWriter, r *http.Request) {
//debug print1
log.Printf("....")
myfunc()
}
func myfunc() {
//debug print2
log.Printf("....")
}
Here I need a way to identify print1 and print2 as part of same request. It looks like zerolog does have something like this, as described here. Like so:
....
c = c.Append(hlog.RequestIDHandler("req_id", "Request-Id"))
h := c.Then(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
hlog.FromRequest(r).Info().
Msg("Something happened")
}))
http.Handle("/", h)
But if I understand it right, it will involve passing request object to each and every function. Is this the idiomatic way to solve this problem? What are the alternatives?
Set a unique id on a context.Context as soon as the request is received, and pass that context down the call stack. This is what contexts are for.
[Context] carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.
Example:
// You could place this in a separate helper package to improve encapsulation
type ctxKey struct{}
func myRequestHandler(w http.ResponseWriter, r *http.Request) {
uniqueID := // generate a unique identifier
// create a context with the http.Request context as parent
ctx := context.WithValue(r.Context(), ctxKey{}, uniqueID)
foo(ctx, ...)
bar(ctx, ...)
}
func foo(ctx context.Context, ...) {
uniqueID := ctx.Value(ctxKey{})
// do something with the unique id
baz(ctx, ...)
}
In particular:
Create the context with *http.Request.Context() as parent. This way if the request is canceled, e.g. due to client disconnection, cancellation will propagate to your sub-context
Consider setting the context value using an unexported struct as key. Unexported structs defined in your package will never conflict with other keys. If you use strings as keys instead, any package could in theory use the same key and overwrite your value (or you could overwrite others' values). YMMV.
Pass your context as the first argument of any function in your call stack, as the package documentation recommends.
For tracing and logging across applications, you might want to look into opentracing. Propagation of tracers is still done with Contexts as outlined above.
you can use context.Context and set request id on it via middleware function.
example:
type requestIDKey struct{}
func requestIDSetter(next http.HandlerFunc) http.HandlerFunc {
return func(rw http.ResponseWriter, r *http.Request) {
// use provided request id from incoming request if any
reqID := r.Header.Get("X-Request-ID")
if reqID == "" {
// or use some generated string
reqID = uuid.New().String()
}
ctx := context.WithValue(r.Context(), requestIDKey{}, reqID)
next(rw, r.WithContext(ctx))
}
}
then you need to modify your logger to accept context.Context
example:
func printfWithContext(ctx context.Context, format string, v ...interface{}) {
reqID := ctx.Value(requestIDKey{}).(string)
log.Printf(reqID+": "+format, v...)
}
and finally apply to your code
http.HandleFunc("/my-request", requestIDSetter(myrequestHandler))
func myrequestHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
//debug print1
printfWithContext(ctx, "....1")
myfunc(ctx)
}
func myfunc(ctx context.Context) {
//debug print2
printfWithContext(ctx, "....2")
}
Related
I'm writing an HTTP service in Go using Gorilla. I'm newish to Go (<1yr experience), but ramping up fairly quickly.
I have a function I use to register my handlers:
func (s *Server) RegisterHandler(path string, handler http.HandlerFunc, methods ...string) {
if len(methods) == 0 {
s.Router.Handle(path, handler).Methods(http.MethodGet)
} else {
s.Router.Handle(path, handler).Methods(methods...)
}
}
I have some code that registers named functions as handlers:
func (s *Server) RegisterDefaultHandlers() {
s.RegisterHandler("/ping", Ping)
}
func Ping(w http.ResponseWriter, request *http.Request) {
responders.RespondOk(w)
}
I also have unit test code that registers anonymous functions as handlers:
s.RegisterHandler("/testPath", func(w http.ResponseWriter, r *http.Request) {
// whatever the test calls for
}, http.MethodPost)
This all works great -- just establishing my starting point.
Today, I find myself banging my head against Go's type system. I am defining some custom handler types, for example:
type UserAwareHandlerFunc func(http.ResponseWriter, *http.Request, models.User)
And I'm also introducing a function to allow me to register such handlers, and to wrap all handlers in context.ClearHandler. If this works, I'll also wrap everything with another function that sets a few things on my logging context. What I have so far:
func (s *Server) RegisterHandler(path string, handler interface{}, methods ...string) {
wrappedHandler := wrappers.ApplyWrappers(handler)
if len(methods) == 0 {
s.Router.Handle(path, wrappedHandler).Methods(http.MethodGet)
} else {
s.Router.Handle(path, wrappedHandler).Methods(methods...)
}
}
func ApplyWrappers(handler interface{}) http.Handler {
var result http.Handler
if userAwareHandler, ok := handler.(UserAwareHandlerFunc); ok {
result = UserAware(userAwareHandler)
} else if handlerFunc, ok := handler.(http.HandlerFunc); ok {
result = handlerFunc
} else if handlerObj, ok := handler.(http.Handler); ok {
result = handlerObj
} else {
log.Fatalf("handler %+v (type %s) is not a recognized handler type.", handler, reflect.TypeOf(handler))
}
// to avoid memory leaks, ensure that all request data is cleared by the end of the request lifetime
// for all handlers -- see https://stackoverflow.com/a/48203334
result = context.ClearHandler(result)
return result
}
func UserAware(handler UserAwareHandlerFunc) http.Handler {
return func(w http.ResponseWriter, r *http.Request) {
user := ... // get user from session
handler(w, r, user)
}
}
With these changes, I can no longer register named or anonymous functions; the type assertions in ApplyWrappers all fail. I have to declare and define a typed variable, then pass that in.
Named functions have two feasible approaches:
var Ping http.HandlerFunc = func(w http.ResponseWriter, request *http.Request) {
responders.RespondOk(w)
}
func Ping2(w http.ResponseWriter, request *http.Request) {
responders.RespondOk(w)
}
func (s *Server) RegisterDefaultHandlers() {
s.RegisterHandler("/ping", Ping)
var pingHandler2 http.HandlerFunc = Ping2
s.RegisterHandler("/ping2", pingHandler2)
}
For anonymous functions, I can do:
var handler http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) {
...
}
s.RegisterHandler("/testPath", handler, http.MethodPost)
The whole point of what I've built here is to consolidate boilerplate into one place, keeping my many tests and handlers as streamlined as possible. The need to declare a typed variable is working against that goal. So my question is this: is there some special type magic I could use (preferably in RegisterHandler and/or ApplyWrappers) that would restore the ability to pass named and/or anonymous functions to RegisterHandler?
EDIT: thanks so much for the quick answers. Problem solved:
func ApplyWrappers(handler interface{}) http.Handler {
var result http.Handler
if userAwareHandler, ok := handler.(UserAwareHandlerFunc); ok {
result = UserAware(userAwareHandler)
} else if anonymousFunc, ok := handler.(func(http.ResponseWriter,*http.Request)); ok {
result = http.HandlerFunc(anonymousFunc)
} else if handlerObj, ok := handler.(http.Handler); ok {
result = handlerObj
} else {
log.Fatalf("handler %+v (type %s) is not a recognized handler type.", handler, reflect.TypeOf(handler))
}
// to avoid memory leaks, ensure that all request data is cleared by the end of the request lifetime
// for all handlers -- see https://stackoverflow.com/a/48203334
result = context.ClearHandler(result)
return result
}
It's working now, but I still have questions:
If I understand correctly, the "duck typing" behavior that I was looking for here would have been fine if I were dealing with interfaces rather than functions. What drives the distinction? Is duck-typing of functions something I could reasonably hope to see in a future version of the language?
I can cast the anonymous function to a HandlerFunc. It's weird to me that casting and type assertions don't share semantics. Can someone explain?
EDIT 2: I've now seen the bit of the language spec that says that defined types (i.e. ones with names) are never identical to any other type, even if the underlying type is the same, and as such will never work in a type assertion (unless it's an interface). So now I'm left wondering:
Why are the semantics different between interfaces and other types?
Why are the semantics different for named and un-named types?
I find both to be unintuitive and inconvenient. Am I alone here? I'm wondering if anyone knows why these decisions were made when the language was designed (perhaps it's particularly difficult to implement without bloating the compiler or its output, etc.), and if anyone is aware of plans to address either situation.
http.HandlerFunc is a specific type. The Ping function is NOT of that type, although it can be converted to that type since they both have the same underlying type.
If handler is an anonymous function then you need to use an anonymous function in the type assertion:
f, ok := handler.(func(http.ResponseWriter,*http.Request))
https://golang.org/ref/spec#Type_assertions
if T is not an interface type, x.(T) asserts that the dynamic type of x is identical to the type T
If T is an interface type, x.(T) asserts that the dynamic type of x implements the interface T.
I am designing my handlers to return a http.Handler. Here's the design of my handlers:
func Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
})
}
My middleware is designed to accept an http.Handler and then call the handler once the middleware has finished performing its operations. Here's the design of my middleware:
func Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Middleware operations
next.ServeHTTP(w, r)
})
}
Considering the design of my middleware and handlers, what is the proper way of passing information from the middleware to the handler? The information that I am trying to pass from my middleware to the handlers is a JSON web token parsed from the request body. If I do not pass the parsed JWT to the handler, then I will need to parse the JWT again in my handlers. Parsing the request body for a JWT in both the middleware and handler seems wasteful. Just in case this information is relevant, I am using the standard net/http library with gorilla mux.
Since you're already using Gorilla take a look at the context package.
(This is nice if you don't want to change your method signatures.)
import (
"github.com/gorilla/context"
)
...
func Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Middleware operations
// Parse body/get token.
context.Set(r, "token", token)
next.ServeHTTP(w, r)
})
}
...
func Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := context.Get(r, "token")
})
}
Update
The Gorilla context package is now in maintenance mode
per the repo:
Note gorilla/context, having been born well before context.Context existed, does not play well with the shallow copying of the request that http.Request.WithContext (added to net/http Go 1.7 onwards) performs.
Using gorilla/context may lead to memory leaks under those conditions, as the pointers to each http.Request become "islanded" and will not be cleaned up when the response is sent.
You should use the http.Request.Context() feature in Go 1.7.
The proper way to pass request scoped data would now be the context package in the standard library.
https://golang.org/pkg/context/
You can access it with request.Context on an http.Request.
A first approach, similar to the question, is in codemodus/chain by Daved.
Package chain aids the composition of Handler wrapper chains that carry request-scoped data.
It uses the notion of Context, coupled with a Context handler:
func ctxHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
// ...
if s, ok := getMyString(ctx); ok {
// s = "Send this down the line."
}
// ...
}
Another approach: You can have a look at "Custom Handlers and Avoiding Globals in Go Web Applications", by Matt Silverlock (elithrar). (full example here)
The idea is to define ServeHTTP on a type which include the relevant context.
// We've turned our original appHandler into a struct with two fields:
// - A function type similar to our original handler type (but that now takes an *appContext)
// - An embedded field of type *appContext
type appHandler struct {
*appContext
h func(*appContext, http.ResponseWriter, *http.Request) (int, error)
}
// Our ServeHTTP method is mostly the same, and also has the ability to
// access our *appContext's fields (templates, loggers, etc.) as well.
func (ah appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Updated to pass ah.appContext as a parameter to our handler type.
status, err := ah.h(ah.appContext, w, r)
if err != nil {
log.Printf("HTTP %d: %q", status, err)
switch status {
case http.StatusNotFound:
http.NotFound(w, r)
// And if we wanted a friendlier error page, we can
// now leverage our context instance - e.g.
// err := ah.renderTemplate(w, "http_404.tmpl", nil)
case http.StatusInternalServerError:
http.Error(w, http.StatusText(status), status)
default:
http.Error(w, http.StatusText(status), status)
}
}
}
In the appContext struct, you would put any data you want to pass around.
I saw some http handler function declarations are varied.
Two of them I found are the standard function and the one returning anonymous function inside the handler.
For example:
Using standard way:
func helloworld(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello World")
}
This the most straight way to declare a handler for an http api.
Another way is using anonym/closure function inside the handler function:
func helloworld2() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
fmt.Fprintln(w, "Hello World")
})
}
What are the differences and the benefit? When to use one of them? What's the best practice?
Pattern
func Middleware(next http.Handler) http.Handler{
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Do something
next.ServeHTTP(w, r)
})
}
often used to construct middleware chain like
http.Handle("/", middlewareOne(middlewareTwo(finalHandler)))
Returning an anonymous function is the only way to work with handlers that require additional arguments, by returning a closure. Example:
func fooHandler(db *someDatabase) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// do something with `db` variable
}
}
Otherwise, there's typically no practical difference between the approaches. One may choose to use the anonymous function universally for consistency.
One of the most popular source of information about structure returning anonymous functions is a blog post from Mat Ryer How I write HTTP services after eight years
I sure it will be good to provide some quotes from his article here:
... handler functions don’t actually handle the requests, they return a function that does. This gives us a closure environment in which our handler can operate:
func (s *server) handleSomething() http.HandlerFunc {
thing := prepareThing()
return func(w http.ResponseWriter, r *http.Request) {
// use thing
}
}
The prepareThing is called only once, so you can use it to do one-time
per-handler initialisation, and then use the thing in the handler.
Also,
If an endpoint has its own request and response types, usually they’re only useful for that particular handler. If that’s the case, you can define them inside the function.
func (s *server) handleSomething() http.HandlerFunc {
// you have these handy structs always visible to your handler and eyes
// and invisible to code that don't use them
type request struct {
Name string
}
type response struct {
Greeting string `json:"greeting"`
}
return func(w http.ResponseWriter, r *http.Request) {
// decode into request struct
// validate
// call business-logic
// encode response from business-logic into response struct
}
}
In practice, writing RESTy APIs you have handler named after resource, e.g. you have /maps resource and appropriate handler struct mapsHandler with injected dependencies (repositories, services containing some business-logic, loggers) into it. But sometimes you will also need to pass an additional dependency exclusively per one handle and suddenly realized that handler has strict signature, so you should wrap it. Then you have something like this
// RESTy routes for "maps" resource
router.Route("/maps", func(r chi.Router) {
adHocDependency := newAdHocDependency(options)
r.Post("/", mapsHandler.handleCreateMap(adHocDependency))
})
making your ad hoc dependency visible to your handler.
Hope it helps!
I am having an issue with creating a middleware that will be chained to other routes and requires access to the database and am not sure how to approach this problem.
I store all of my app context, including the database in a struct called AppContext. I want to create a function handler that looks something like this:
func SomeHandler(appC *AppContext, next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
// Access the database using appC.db
// Logic that requires access to the database.
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
}
In main.go, I have tried:
someHandler := middleware.SomeHandler(&appC)
However, I get the error not enough arguments in call to middleware.SomeHandler. What would be the best way to approach this problem?
The error you're getting is due to not providing the second argument, next http.Handler.
In the case of how to go about the middleware, I recommend taking a look at the implementation of the http.ServeMux https://golang.org/src/net/http/server.go?s=57308:57433#L1890 it essentially does what you're trying to do (and then some) for routing though. So using a http.Handler struct might be more easy here than using a Handler function, this way the Handler(s) you'd have as the next http.Handler argument in your function are just a field within the struct that the parent handler can call from within its ServeHTTP().
So to wrap up my point, you might want to use a struct that implements the http.Handler interface. That way it can have child handlers and the DB access. That way you don't have to keep passing this AppContext either.
I'd not do a premature setup of the context. It is specifically there to be request scoped.
I'd rather create a small and dedicated middleware for passing a database session out of the pool into the context and retrieve said session created for the request in the main handler.
func DBSession(sess *mgo.Session, next http.Handler) http.Handler {
return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
// Create a new session for the scope of the request
s := sess.Copy()
// Make it close when exiting scope
defer s.Close()
// Add the new session (actually a pointer to it)
// acessible via the name "_sess"
ctx = context.WithValue(r.Context(), "_sess", s)
// execute the next handler
next(w, r.WithContext(ctx))
})
}
Now you can use this middleware in you main.go
package main
import (
"net/http"
"gopkg.in/mgo.v2"
)
func sayHello(w http.ResponseWriter, r *http.Request) http.Handler{
return http.HandlerFunc(
func (w http.ResponseWriter, r *http.Request) {
s := r.Context().Value("_sess").(*mgo.Session)
// Do something with your database here.
}
)
}
func main() {
// Ignoring err for brevity
sess, _ := mgo.Dial("localhost:27017")
// Magic happens here: the sayHello Handler is wrapped in the
// DBSession middleware, which makes the session available
// as context param _sess and closes the session after sayHello
// executed. No clutter in your controller for setting up and tearing down
// the session, no way you can forget to close it.
http.Handle("/", middleware.DBSession(sess, sayHello))
}
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
}))