XHandler is a bridge between net/context and http.Handler
.
It lets you enforce net/context
in your handlers without sacrificing compatibility with existing http.Handlers
nor imposing a specific router.
Thanks to net/context
deadline management, xhandler
is able to enforce a per request deadline and will cancel the context when the client closes the connection unexpectedly.
You may create your own net/context
aware handler pretty much the same way as you would do with http.Handler.
Read more about xhandler on Dailymotion engineering blog.
go get -u github.com/rs/xhandler
package main import ( "log" "net/http" "time" "github.com/rs/cors" "github.com/rs/xhandler" "golang.org/x/net/context" ) type myMiddleware struct { next xhandler.HandlerC } func (h myMiddleware) ServeHTTPC(ctx context.Context, w http.ResponseWriter, r *http.Request) { ctx = context.WithValue(ctx, "test", "World") h.next.ServeHTTPC(ctx, w, r) } func main() { c := xhandler.Chain{} // Add close notifier handler so context is cancelled when the client closes // the connection c.UseC(xhandler.CloseHandler) // Add timeout handler c.UseC(xhandler.TimeoutHandler(2 * time.Second)) // Middleware putting something in the context c.UseC(func(next xhandler.HandlerC) xhandler.HandlerC { return myMiddleware{next: next} }) // Mix it with a non-context-aware middleware handler c.Use(cors.Default().Handler) // Final handler (using handlerFuncC), reading from the context xh := xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { value := ctx.Value("test").(string) w.Write([]byte("Hello " + value)) }) // Bridge context aware handlers with http.Handler using xhandler.Handle() http.Handle("/test", c.Handler(xh)) if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal(err) } }
Xhandler comes with an optional context aware muxer forked from httprouter:
package main import ( "fmt" "log" "net/http" "time" "github.com/rs/xhandler" "github.com/rs/xmux" "golang.org/x/net/context" ) func main() { c := xhandler.Chain{} // Append a context-aware middleware handler c.UseC(xhandler.CloseHandler) // Another context-aware middleware handler c.UseC(xhandler.TimeoutHandler(2 * time.Second)) mux := xmux.New() // Use c.Handler to terminate the chain with your final handler mux.GET("/welcome/:name", xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, "Welcome %s!", xmux.Params(ctx).Get("name")) })) if err := http.ListenAndServe(":8080", c.Handler(mux)); err != nil { log.Fatal(err) } }
See xmux for more examples.
Here is a list of net/context
aware middleware handlers implementing xhandler.HandlerC
interface.
Feel free to put up a PR linking your middleware if you have built one:
All source code is licensed under the MIT License.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4