diff --git a/context.go b/context.go index 9015159..c603030 100644 --- a/context.go +++ b/context.go @@ -54,11 +54,7 @@ func (c *Context) Next() { } func (c *Context) prepare(ctx *Context) { - // Only parse multipart form if it hasn't been parsed already - // This prevents race conditions when multiple goroutines might access the same request - if ctx.Request.httpRequest.MultipartForm == nil { - ctx.Request.httpRequest.ParseMultipartForm(int64(app.Config.Request.MaxUploadFileSize)) - } + ctx.Request.httpRequest.ParseMultipartForm(int64(app.Config.Request.MaxUploadFileSize)) } func (c *Context) GetPathParam(key string) interface{} { diff --git a/core.go b/core.go index 9afef81..ca8e747 100644 --- a/core.go +++ b/core.go @@ -6,7 +6,6 @@ package core import ( - "context" "embed" "fmt" "log" @@ -52,18 +51,12 @@ type configContainer struct { // App is a struct representing the main application container and its core components. type App struct { - t int // for tracking hooks (deprecated - maintained for backward compatibility) + t int // for tracking hooks chain *chain hooks *Hooks Config *configContainer } -// requestContext holds request-specific chain execution state -type requestContext struct { - chainIndex int - chainNodes []interface{} -} - // app is a global instance of the App structure used to manage application configuration and lifecycle. var app *App @@ -238,25 +231,10 @@ func (app *App) RegisterRoutes(routes []Route, router *httprouter.Router) *httpr // makeHTTPRouterHandlerFunc creates an httprouter.Handle that handles HTTP requests with the specified controller and hooks. func (app *App) makeHTTPRouterHandlerFunc(h Controller, ms []Hook) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { - // Create request-specific chain state - reqCtx := &requestContext{ - chainIndex: 0, - } - - // Prepare the chain nodes for this request - mw := app.hooks.GetHooks() - for _, v := range mw { - reqCtx.chainNodes = append(reqCtx.chainNodes, v) - } - rhs := app.combHandlers(h, ms) - for _, v := range rhs { - reqCtx.chainNodes = append(reqCtx.chainNodes, v) - } - - // Store chain state in request context + ctx := &Context{ Request: &Request{ - httpRequest: r.WithContext(context.WithValue(r.Context(), "goffeeChain", reqCtx)), + httpRequest: r, httpPathParams: ps, }, Response: &Response{ @@ -279,16 +257,10 @@ func (app *App) makeHTTPRouterHandlerFunc(h Controller, ms []Hook) httprouter.Ha } ctx.prepare(ctx) - - // Execute the first handler in the chain - if len(reqCtx.chainNodes) > 0 { - n := reqCtx.chainNodes[0] - if f, ok := n.(Hook); ok { - f(ctx) - } else if ff, ok := n.(Controller); ok { - ff(ctx) - } - } + rhs := app.combHandlers(h, ms) + app.prepareChain(rhs) + app.t = 0 + app.chain.execute(ctx) for _, header := range ctx.Response.headers { w.Header().Add(header.key, header.val) @@ -391,30 +363,16 @@ func UseHook(mw Hook) { // Next advances to the next middleware or controller in the chain and invokes it with the given context if available. func (app *App) Next(c *Context) { - // Get request-specific chain state from context - if reqCtx, ok := c.Request.httpRequest.Context().Value("goffeeChain").(*requestContext); ok { - reqCtx.chainIndex++ - if reqCtx.chainIndex < len(reqCtx.chainNodes) { - n := reqCtx.chainNodes[reqCtx.chainIndex] - if f, ok := n.(Hook); ok { - f(c) - } else if ff, ok := n.(Controller); ok { - ff(c) - } - } - } else { - // Fallback to old behavior (not thread-safe) - app.t = app.t + 1 - n := app.chain.getByIndex(app.t) - if n != nil { - f, ok := n.(Hook) + app.t = app.t + 1 + n := app.chain.getByIndex(app.t) + if n != nil { + f, ok := n.(Hook) + if ok { + f(c) + } else { + ff, ok := n.(Controller) if ok { - f(c) - } else { - ff, ok := n.(Controller) - if ok { - ff(c) - } + ff(c) } } } @@ -452,17 +410,6 @@ func (app *App) prepareChain(hs []interface{}) { } } -// prepareRequestChain prepares a request-specific chain to avoid race conditions -func (app *App) prepareRequestChain(requestChain *chain, hs []interface{}) { - mw := app.hooks.GetHooks() - for _, v := range mw { - requestChain.nodes = append(requestChain.nodes, v) - } - for _, v := range hs { - requestChain.nodes = append(requestChain.nodes, v) - } -} - // execute executes the first node in the chain, invoking it as either a Hook or Controller if applicable. func (cn *chain) execute(ctx *Context) { i := cn.getByIndex(0) diff --git a/template/components/content_list.go b/template/components/content_list.go index 62927e6..34bfb49 100644 --- a/template/components/content_list.go +++ b/template/components/content_list.go @@ -1,12 +1,10 @@ package components type ContentList struct { - ID string Items []ContentListItem } type ContentListItem struct { - ID string Text string Description string EndElement string diff --git a/template/components/content_list.html b/template/components/content_list.html index 351bcad..31af60b 100644 --- a/template/components/content_list.html +++ b/template/components/content_list.html @@ -1,10 +1,8 @@ {{define "content_list"}} -