pkg/web: restrict handler types (#48495)
Makes `pkg/web` only accept handles from the following set: ```go handlerStd = func(http.ResponseWriter, *http.Request) handlerStdCtx = func(http.ResponseWriter, *http.Request, *web.Context) handlerStdReqCtx = func(http.ResponseWriter, *http.Request, *models.ReqContext) handlerReqCtx = func(*models.ReqContext) handlerReqCtxRes = func(*models.ReqContext) Response handlerCtx = func(*web.Context) ``` This is a first step to reducing above set to only `http.Handler`. --- Due to a cyclic import situation between `pkg/models` and `pkg/web`, parts of this PR were put into `pkg/api/response`, even though they definitely do not belong there. This however is _temporary_ until we untangle `models.ReqContext`.
This commit is contained in:
+5
-21
@@ -19,9 +19,10 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
_ "unsafe"
|
||||
|
||||
"context"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -47,31 +48,14 @@ func Version() string {
|
||||
// and panics if an argument could not be fulfilled via dependency injection.
|
||||
type Handler interface{}
|
||||
|
||||
// handlerFuncInvoker is an inject.FastInvoker wrapper of func(http.ResponseWriter, *http.Request).
|
||||
type handlerFuncInvoker func(http.ResponseWriter, *http.Request)
|
||||
|
||||
func (invoke handlerFuncInvoker) Invoke(params []interface{}) ([]reflect.Value, error) {
|
||||
invoke(params[0].(http.ResponseWriter), params[1].(*http.Request))
|
||||
return nil, nil
|
||||
}
|
||||
//go:linkname hack_wrap github.com/grafana/grafana/pkg/api/response.wrap_handler
|
||||
func hack_wrap(Handler) http.HandlerFunc
|
||||
|
||||
// validateAndWrapHandler makes sure a handler is a callable function, it panics if not.
|
||||
// When the handler is also potential to be any built-in inject.FastInvoker,
|
||||
// it wraps the handler automatically to have some performance gain.
|
||||
func validateAndWrapHandler(h Handler) Handler {
|
||||
if reflect.TypeOf(h).Kind() != reflect.Func {
|
||||
panic("Macaron handler must be a callable function")
|
||||
}
|
||||
|
||||
if !IsFastInvoker(h) {
|
||||
switch v := h.(type) {
|
||||
case func(*Context):
|
||||
return ContextInvoker(v)
|
||||
case func(http.ResponseWriter, *http.Request):
|
||||
return handlerFuncInvoker(v)
|
||||
}
|
||||
}
|
||||
return h
|
||||
return hack_wrap(h)
|
||||
}
|
||||
|
||||
// validateAndWrapHandlers preforms validation and wrapping for each input handler.
|
||||
|
||||
Reference in New Issue
Block a user