mirror of
https://github.com/go-gitea/gitea
synced 2024-11-09 11:44:27 +00:00
d32648b204
Refactor route path normalization and decouple it from the chi router. Fix the TODO, fix the legacy strange path behavior.
101 lines
3.3 KiB
Go
101 lines
3.3 KiB
Go
// Copyright 2021 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package common
|
|
|
|
import (
|
|
go_context "context"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"code.gitea.io/gitea/modules/cache"
|
|
"code.gitea.io/gitea/modules/httplib"
|
|
"code.gitea.io/gitea/modules/process"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
"code.gitea.io/gitea/modules/web/middleware"
|
|
"code.gitea.io/gitea/modules/web/routing"
|
|
"code.gitea.io/gitea/services/context"
|
|
|
|
"gitea.com/go-chi/session"
|
|
"github.com/chi-middleware/proxy"
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
// ProtocolMiddlewares returns HTTP protocol related middlewares, and it provides a global panic recovery
|
|
func ProtocolMiddlewares() (handlers []any) {
|
|
// make sure chi uses EscapedPath(RawPath) as RoutePath, then "%2f" could be handled correctly
|
|
handlers = append(handlers, func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
|
ctx := chi.RouteContext(req.Context())
|
|
if req.URL.RawPath == "" {
|
|
ctx.RoutePath = req.URL.EscapedPath()
|
|
} else {
|
|
ctx.RoutePath = req.URL.RawPath
|
|
}
|
|
next.ServeHTTP(resp, req)
|
|
})
|
|
})
|
|
|
|
// prepare the ContextData and panic recovery
|
|
handlers = append(handlers, func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
RenderPanicErrorPage(resp, req, err) // it should never panic
|
|
}
|
|
}()
|
|
req = req.WithContext(middleware.WithContextData(req.Context()))
|
|
req = req.WithContext(go_context.WithValue(req.Context(), httplib.RequestContextKey, req))
|
|
next.ServeHTTP(resp, req)
|
|
})
|
|
})
|
|
|
|
// wrap the request and response, use the process context and add it to the process manager
|
|
handlers = append(handlers, func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
|
ctx, _, finished := process.GetManager().AddTypedContext(req.Context(), fmt.Sprintf("%s: %s", req.Method, req.RequestURI), process.RequestProcessType, true)
|
|
defer finished()
|
|
next.ServeHTTP(context.WrapResponseWriter(resp), req.WithContext(cache.WithCacheContext(ctx)))
|
|
})
|
|
})
|
|
|
|
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))
|
|
}
|
|
|
|
if setting.IsRouteLogEnabled() {
|
|
handlers = append(handlers, routing.NewLoggerHandler())
|
|
}
|
|
|
|
if setting.IsAccessLogEnabled() {
|
|
handlers = append(handlers, context.AccessLogger())
|
|
}
|
|
|
|
return handlers
|
|
}
|
|
|
|
func Sessioner() func(next http.Handler) http.Handler {
|
|
return session.Sessioner(session.Options{
|
|
Provider: setting.SessionConfig.Provider,
|
|
ProviderConfig: setting.SessionConfig.ProviderConfig,
|
|
CookieName: setting.SessionConfig.CookieName,
|
|
CookiePath: setting.SessionConfig.CookiePath,
|
|
Gclifetime: setting.SessionConfig.Gclifetime,
|
|
Maxlifetime: setting.SessionConfig.Maxlifetime,
|
|
Secure: setting.SessionConfig.Secure,
|
|
SameSite: setting.SessionConfig.SameSite,
|
|
Domain: setting.SessionConfig.Domain,
|
|
})
|
|
}
|