mirror of
https://github.com/go-gitea/gitea.git
synced 2025-10-04 07:46:28 +00:00

the middleware that creates the session provider just panics if on creation the config is wrong. this is not catched and so you just get an cryptic stacktrace with no point where to look at (as user). ## Before ``` 2025/09/16 03:56:37 ...xer/stats/indexer.go:87:populateRepoIndexer() [I] Done (re)populating the repo stats indexer with existing repositories 2025/09/16 03:56:37 modules/ssh/ssh.go:387:Listen() [I] Adding SSH host key: /var/lib/gitea/data/ssh/gitea.rsa 2025/09/16 03:56:37 modules/ssh/init.go:26:Init() [I] SSH server started on :1234. Cipher list ([chacha20-poly1305@openssh.com aes128-ctr aes192-ctr aes256-ctr aes128-gcm@openssh.com aes256-gcm@openssh.com]), key exchange algorithms ([curve25519-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 diffie-hellman-group14-sha256 diffie-hellman-group14-sha1]), MACs ([hmac-sha2-256-etm@openssh.com hmac-sha2-256 hmac-sha1]) 2025/09/16 03:56:37 ...s/graceful/server.go:50:NewServer() [I] Starting new SSH server: tcp::1234 on PID: 83337 2025/09/16 03:56:38 cmd/web.go:231:func1() [F] PANIC: dial tcp 127.0.0.1:6379: connect: connection refused gitea.com/go-chi/session@v0.0.0-20240316035857-16768d98ec96/session.go:239 (0x1cdb908) code.gitea.io/gitea/routers/common/middleware.go:108 (0x2547f5a) code.gitea.io/gitea/routers/web/web.go:270 (0x278b8e9) code.gitea.io/gitea/routers/init.go:185 (0x2850d89) code.gitea.io/gitea/cmd/web.go:211 (0x295c5ad) code.gitea.io/gitea/cmd/web.go:262 (0x295cacb) code.gitea.io/gitea/cmd/main.go:111 (0x2953422) github.com/urfave/cli/v2@v2.27.2/command.go:276 (0x1cc3dfd) github.com/urfave/cli/v2@v2.27.2/command.go:269 (0x1cc4084) github.com/urfave/cli/v2@v2.27.2/app.go:333 (0x1cc086a) github.com/urfave/cli/v2@v2.27.2/app.go:307 (0x2953f18) code.gitea.io/gitea/cmd/main.go:172 (0x2953efc) code.gitea.io/gitea/main.go:46 (0x2998498) runtime/proc.go:283 (0x4471ca) runtime/asm_amd64.s:1700 (0x484a20) ``` ## After ``` 2025/09/22 22:52:35 .../templates/htmlrenderer.go:118:initHTMLRenderer() [D] Creating static HTML Renderer 2025/09/22 22:52:35 routers/web/web.go:273:Routes() [F] common.Sessioner failed: failed to create session middleware: dial tcp 127.0.0.1:6379: connect: connection refused ``` --------- Signed-off-by: 6543 <6543@obermui.de>
128 lines
4.1 KiB
Go
128 lines
4.1 KiB
Go
// Copyright 2021 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package common
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"code.gitea.io/gitea/modules/cache"
|
|
"code.gitea.io/gitea/modules/gtprof"
|
|
"code.gitea.io/gitea/modules/httplib"
|
|
"code.gitea.io/gitea/modules/reqctx"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
"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) {
|
|
// the order is important
|
|
handlers = append(handlers, ChiRoutePathHandler()) // make sure chi has correct paths
|
|
handlers = append(handlers, RequestContextHandler()) // prepare the context and panic recovery
|
|
|
|
if setting.ReverseProxyLimit > 0 && len(setting.ReverseProxyTrustedProxies) > 0 {
|
|
handlers = append(handlers, ForwardedHeadersHandler(setting.ReverseProxyLimit, setting.ReverseProxyTrustedProxies))
|
|
}
|
|
|
|
if setting.IsRouteLogEnabled() {
|
|
handlers = append(handlers, routing.NewLoggerHandler())
|
|
}
|
|
|
|
if setting.IsAccessLogEnabled() {
|
|
handlers = append(handlers, context.AccessLogger())
|
|
}
|
|
|
|
return handlers
|
|
}
|
|
|
|
func RequestContextHandler() func(h http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(respOrig http.ResponseWriter, req *http.Request) {
|
|
// this response writer might not be the same as the one in context.Base.Resp
|
|
// because there might be a "gzip writer" in the middle, so the "written size" here is the compressed size
|
|
respWriter := context.WrapResponseWriter(respOrig)
|
|
|
|
profDesc := fmt.Sprintf("HTTP: %s %s", req.Method, req.RequestURI)
|
|
ctx, finished := reqctx.NewRequestContext(req.Context(), profDesc)
|
|
defer finished()
|
|
|
|
ctx, span := gtprof.GetTracer().Start(ctx, gtprof.TraceSpanHTTP)
|
|
req = req.WithContext(ctx)
|
|
defer func() {
|
|
chiCtx := chi.RouteContext(req.Context())
|
|
span.SetAttributeString(gtprof.TraceAttrHTTPRoute, chiCtx.RoutePattern())
|
|
span.End()
|
|
}()
|
|
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
RenderPanicErrorPage(respWriter, req, err) // it should never panic
|
|
}
|
|
}()
|
|
|
|
ds := reqctx.GetRequestDataStore(ctx)
|
|
req = req.WithContext(cache.WithCacheContext(ctx))
|
|
ds.SetContextValue(httplib.RequestContextKey, req)
|
|
ds.AddCleanUp(func() {
|
|
if req.MultipartForm != nil {
|
|
_ = req.MultipartForm.RemoveAll() // remove the temp files buffered to tmp directory
|
|
}
|
|
})
|
|
next.ServeHTTP(respWriter, req)
|
|
})
|
|
}
|
|
}
|
|
|
|
func ChiRoutePathHandler() func(h http.Handler) http.Handler {
|
|
// make sure chi uses EscapedPath(RawPath) as RoutePath, then "%2f" could be handled correctly
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
|
chiCtx := chi.RouteContext(req.Context())
|
|
if req.URL.RawPath == "" {
|
|
chiCtx.RoutePath = req.URL.EscapedPath()
|
|
} else {
|
|
chiCtx.RoutePath = req.URL.RawPath
|
|
}
|
|
next.ServeHTTP(resp, req)
|
|
})
|
|
}
|
|
}
|
|
|
|
func ForwardedHeadersHandler(limit int, trustedProxies []string) func(h http.Handler) http.Handler {
|
|
opt := proxy.NewForwardedHeadersOptions().WithForwardLimit(limit).ClearTrustedProxies()
|
|
for _, n := range trustedProxies {
|
|
if !strings.Contains(n, "/") {
|
|
opt.AddTrustedProxy(n)
|
|
} else {
|
|
opt.AddTrustedNetwork(n)
|
|
}
|
|
}
|
|
return proxy.ForwardedHeaders(opt)
|
|
}
|
|
|
|
func Sessioner() (func(next http.Handler) http.Handler, error) {
|
|
middleware, err := 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,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create session middleware: %w", err)
|
|
}
|
|
|
|
return middleware, nil
|
|
}
|