Files
Atay-Makhzan/routers/common/middleware.go
T

84 lines
2.5 KiB
Go
Raw Normal View History

2021-06-09 07:33:54 +08:00
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package common
import (
"fmt"
"net/http"
"strings"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
2021-06-09 07:33:54 +08:00
"code.gitea.io/gitea/modules/setting"
2022-01-20 19:41:25 +08:00
"code.gitea.io/gitea/modules/web/routing"
2021-06-09 07:33:54 +08:00
"github.com/chi-middleware/proxy"
"github.com/go-chi/chi/v5/middleware"
2021-06-09 07:33:54 +08:00
)
// Middlewares returns common middlewares
func Middlewares() []func(http.Handler) http.Handler {
2022-01-20 18:46:10 +01:00
handlers := []func(http.Handler) http.Handler{
2021-06-09 07:33:54 +08:00
func(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
// First of all escape the URL RawPath to ensure that all routing is done using a correctly escaped URL
req.URL.RawPath = req.URL.EscapedPath()
ctx, _, finished := process.GetManager().AddContext(req.Context(), fmt.Sprintf("%s: %s", req.Method, req.RequestURI))
defer finished()
next.ServeHTTP(context.NewResponse(resp), req.WithContext(ctx))
2021-06-09 07:33:54 +08:00
})
},
}
if setting.ReverseProxyLimit > 0 {
opt := proxy.NewForwardedHeadersOptions().
WithForwardLimit(setting.ReverseProxyLimit).
ClearTrustedProxies()
for _, n := range setting.ReverseProxyTrustedProxies {
if !strings.Contains(n, "/") {
opt.AddTrustedProxy(n)
} else {
opt.AddTrustedNetwork(n)
}
}
handlers = append(handlers, proxy.ForwardedHeaders(opt))
}
handlers = append(handlers, middleware.StripSlashes)
2022-01-20 19:41:25 +08:00
if !setting.DisableRouterLog {
handlers = append(handlers, routing.NewLoggerHandler())
2021-06-09 07:33:54 +08:00
}
2022-01-20 19:41:25 +08:00
2021-06-09 07:33:54 +08:00
if setting.EnableAccessLog {
handlers = append(handlers, context.AccessLogger())
}
handlers = append(handlers, func(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
// Why we need this? The Recovery() will try to render a beautiful
// error page for user, but the process can still panic again, and other
// middleware like session also may panic then we have to recover twice
2022-01-20 19:41:25 +08:00
// and send a simple error page that should not panic anymore.
2021-06-09 07:33:54 +08:00
defer func() {
if err := recover(); err != nil {
2022-01-20 19:41:25 +08:00
routing.UpdatePanicError(req.Context(), err)
combinedErr := fmt.Sprintf("PANIC: %v\n%s", err, log.Stack(2))
2021-06-09 07:33:54 +08:00
log.Error("%v", combinedErr)
if setting.IsProd {
2021-06-09 07:33:54 +08:00
http.Error(resp, http.StatusText(500), 500)
} else {
http.Error(resp, combinedErr, 500)
}
}
}()
next.ServeHTTP(resp, req)
})
})
return handlers
}