// bless is the meat of kami. // It wraps a ContextHandler into an httprouter compatible request, // in order to run all the middleware and other special handlers. func bless(k ContextHandler, base *context.Context, m *middlewares, panicHandler *HandlerType, logHandler *func(context.Context, mutil.WriterProxy, *http.Request), closeHandler *func(context.Context, *http.Request)) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, params httprouter.Params) { ctx := defaultContext(*base, r) if len(params) > 0 { ctx = newContextWithParams(ctx, params) } ranLogHandler := false // track this in case the log handler blows up ranCloseHandler := false // track this in case the log handler blows up writer := w var proxy mutil.WriterProxy if *logHandler != nil { proxy = mutil.WrapWriter(w) writer = proxy } if *panicHandler != nil { defer func() { if err := recover(); err != nil { ctx = newContextWithException(ctx, err) wrap(*panicHandler).ServeHTTPContext(ctx, writer, r) if *closeHandler != nil && !ranCloseHandler { (*closeHandler)(ctx, r) } if *logHandler != nil && !ranLogHandler { (*logHandler)(ctx, proxy, r) // should only happen if header hasn't been written proxy.WriteHeader(http.StatusInternalServerError) } } }() } ctx, ok := m.run(ctx, writer, r) if ok { k.ServeHTTPContext(ctx, writer, r) } if *closeHandler != nil { ranCloseHandler = true (*closeHandler)(ctx, r) } if *logHandler != nil { ranLogHandler = true (*logHandler)(ctx, proxy, r) // should only happen if header hasn't been written proxy.WriteHeader(http.StatusInternalServerError) } } }
// bless is the meat of kami. // It wraps a HandleFn into an httprouter compatible request, // in order to run all the middleware and other special handlers. func bless(k ContextHandler) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, params httprouter.Params) { ctx := Context if len(params) > 0 { ctx = newContextWithParams(Context, params) } ranLogHandler := false // track this in case the log handler blows up writer := w var proxy mutil.WriterProxy if LogHandler != nil { proxy = mutil.WrapWriter(w) writer = proxy } if PanicHandler != nil { defer func() { if err := recover(); err != nil { ctx = newContextWithException(ctx, err) wrap(PanicHandler).ServeHTTPContext(ctx, writer, r) if LogHandler != nil && !ranLogHandler { LogHandler(ctx, proxy, r) // should only happen if header hasn't been written proxy.WriteHeader(500) } } }() } ctx, ok := run(ctx, writer, r) if ok { k.ServeHTTPContext(ctx, writer, r) } if LogHandler != nil { ranLogHandler = true LogHandler(ctx, proxy, r) // should only happen if header hasn't been written proxy.WriteHeader(500) } } }