mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	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:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user