AFAIRE
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
3.0 KiB

/*
------------------------------------------------------------------------------------------------------------------------
####### kong ####### Copyright (c) 2021-2022 losyme ################################################ MIT License #######
------------------------------------------------------------------------------------------------------------------------
*/
package router
import (
"net/http"
"strings"
"forge.chapril.org/losyme/errors"
"forge.chapril.org/losyme/kong/context"
)
func getHandler(handler HandlerFunc, mdlw []Middleware) HandlerFunc {
for i := len(mdlw) - 1; i >= 0; i-- {
handler = mdlw[i](handler)
}
return handler
}
func (sr *SubRouter) notFound(c *context.Context) error {
if sr.OnNotFound != nil {
return sr.OnNotFound(c)
}
return c.NewError(http.StatusNotFound, "URI not found", "uri", c.Request.RequestURI) ///////////////////////////////
}
func (sr *SubRouter) serve(c *context.Context, handler HandlerFunc, mdlw []Middleware) {
err := getHandler(handler, mdlw)(c)
if err == nil {
return
}
if c.Status != 0 {
// Le statut a été inscrit mais il a été impossible d'écrire les données si il y en avait.
// On ne peut rien faire de plus.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
return
}
var ce *context.Error
if !errors.As(err, &ce) {
ce = &context.Error{
Status: http.StatusInternalServerError,
Message: err.Error(),
}
}
if c.Render(ce.Status, ce) == nil {
return
}
if c.Status != 0 {
// Le statut a été inscrit mais il a été impossible d'écrire les données.
// On ne peut rien faire de plus.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
return
}
c.RenderStatusInternalServerError()
}
func (sr *SubRouter) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
c := sr.ctxPool.Get(rw, req, sr.rrType)
defer sr.ctxPool.Put(c)
ms := _msPool.Get().(*middlewares)
defer _msPool.Put(ms.reset())
ms.list = append(ms.list, sr.middlewares...)
seg := sr.match(req.URL.Path, c, ms)
if seg == nil || seg.handlers == nil {
sr.serve(c, sr.notFound, sr.middlewares)
return
}
handler, ok := seg.handlers[strings.ToUpper(req.Method)]
if ok {
sr.serve(c, handler, ms.list)
return
}
handler, ok = seg.handlers["*"]
if ok {
sr.serve(c, handler, ms.list)
return
}
var allowed []string
for method := range seg.handlers {
allowed = append(allowed, method)
}
c.SetHeader("Allow", strings.Join(allowed, ", "))
sr.serve(
c,
func(c *context.Context) error {
req := c.Request
return c.NewError( /////////////////////////////////////////////////////////////////////////////////////////
http.StatusMethodNotAllowed,
"method not allowed for this URI",
"uri", req.RequestURI,
"method", req.Method,
"allowed", allowed,
)
},
sr.middlewares,
)
}
/*
######################################################################################################## @(°_°)@ #######
*/