transfer.sh/vendor/github.com/PuerkitoBio/ghost/handlers/context.go

56 lines
1.6 KiB
Go
Raw Normal View History

2016-07-11 22:15:19 +02:00
package handlers
import (
"net/http"
)
// Structure that holds the context map and exposes the ResponseWriter interface.
type contextResponseWriter struct {
http.ResponseWriter
m map[interface{}]interface{}
}
// Implement the WrapWriter interface.
func (this *contextResponseWriter) WrappedWriter() http.ResponseWriter {
return this.ResponseWriter
}
// ContextHandlerFunc is the same as ContextHandler, it is just a convenience
// signature that accepts a func(http.ResponseWriter, *http.Request) instead of
// a http.Handler interface. It saves the boilerplate http.HandlerFunc() cast.
func ContextHandlerFunc(h http.HandlerFunc, cap int) http.HandlerFunc {
return ContextHandler(h, cap)
}
// ContextHandler gives a context storage that lives only for the duration of
// the request, with no locking involved.
func ContextHandler(h http.Handler, cap int) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if _, ok := GetContext(w); ok {
// Self-awareness, context handler is already set up
h.ServeHTTP(w, r)
return
}
// Create the context-providing ResponseWriter replacement.
ctxw := &contextResponseWriter{
w,
make(map[interface{}]interface{}, cap),
}
// Call the wrapped handler with the context-aware writer
h.ServeHTTP(ctxw, r)
}
}
// Helper function to retrieve the context map from the ResponseWriter interface.
func GetContext(w http.ResponseWriter) (map[interface{}]interface{}, bool) {
ctxw, ok := GetResponseWriter(w, func(tst http.ResponseWriter) bool {
_, ok := tst.(*contextResponseWriter)
return ok
})
if ok {
return ctxw.(*contextResponseWriter).m, true
}
return nil, false
}