feat(router): support for middlewares
This commit is contained in:
58
router/middleware/middleware.go
Normal file
58
router/middleware/middleware.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Middleware interface {
|
||||
Serve(r http.HandlerFunc) http.HandlerFunc
|
||||
}
|
||||
|
||||
type MiddlewaredReponse struct {
|
||||
w http.ResponseWriter
|
||||
statuses []int
|
||||
bodyWrites [][]byte
|
||||
}
|
||||
|
||||
func NewMiddlewaredResponse(w http.ResponseWriter) *MiddlewaredReponse {
|
||||
return &MiddlewaredReponse{w, []int{500}, [][]byte{[]byte("")}}
|
||||
}
|
||||
|
||||
func (m *MiddlewaredReponse) WriteHeader(s int) {
|
||||
m.statuses = append(m.statuses, s)
|
||||
}
|
||||
|
||||
func (m *MiddlewaredReponse) Header() http.Header {
|
||||
return m.w.Header()
|
||||
}
|
||||
|
||||
func (m *MiddlewaredReponse) Write(b []byte) (int, error) {
|
||||
m.bodyWrites = append(m.bodyWrites, b)
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (m *MiddlewaredReponse) ReallyWriteHeader() (int, error) {
|
||||
status := m.statuses[len(m.statuses)-1]
|
||||
m.w.WriteHeader(status)
|
||||
bytes := 0
|
||||
for _, b := range m.bodyWrites {
|
||||
by, err := m.w.Write(b)
|
||||
if err != nil {
|
||||
return bytes, errors.Join(
|
||||
fmt.Errorf(
|
||||
"Failed to write to response in middleware."+
|
||||
"\nStatuses are %v"+
|
||||
"\nTried to write %v bytes"+
|
||||
"\nTried to write response:\n%s",
|
||||
m.statuses, bytes, string(b),
|
||||
),
|
||||
err,
|
||||
)
|
||||
}
|
||||
bytes += by
|
||||
}
|
||||
|
||||
return bytes, nil
|
||||
}
|
||||
@@ -3,11 +3,14 @@ package router
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"forge.capytal.company/capytalcode/project-comicverse/router/middleware"
|
||||
)
|
||||
|
||||
type Router struct {
|
||||
mux *http.ServeMux
|
||||
serveHttp http.HandlerFunc
|
||||
middlewares []middleware.Middleware
|
||||
}
|
||||
|
||||
type RouterOpts struct {
|
||||
@@ -48,7 +51,35 @@ func (rt *Router) HandleRoutes(routes []Route) {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Router) AddMiddleware(m middleware.Middleware) {
|
||||
r.middlewares = append(r.middlewares, m)
|
||||
}
|
||||
|
||||
func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if len(rt.middlewares) > 0 {
|
||||
rt.serveHttp = rt.wrapMiddlewares(rt.middlewares, rt.serveHttp)
|
||||
}
|
||||
rt.serveHttp(w, r)
|
||||
}
|
||||
|
||||
func (r *Router) wrapMiddlewares(ms []middleware.Middleware, h http.HandlerFunc) http.HandlerFunc {
|
||||
wh := h.ServeHTTP
|
||||
for _, m := range ms {
|
||||
wh = m.Serve(wh)
|
||||
}
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
mw := middleware.NewMiddlewaredResponse(w)
|
||||
wh(mw, r)
|
||||
if _, err := mw.ReallyWriteHeader(); err != nil {
|
||||
_, _ = w.Write(
|
||||
[]byte(
|
||||
fmt.Sprintf(
|
||||
"Error while trying to write middlewared response.\n%s",
|
||||
err.Error(),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user