Skip to content

Instantly share code, notes, and snippets.

@nanoninja
Created December 13, 2015 16:24
Show Gist options
  • Save nanoninja/24d504aa28fd8ccdce0f to your computer and use it in GitHub Desktop.
Save nanoninja/24d504aa28fd8ccdce0f to your computer and use it in GitHub Desktop.
Go Context Handler
package main
import (
"fmt"
"golang.org/x/net/context"
"log"
"net/http"
"os"
)
type Handler interface {
ServeHTTP(c context.Context, w http.ResponseWriter, r *http.Request)
}
type HandlerFunc func(ctx context.Context, w http.ResponseWriter, r *http.Request)
func (fn HandlerFunc) ServeHTTP(ctx context.Context, w http.ResponseWriter, r *http.Request) {
fn(ctx, w, r)
}
func Wrap(handler http.Handler) Handler {
return HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
handler.ServeHTTP(w, r)
})
}
type Middleware []Handler
func (m *Middleware) Use(handler Handler) {
*m = append(*m, handler)
}
func (m Middleware) ServeHTTP(ctx context.Context, w http.ResponseWriter, r *http.Request) {
for _, handler := range m {
handler.ServeHTTP(ctx, w, r)
}
}
type Drago struct {
context context.Context
handlers []Handler
}
func New(handlers ...Handler) *Drago {
return &Drago{
context: NewContext(),
handlers: handlers,
}
}
func (d *Drago) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for _, handler := range d.handlers {
handler.ServeHTTP(d.context, w, r)
}
}
func (d *Drago) Use(handler Handler) {
d.handlers = append(d.handlers, handler)
}
func (d *Drago) UseFunc(handleFunc HandlerFunc) {
d.Use(HandlerFunc(handleFunc))
}
func (d *Drago) UseHandler(handler http.Handler) {
d.Use(Wrap(handler))
}
func (d *Drago) UseHandlerFunc(handleFunc http.HandlerFunc) {
d.UseHandler(http.HandlerFunc(handleFunc))
}
func (d *Drago) Run(addr string) {
l := log.New(os.Stdout, "[drago] ", 0)
l.Printf("Listening on %s", addr)
l.Fatal(http.ListenAndServe(addr, d))
}
type Context struct {
Params map[string]interface{}
Errors []error
}
func NewContext() context.Context {
return context.WithValue(context.Background(), "ctx", &Context{
Params: make(map[string]interface{}),
Errors: make([]error, 0),
})
}
func homeHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
params, _ := ctx.Value("ctx").(map[string]interface{})
params["test"] = "ok"
fmt.Println("Hello Home Handler")
}
func testHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
params, _ := ctx.Value("params").(map[string]interface{})
fmt.Println("Hello Test Handler", params)
}
func main() {
drago := New()
drago.UseFunc(homeHandler)
drago.UseFunc(testHandler)
drago.Run(":3000")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment