router: added middlewares

This commit is contained in:
2026-02-02 17:26:45 +02:00
parent c973fccc86
commit 0dac88fde8
5 changed files with 113 additions and 2 deletions
+2
View File
@@ -11,6 +11,7 @@ type Context struct {
Request *http.Request
Writer http.ResponseWriter
PathMap map[string]string
StatusCode int
}
func NewContext(writer http.ResponseWriter, request *http.Request) *Context {
@@ -29,6 +30,7 @@ func (rctx *Context) SetHeader(key, value string) {
}
func (rctx *Context) SetStatus(httpStatus int) {
rctx.StatusCode = httpStatus
rctx.Writer.WriteHeader(httpStatus)
}
+33
View File
@@ -0,0 +1,33 @@
package router
func NewCorsMiddleware() MiddlewareFunc {
mw := func(next Handler) Handler {
return newCorsHandler(next)
}
return mw
}
type corsHandler struct {
next Handler
}
func newCorsHandler(next Handler) *corsHandler {
return &corsHandler{
next: next,
}
}
func (hand corsHandler) ServeHTTP(ctx *Context) {
origin := ctx.Request.Header.Get("Origin")
if origin != "" {
ctx.SetHeader("Access-Control-Allow-Origin", origin)
ctx.SetHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE, PATCH")
ctx.SetHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
ctx.SetHeader("Access-Control-Max-Age", "86400")
ctx.SetHeader("Access-Control-Allow-Credentials", "true")
}
if ctx.Request.Method == "OPTIONS" {
return
}
hand.next.ServeHTTP(ctx)
}
+27
View File
@@ -0,0 +1,27 @@
package router
func NewLoggingMiddleware(print func(string, ...any)) MiddlewareFunc {
mw := func(next Handler) Handler {
return newLoggingHandler(next, print)
}
return mw
}
type loggingHandler struct {
next Handler
printFunc func(string, ...any)
}
func newLoggingHandler(next Handler, print func(string, ...any)) *loggingHandler {
return &loggingHandler{
next: next,
printFunc: print,
}
}
func (logging loggingHandler) ServeHTTP(rctx *Context) {
logging.next.ServeHTTP(rctx)
logging.printFunc("%s %s %s %s %d", rctx.Request.RemoteAddr,
rctx.Request.Method, rctx.Request.URL.String(),
rctx.Request.Proto, rctx.StatusCode)
}
+40
View File
@@ -0,0 +1,40 @@
package router
import (
"net/http"
"runtime/debug"
"time"
)
func NewRecoveryMiddleware(print func(string, ...any)) MiddlewareFunc {
mw := func(next Handler) Handler {
return newRecoveryHandler(next, print)
}
return mw
}
type recoveryHandler struct {
next Handler
print func(string, ...any)
}
func newRecoveryHandler(next Handler, print func(string, ...any)) *recoveryHandler {
return &recoveryHandler{
next: next,
print: print,
}
}
func (hand recoveryHandler) ServeHTTP(rctx *Context) {
exitFunc := func() {
err := recover()
if err != nil {
rctx.Writer.WriteHeader(http.StatusInternalServerError)
stack := string(debug.Stack())
timestamp := time.Now().Format(time.RFC3339)
hand.print("%s %v ; %s\n", timestamp, err, stack)
}
}
defer exitFunc()
hand.next.ServeHTTP(rctx)
}
+11 -2
View File
@@ -6,6 +6,8 @@ import (
"regexp"
)
type MiddlewareFunc func(next Handler) Handler
type Handler interface {
ServeHTTP(rctx *Context)
}
@@ -17,15 +19,22 @@ func (handlerFunc HandlerFunc) ServeHTTP(rctx *Context) {
}
type Router struct {
headHandler Handler
routeHandler *Selector
}
func NewRouter() *Router {
selector := NewSelector()
return &Router{
routeHandler: NewSelector(),
routeHandler: selector,
headHandler: selector,
}
}
func (rout *Router) Use(mwFunc MiddlewareFunc) {
rout.headHandler = mwFunc(rout.headHandler)
}
func (rout *Router) Selector() *Selector {
return rout.routeHandler
}
@@ -60,7 +69,7 @@ func (rout *Router) Delete(path string, handlerFunc HandlerFunc) {
func (rout *Router) ServeHTTP(writer http.ResponseWriter, req *http.Request) {
rctx := NewContext(writer, req)
rout.routeHandler.ServeHTTP(rctx)
rout.headHandler.ServeHTTP(rctx)
}
func (rout *Router) NotFound(handlerFunc HandlerFunc) {