From b4c4b0a27ed44f9c9c225bcdb25664fb74475e1a Mon Sep 17 00:00:00 2001 From: ryan Date: Sun, 30 Aug 2026 11:07:22 +0800 Subject: [PATCH] feat(http): make trailing-slash redirect configurable --- backend/plugins/drivers/driver_http/config.go | 1 + backend/plugins/drivers/driver_http/engine.go | 5 ++++ .../drivers/driver_http/engine_slash_test.go | 28 +++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 backend/plugins/drivers/driver_http/engine_slash_test.go diff --git a/backend/plugins/drivers/driver_http/config.go b/backend/plugins/drivers/driver_http/config.go index df2046c1..af27dd07 100644 --- a/backend/plugins/drivers/driver_http/config.go +++ b/backend/plugins/drivers/driver_http/config.go @@ -15,6 +15,7 @@ type httpAppConfig struct { SessionAge int `config:"session_age" env:"APP_SESSION_AGE" default:"86400"` SessionHTTPOnly bool `config:"session_http_only" env:"APP_SESSION_HTTP_ONLY" default:"true"` SessionSecure bool `config:"session_secure" env:"APP_SESSION_SECURE"` + RedirectTrailingSlash *bool `config:"redirect_trailing_slash" env:"APP_REDIRECT_TRAILING_SLASH"` } type httpRedisConfig struct { diff --git a/backend/plugins/drivers/driver_http/engine.go b/backend/plugins/drivers/driver_http/engine.go index 2ca969a1..7e538f65 100644 --- a/backend/plugins/drivers/driver_http/engine.go +++ b/backend/plugins/drivers/driver_http/engine.go @@ -31,6 +31,11 @@ func BuildEngineWithConfig(appCfg httpAppConfig, redisCfg httpRedisConfig) (*gin // 初始化路由 r := gin.New() + redirect := true + if appCfg.RedirectTrailingSlash != nil { + redirect = *appCfg.RedirectTrailingSlash + } + r.RedirectTrailingSlash = redirect r.Use(gin.Recovery()) r.Use(corsMiddleware()) diff --git a/backend/plugins/drivers/driver_http/engine_slash_test.go b/backend/plugins/drivers/driver_http/engine_slash_test.go new file mode 100644 index 00000000..83c7e111 --- /dev/null +++ b/backend/plugins/drivers/driver_http/engine_slash_test.go @@ -0,0 +1,28 @@ +// Copyright 2026 Arctel.net +// SPDX-License-Identifier: Apache-2.0 + +package driver_http + +import "testing" + +func TestBuildEngineDefaultRedirectsTrailingSlash(t *testing.T) { + eng, err := BuildEngineWithConfig(httpAppConfig{}, httpRedisConfig{}) + if err != nil { + t.Fatal(err) + } + if !eng.RedirectTrailingSlash { + t.Fatal("default RedirectTrailingSlash must be true") + } +} + +func TestBuildEngineCanDisableRedirectTrailingSlash(t *testing.T) { + eng, err := BuildEngineWithConfig(httpAppConfig{RedirectTrailingSlash: boolPtr(false)}, httpRedisConfig{}) + if err != nil { + t.Fatal(err) + } + if eng.RedirectTrailingSlash { + t.Fatal("RedirectTrailingSlash must honor false") + } +} + +func boolPtr(v bool) *bool { return &v }