forked from forgejo/forgejo
Decouple the different contexts from each other (#24786)
Replace #16455 Close #21803 Mixing different Gitea contexts together causes some problems: 1. Unable to respond proper content when error occurs, eg: Web should respond HTML while API should respond JSON 2. Unclear dependency, eg: it's unclear when Context is used in APIContext, which fields should be initialized, which methods are necessary. To make things clear, this PR introduces a Base context, it only provides basic Req/Resp/Data features. This PR mainly moves code. There are still many legacy problems and TODOs in code, leave unrelated changes to future PRs.
This commit is contained in:
parent
6ba4f89723
commit
6b33152b7d
57 changed files with 885 additions and 781 deletions
|
@ -10,6 +10,7 @@ import (
|
|||
"reflect"
|
||||
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/web/routing"
|
||||
)
|
||||
|
||||
|
@ -25,6 +26,10 @@ var argTypeProvider = map[reflect.Type]func(req *http.Request) ResponseStatusPro
|
|||
reflect.TypeOf(&context.PrivateContext{}): func(req *http.Request) ResponseStatusProvider { return context.GetPrivateContext(req) },
|
||||
}
|
||||
|
||||
func RegisterHandleTypeProvider[T any](fn func(req *http.Request) ResponseStatusProvider) {
|
||||
argTypeProvider[reflect.TypeOf((*T)(nil)).Elem()] = fn
|
||||
}
|
||||
|
||||
// responseWriter is a wrapper of http.ResponseWriter, to check whether the response has been written
|
||||
type responseWriter struct {
|
||||
respWriter http.ResponseWriter
|
||||
|
@ -78,7 +83,13 @@ func preCheckHandler(fn reflect.Value, argsIn []reflect.Value) {
|
|||
}
|
||||
}
|
||||
|
||||
func prepareHandleArgsIn(resp http.ResponseWriter, req *http.Request, fn reflect.Value) []reflect.Value {
|
||||
func prepareHandleArgsIn(resp http.ResponseWriter, req *http.Request, fn reflect.Value, fnInfo *routing.FuncInfo) []reflect.Value {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Error("unable to prepare handler arguments for %s: %v", fnInfo.String(), err)
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
isPreCheck := req == nil
|
||||
|
||||
argsIn := make([]reflect.Value, fn.Type().NumIn())
|
||||
|
@ -155,7 +166,7 @@ func toHandlerProvider(handler any) func(next http.Handler) http.Handler {
|
|||
}
|
||||
|
||||
// prepare the arguments for the handler and do pre-check
|
||||
argsIn := prepareHandleArgsIn(resp, req, fn)
|
||||
argsIn := prepareHandleArgsIn(resp, req, fn, funcInfo)
|
||||
if req == nil {
|
||||
preCheckHandler(fn, argsIn)
|
||||
return // it's doing pre-check, just return
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue