|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
package route |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"fmt" |
|
|
|
|
"net/http" |
|
|
|
|
"sync" |
|
|
|
|
|
|
|
|
@ -32,7 +33,7 @@ func WithParam(ctx context.Context, p, v string) context.Context {
|
|
|
|
|
return context.WithValue(ctx, param(p), v) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type contextFn func(r *http.Request) context.Context |
|
|
|
|
type contextFn func(r *http.Request) (context.Context, error) |
|
|
|
|
|
|
|
|
|
// Router wraps httprouter.Router and adds support for prefixed sub-routers
|
|
|
|
|
// and per-request context injections.
|
|
|
|
@ -45,8 +46,8 @@ type Router struct {
|
|
|
|
|
// New returns a new Router.
|
|
|
|
|
func New(ctxFn contextFn) *Router { |
|
|
|
|
if ctxFn == nil { |
|
|
|
|
ctxFn = func(r *http.Request) context.Context { |
|
|
|
|
return context.Background() |
|
|
|
|
ctxFn = func(r *http.Request) (context.Context, error) { |
|
|
|
|
return context.Background(), nil |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return &Router{ |
|
|
|
@ -63,7 +64,12 @@ func (r *Router) WithPrefix(prefix string) *Router {
|
|
|
|
|
// handle turns a HandlerFunc into an httprouter.Handle.
|
|
|
|
|
func (r *Router) handle(h http.HandlerFunc) httprouter.Handle { |
|
|
|
|
return func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { |
|
|
|
|
ctx, cancel := context.WithCancel(r.ctxFn(req)) |
|
|
|
|
reqCtx, err := r.ctxFn(req) |
|
|
|
|
if err != nil { |
|
|
|
|
http.Error(w, fmt.Sprintf("Error creating request context: %v", err), http.StatusBadRequest) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
ctx, cancel := context.WithCancel(reqCtx) |
|
|
|
|
defer cancel() |
|
|
|
|
|
|
|
|
|
for _, p := range params { |
|
|
|
|