diff --git a/framework/context.go b/framework/context.go index 19961ee..8991be3 100644 --- a/framework/context.go +++ b/framework/context.go @@ -19,7 +19,10 @@ type Context struct { ctx context.Context request *http.Request responseWriter http.ResponseWriter - handler ControllerHandler + + handlers []ControllerHandler + // current handler index + index int hasTimeout bool writerMux *sync.Mutex @@ -32,6 +35,7 @@ func NewContext(w http.ResponseWriter, r *http.Request) *Context { request: r, responseWriter: w, writerMux: &sync.Mutex{}, + index: -1, // will be set to 0 when at the beginning } } @@ -99,10 +103,23 @@ func (ctx *Context) Value(key any) any { // Next runs the next function in the function chain func (ctx *Context) Next() error { - // TODO + ctx.index++ + if ctx.index >= len(ctx.handlers) { + // This is the end of the chain + return nil + } + // Run this handler + if err := ctx.handlers[ctx.index](ctx); err != nil { + return err + } return nil } +// SetHandlers sets handlers for context +func (ctx *Context) SetHandlers(handlers []ControllerHandler) { + ctx.handlers = handlers +} + // }}} // {{{ Implements request functions diff --git a/framework/core.go b/framework/core.go index 45fcec0..7336ddc 100644 --- a/framework/core.go +++ b/framework/core.go @@ -60,7 +60,7 @@ func (c *Core) Delete(url string, handler ControllerHandler) { } // FindRouteByRequest finds route using the request -func (c *Core) FindRouteByRequest(r *http.Request) ControllerHandler { +func (c *Core) FindRouteByRequest(r *http.Request) []ControllerHandler { upperUri := strings.ToUpper(r.URL.Path) upperMethod := strings.ToUpper(r.Method) @@ -70,13 +70,13 @@ func (c *Core) FindRouteByRequest(r *http.Request) ControllerHandler { return nil } - controller := mapper.FindRoute(upperUri) - if controller == nil { + controllers := mapper.FindRoute(upperUri) + if controllers == nil { log.Printf("URI %q is not recognized\n", r.URL.Path) return nil } - return controller + return controllers } func (c *Core) Group(prefix string) IGroup { @@ -92,14 +92,15 @@ func (c *Core) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := NewContext(w, r) - router := c.FindRouteByRequest(r) - if router == nil { + handlers := c.FindRouteByRequest(r) + if handlers == nil { ctx.WriteJSON(http.StatusNotFound, "Request not found") return } - err := router(ctx) - if err != nil { + ctx.SetHandlers(handlers) + + if err := ctx.Next(); err != nil { ctx.WriteJSON(http.StatusInternalServerError, "Internal error") return } diff --git a/framework/trie.go b/framework/trie.go index 2b3d6fb..a118811 100644 --- a/framework/trie.go +++ b/framework/trie.go @@ -14,10 +14,10 @@ func NewTrie() *Trie { return &Trie{root: newNode("")} } -func (t *Trie) FindRoute(uri string) ControllerHandler { +func (t *Trie) FindRoute(uri string) []ControllerHandler { uri = strings.TrimPrefix(uri, "/") if uri == "" { - return t.root.handler + return t.root.handlers } found := t.root.findRoute(uri) @@ -25,14 +25,14 @@ func (t *Trie) FindRoute(uri string) ControllerHandler { return nil } - return found.handler + return found.handlers } func (t *Trie) AddRouter(uri string, handler ControllerHandler) error { uri = strings.TrimPrefix(uri, "/") if uri == "" { t.root.isLast = true - t.root.handler = handler + t.root.handlers = append(t.root.handlers, handler) return nil } @@ -54,7 +54,7 @@ func (t *Trie) AddRouter(uri string, handler ControllerHandler) error { type node struct { isLast bool segment string - handler ControllerHandler + handlers []ControllerHandler children []*node } @@ -125,7 +125,7 @@ func (n *node) addRoute(uri string, handler ControllerHandler) error { } else { // otherwise, set the child child.isLast = true - child.handler = handler + child.handlers = append(child.handlers, handler) return nil } } @@ -138,7 +138,7 @@ func (n *node) addRoute(uri string, handler ControllerHandler) error { new := newNode(splitted[0]) if isLast { // this is the end - new.handler = handler + new.handlers = append(new.handlers, handler) new.isLast = true n.children = append(n.children, new) return nil