rewrite midlleware to fiber
This commit is contained in:
parent
2fb7cd5a02
commit
2746737891
@ -17,6 +17,7 @@ func JwtPlug(c *fiber.Ctx) error {
|
|||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo оказывается то что и хттп я переписал, ну надо убрать потом думаю
|
||||||
func Jwt(c *fiber.Ctx) error {
|
func Jwt(c *fiber.Ctx) error {
|
||||||
var (
|
var (
|
||||||
token, role string
|
token, role string
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
"heruvym/jwt_adapter"
|
"heruvym/jwt_adapter"
|
||||||
"net/http"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
errors2 "github.com/pkg/errors"
|
|
||||||
"github.com/rs/xid"
|
"github.com/rs/xid"
|
||||||
"github.com/themakers/hlog"
|
"github.com/themakers/hlog"
|
||||||
)
|
)
|
||||||
@ -38,23 +36,25 @@ func NewMiddleware(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mw *Middleware) MiddlewareLogger(next http.Handler) http.Handler {
|
func (mw *Middleware) MiddlewareLogger(ctx *fiber.Ctx) error {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
mw.logger.Emit(DebugHttpRequest{
|
||||||
mw.logger.Emit(DebugHttpRequest{Url: r.URL.String()})
|
Url: ctx.OriginalURL(),
|
||||||
next.ServeHTTP(w, r)
|
|
||||||
})
|
})
|
||||||
|
return ctx.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mw *Middleware) MiddlewareOriginAccess(next http.Handler) http.Handler {
|
func (mw *Middleware) MiddlewareOriginAccess(ctx *fiber.Ctx) error {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
origin := ctx.Get("Origin")
|
||||||
if len(r.Header["Origin"]) > 0 {
|
if origin == "" {
|
||||||
if mw.allowedOrigins != "*" && !strings.Contains(mw.allowedOrigins, r.Header["Origin"][0]) {
|
if mw.allowedOrigins != "*" && !strings.Contains(mw.allowedOrigins, origin) {
|
||||||
mw.logger.Emit(ErrorOriginAccess{Origin: r.Header["Origin"][0], Url: r.URL.String()})
|
mw.logger.Emit(ErrorOriginAccess{
|
||||||
return
|
Origin: origin,
|
||||||
}
|
Url: ctx.OriginalURL(),
|
||||||
|
})
|
||||||
|
return ctx.SendStatus(fiber.StatusForbidden)
|
||||||
}
|
}
|
||||||
next.ServeHTTP(w, r)
|
}
|
||||||
})
|
return ctx.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
func recFn(rec interface{}) (int, string) {
|
func recFn(rec interface{}) (int, string) {
|
||||||
@ -64,196 +64,177 @@ func recFn(rec interface{}) (int, string) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if err, ok := rec.(error); ok {
|
if err, ok := rec.(error); ok {
|
||||||
code = http.StatusInternalServerError
|
code = fiber.StatusInternalServerError
|
||||||
message = err.Error()
|
message = err.Error()
|
||||||
} else {
|
} else {
|
||||||
code = http.StatusInternalServerError
|
code = fiber.StatusInternalServerError
|
||||||
message = fmt.Sprintf("%v", rec)
|
message = fmt.Sprintf("%v", rec)
|
||||||
}
|
}
|
||||||
|
|
||||||
return code, message
|
return code, message
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mw *Middleware) MiddlewareRecovery(next http.Handler) http.Handler {
|
func (mw *Middleware) MiddlewareRecovery(ctx *fiber.Ctx) error {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
defer func() {
|
||||||
defer func() {
|
if rec := recover(); rec != nil {
|
||||||
if rec := recover(); rec != nil {
|
code, message := recFn(rec)
|
||||||
code, message := recFn(rec)
|
ctx.Status(code)
|
||||||
w.WriteHeader(code)
|
if _, err := ctx.WriteString(message); err != nil {
|
||||||
if _, err := fmt.Fprint(w, message); err != nil {
|
mw.logger.Emit(ErrorWritingPanicResponse{Err: err})
|
||||||
mw.logger.Emit(ErrorWritingPanicResponse{Err: err})
|
|
||||||
}
|
|
||||||
mw.logger.Emit(ErrorPanicInHttpHandler{
|
|
||||||
Code: code,
|
|
||||||
Message: message,
|
|
||||||
Recovered: rec,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}()
|
mw.logger.Emit(ErrorPanicInHttpHandler{
|
||||||
next.ServeHTTP(w, r)
|
Code: code,
|
||||||
})
|
Message: message,
|
||||||
|
Recovered: rec,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return ctx.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mw *Middleware) MiddlewareJwt(next http.Handler) http.Handler {
|
func (mw *Middleware) MiddlewareJwt(ctx *fiber.Ctx) error {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
var (
|
||||||
|
token, role string
|
||||||
|
adapter *jwt_adapter.JwtAdapter
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
switch ctx.Get("Referer") {
|
||||||
token, role string
|
case "sadmin.pena":
|
||||||
adapter *jwt_adapter.JwtAdapter
|
role = "admin"
|
||||||
)
|
case "admin.pena":
|
||||||
|
role = "admin"
|
||||||
switch r.Header["Referer"][0] {
|
default:
|
||||||
case "sadmin.pena":
|
role = "user"
|
||||||
role = "admin"
|
|
||||||
case "admin.pena":
|
|
||||||
role = "admin"
|
|
||||||
default:
|
|
||||||
role = "user"
|
|
||||||
}
|
|
||||||
ctx := context.WithValue(r.Context(), jwt_adapter.RoleKey, role)
|
|
||||||
|
|
||||||
tokenCookie, err := r.Cookie(jwt_adapter.DefaultHeaderKey)
|
|
||||||
fmt.Println("MW1", err)
|
|
||||||
if err != nil {
|
|
||||||
// Escape GET requests
|
|
||||||
if r.Method == http.MethodGet {
|
|
||||||
next.ServeHTTP(w, r.WithContext(ctx))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("MW2", jwt_adapter.DefaultHeaderKey, r.Header[jwt_adapter.DefaultHeaderKey])
|
|
||||||
if len(r.Header[jwt_adapter.DefaultHeaderKey]) <= 0 || !func(hdrs []string) bool {
|
|
||||||
if len(hdrs) == 0 {return false}
|
|
||||||
fmt.Println("SS", hdrs[0])
|
|
||||||
if hdrs[0] == "Bearer" || hdrs[0] == "Bearer " {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}(r.Header[jwt_adapter.DefaultHeaderKey]) {
|
|
||||||
fmt.Println("MW3", r.Header[sessionKey], sessionKey, r.Header)
|
|
||||||
if len(r.Header[sessionKey]) == 0 {
|
|
||||||
if sessCookie, err := r.Cookie(sessionKey); err != nil {
|
|
||||||
id := xid.New().String()
|
|
||||||
adapter = &jwt_adapter.JwtAdapter{Id: id}
|
|
||||||
http.SetCookie(w, &http.Cookie{
|
|
||||||
Name: sessionKey,
|
|
||||||
Value: id,
|
|
||||||
Expires: time.Now().Add(time.Hour * 24 * 30),
|
|
||||||
SameSite: http.SameSiteNoneMode,
|
|
||||||
Secure: true,
|
|
||||||
})
|
|
||||||
fmt.Println("SSS", sessCookie, err)
|
|
||||||
} else {
|
|
||||||
fmt.Println("SSS1", sessCookie.Value, err)
|
|
||||||
adapter = &jwt_adapter.JwtAdapter{Id: sessCookie.Value}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
adapter = &jwt_adapter.JwtAdapter{Id: r.Header[sessionKey][0]}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
token = r.Header[jwt_adapter.DefaultHeaderKey][0]
|
|
||||||
token = strings.Replace(token, "Bearer ", "", -1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
token = tokenCookie.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
if adapter == nil {
|
|
||||||
adapter, err = jwt_adapter.Decode(token)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
mw.logger.Emit(ErrorJwtAccess{Err: err})
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = setJwtHeader(adapter, w, mw.logger)
|
|
||||||
if err != nil {
|
|
||||||
mw.logger.Emit(ErrorJwtAccess{Err: err})
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = context.WithValue(ctx, jwt_adapter.DefaultHeaderKey, adapter)
|
|
||||||
next.ServeHTTP(w, r.WithContext(ctx))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func getJwtUserId(r *http.Request) (string, error) {
|
|
||||||
if jwtAdapter, ok := r.Context().Value(jwt_adapter.DefaultHeaderKey).(*jwt_adapter.JwtAdapter); ok {
|
|
||||||
return jwtAdapter.Id, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", errors2.New("no token in context")
|
ctx.Locals(jwt_adapter.RoleKey, role)
|
||||||
}
|
tokenCookie := ctx.Cookies(jwt_adapter.DefaultHeaderKey)
|
||||||
|
if tokenCookie == "" {
|
||||||
func (mw *Middleware) MiddlewareRoleAccess(next http.Handler) http.Handler {
|
if ctx.Method() == "GET" {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return ctx.Next()
|
||||||
// Если доступ по роли задан
|
|
||||||
if allowedRoles, ok := mw.allowedRoles[r.URL.Path]; ok {
|
|
||||||
|
|
||||||
// Если роли не указаны
|
|
||||||
if allowedRoles == "" {
|
|
||||||
next.ServeHTTP(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
id, err := getJwtUserId(r)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
mw.logger.Emit(ErrorRoleAccess{Err: err})
|
|
||||||
http.Error(w, "internal server error", http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}*/
|
|
||||||
/*
|
|
||||||
role, err := mw.mongo.GetProfileRole(r.Context(), id)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
mw.logger.Emit(ErrorRoleAccess{Err: err})
|
|
||||||
http.Error(w, "internal server error", http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// Если у пользователя не задана роль - блокируем доступ
|
|
||||||
/* if role == "" {
|
|
||||||
err = errors.UserHaveNoRole("User have no role")
|
|
||||||
mw.logger.Emit(ErrorRoleAccess{err})
|
|
||||||
http.Error(w, err.Error(), http.StatusForbidden)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Если указан астериск - доступ имеет любая роль
|
|
||||||
if !(allowedRoles == "*" || strings.Contains(allowedRoles, role)) {
|
|
||||||
err = errors.UserHaveNoRole("User role not allowed")
|
|
||||||
mw.logger.Emit(ErrorRoleAccess{err})
|
|
||||||
http.Error(w, err.Error(), http.StatusForbidden)
|
|
||||||
return
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
headerToken := ctx.Get(jwt_adapter.DefaultHeaderKey)
|
||||||
|
if headerToken == "" || !strings.HasPrefix(headerToken, "Bearer") {
|
||||||
|
if ctx.Get(sessionKey) == "" {
|
||||||
|
sessCookie := ctx.Cookies(sessionKey)
|
||||||
|
if sessCookie == "" {
|
||||||
|
id := xid.New().String()
|
||||||
|
adapter = &jwt_adapter.JwtAdapter{Id: id}
|
||||||
|
ctx.Cookie(&fiber.Cookie{
|
||||||
|
Name: sessionKey,
|
||||||
|
Value: id,
|
||||||
|
Expires: time.Now().Add(time.Hour * 24 * 30),
|
||||||
|
SameSite: fiber.CookieSameSiteNoneMode,
|
||||||
|
Secure: true,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
adapter = &jwt_adapter.JwtAdapter{Id: sessCookie}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
adapter = &jwt_adapter.JwtAdapter{Id: ctx.Get(sessionKey)}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
token = strings.Replace(headerToken, "Bearer ", "", -1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
token = tokenCookie
|
||||||
|
}
|
||||||
|
|
||||||
next.ServeHTTP(w, r)
|
if adapter == nil {
|
||||||
})
|
adapter, err = jwt_adapter.Decode(token)
|
||||||
|
if err != nil {
|
||||||
|
mw.logger.Emit(ErrorJwtAccess{Err: err})
|
||||||
|
return ctx.Status(fiber.StatusUnauthorized).SendString("Unauthorized")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setJwtHeader(adapter, ctx.Response(), mw.logger)
|
||||||
|
if err != nil {
|
||||||
|
mw.logger.Emit(ErrorJwtAccess{Err: err})
|
||||||
|
return ctx.Status(fiber.StatusUnauthorized).SendString("Unauthorized")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Locals(jwt_adapter.DefaultHeaderKey, adapter)
|
||||||
|
return ctx.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MiddlewareJwtPlug jwt заглушка для отладки кода, удалить в релизе
|
func (mw *Middleware) ExtractHostMiddleware(ctx *fiber.Ctx) error {
|
||||||
/*
|
host := ctx.Get("Referer")
|
||||||
func (mw *Middleware) MiddlewareJwtPlug(next http.Handler) http.Handler {
|
if host != "" {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
ctx.Locals(HostKey, host)
|
||||||
adapter := jwt_adapter.JwtAdapter{ID: "604b79aced1d431b9e911f56"}
|
}
|
||||||
adapter.Init()
|
return ctx.Next()
|
||||||
adapter.SetUserID("604b79aced1d431b9e911f56")
|
|
||||||
ctx := context.WithValue(r.Context(), "JWT", &adapter)
|
|
||||||
|
|
||||||
next.ServeHTTP(w, r.WithContext(ctx))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
func (mw *Middleware) ExtractHostMiddleware(next http.Handler) http.Handler {
|
// todo useless?
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
//func getJwtUserId(r *http.Request) (string, error) {
|
||||||
host := r.Header["Referer"][0]
|
// if jwtAdapter, ok := r.Context().Value(jwt_adapter.DefaultHeaderKey).(*jwt_adapter.JwtAdapter); ok {
|
||||||
ctx := context.WithValue(r.Context(), HostKey, host)
|
// return jwtAdapter.Id, nil
|
||||||
next.ServeHTTP(w, r.WithContext(ctx))
|
// }
|
||||||
})
|
//
|
||||||
}
|
// return "", errors2.New("no token in context")
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func (mw *Middleware) MiddlewareRoleAccess(next http.Handler) http.Handler {
|
||||||
|
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// // Если доступ по роли задан
|
||||||
|
// if allowedRoles, ok := mw.allowedRoles[r.URL.Path]; ok {
|
||||||
|
//
|
||||||
|
// // Если роли не указаны
|
||||||
|
// if allowedRoles == "" {
|
||||||
|
// next.ServeHTTP(w, r)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// /*
|
||||||
|
// id, err := getJwtUserId(r)
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// mw.logger.Emit(ErrorRoleAccess{Err: err})
|
||||||
|
// http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||||
|
// return
|
||||||
|
// }*/
|
||||||
|
// /*
|
||||||
|
// role, err := mw.mongo.GetProfileRole(r.Context(), id)
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// mw.logger.Emit(ErrorRoleAccess{Err: err})
|
||||||
|
// http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// */
|
||||||
|
// // Если у пользователя не задана роль - блокируем доступ
|
||||||
|
// /* if role == "" {
|
||||||
|
// err = errors.UserHaveNoRole("User have no role")
|
||||||
|
// mw.logger.Emit(ErrorRoleAccess{err})
|
||||||
|
// http.Error(w, err.Error(), http.StatusForbidden)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Если указан астериск - доступ имеет любая роль
|
||||||
|
// if !(allowedRoles == "*" || strings.Contains(allowedRoles, role)) {
|
||||||
|
// err = errors.UserHaveNoRole("User role not allowed")
|
||||||
|
// mw.logger.Emit(ErrorRoleAccess{err})
|
||||||
|
// http.Error(w, err.Error(), http.StatusForbidden)
|
||||||
|
// return
|
||||||
|
// }*/
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// next.ServeHTTP(w, r)
|
||||||
|
// })
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// MiddlewareJwtPlug jwt заглушка для отладки кода, удалить в релизе
|
||||||
|
///*
|
||||||
|
//func (mw *Middleware) MiddlewareJwtPlug(next http.Handler) http.Handler {
|
||||||
|
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// adapter := jwt_adapter.JwtAdapter{ID: "604b79aced1d431b9e911f56"}
|
||||||
|
// adapter.Init()
|
||||||
|
// adapter.SetUserID("604b79aced1d431b9e911f56")
|
||||||
|
// ctx := context.WithValue(r.Context(), "JWT", &adapter)
|
||||||
|
//
|
||||||
|
// next.ServeHTTP(w, r.WithContext(ctx))
|
||||||
|
// })
|
||||||
|
//}
|
||||||
|
//*/
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"heruvym/jwt_adapter"
|
"github.com/gofiber/fiber/v2"
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/themakers/hlog"
|
"github.com/themakers/hlog"
|
||||||
|
"heruvym/jwt_adapter"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setJwtHeader(adapter *jwt_adapter.JwtAdapter, w http.ResponseWriter, logger hlog.Logger) error {
|
// todo useless?
|
||||||
|
func setJwtHeader(adapter *jwt_adapter.JwtAdapter, w *fiber.Response, logger hlog.Logger) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,28 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"github.com/gofiber/fiber/v2"
|
||||||
"heruvym/jwt_adapter"
|
"heruvym/jwt_adapter"
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (mw *Middleware) MiddlewareGetJwt(next http.Handler) http.Handler {
|
func (mw *Middleware) MiddlewareGetJwt(c *fiber.Ctx) error {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
if c.Method() != fiber.MethodGet {
|
||||||
// Escape non-GET requests
|
return c.Next()
|
||||||
if r.Method != http.MethodGet {
|
}
|
||||||
next.ServeHTTP(w, r)
|
|
||||||
return
|
bearer := c.Query(jwt_adapter.DefaultHeaderKey)
|
||||||
|
if bearer != "" {
|
||||||
|
adapter, err := jwt_adapter.Decode(bearer)
|
||||||
|
if err == nil {
|
||||||
|
c.Locals(jwt_adapter.DefaultHeaderKey, adapter)
|
||||||
}
|
}
|
||||||
ctx := r.Context()
|
} else {
|
||||||
|
sess := c.Query("s")
|
||||||
bearer := r.URL.Query().Get(jwt_adapter.DefaultHeaderKey)
|
if sess == "" {
|
||||||
if bearer != "" {
|
return nil
|
||||||
|
|
||||||
adapter, err := jwt_adapter.Decode(bearer)
|
|
||||||
if err == nil {
|
|
||||||
//mw.logger.Emit(ErrorJwtAccess{Err: err})
|
|
||||||
//w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
//return
|
|
||||||
ctx = context.WithValue(r.Context(), jwt_adapter.DefaultHeaderKey, adapter)
|
|
||||||
//
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sess := r.URL.Query().Get("s")
|
|
||||||
if sess == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx = context.WithValue(r.Context(), jwt_adapter.DefaultHeaderKey, &jwt_adapter.JwtAdapter{Id: sess})
|
|
||||||
}
|
}
|
||||||
|
c.Locals(jwt_adapter.DefaultHeaderKey, &jwt_adapter.JwtAdapter{Id: sess})
|
||||||
|
}
|
||||||
|
|
||||||
next.ServeHTTP(w, r.WithContext(ctx))
|
return c.Next()
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user