Add never option to PUBLIC_URL_DETECTION configuration (#36785)

Follow up #34250

Docs: https://gitea.com/gitea/docs/pulls/353

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Zettat123
2026-03-01 11:33:47 -07:00
committed by GitHub
parent 2c624d4deb
commit 5b8c8e724f
4 changed files with 22 additions and 1 deletions

View File

@@ -74,6 +74,7 @@ RUN_USER = ; git
;; especially when the Gitea instance needs to be accessed in a container network.
;; * legacy: detect the public URL from "Host" header if "X-Forwarded-Proto" header exists, otherwise use "ROOT_URL".
;; * auto: always use "Host" header, and also use "X-Forwarded-Proto" header if it exists. If no "Host" header, use "ROOT_URL".
;; * never: always use "ROOT_URL", never detect from request headers.
;PUBLIC_URL_DETECTION = legacy
;;
;; For development purpose only. It makes Gitea handle sub-path ("/sub-path/owner/repo/...") directly when debugging without a reverse proxy.

View File

@@ -72,6 +72,10 @@ func GuessCurrentAppURL(ctx context.Context) string {
// GuessCurrentHostURL tries to guess the current full host URL (no sub-path) by http headers, there is no trailing slash.
func GuessCurrentHostURL(ctx context.Context) string {
// "never" means always trust ROOT_URL and skip any request header detection.
if setting.PublicURLDetection == setting.PublicURLNever {
return strings.TrimSuffix(setting.AppURL, setting.AppSubURL+"/")
}
// Try the best guess to get the current host URL (will be used for public URL) by http headers.
// At the moment, if site admin doesn't configure the proxy headers correctly, then Gitea would guess wrong.
// There are some cases:

View File

@@ -77,6 +77,21 @@ func TestGuessCurrentHostURL(t *testing.T) {
ctx = context.WithValue(t.Context(), RequestContextKey, &http.Request{Host: "req-host:3000", Header: headersWithProto})
assert.Equal(t, "https://req-host:3000", GuessCurrentHostURL(ctx))
})
t.Run("Never", func(t *testing.T) {
defer test.MockVariableValue(&setting.PublicURLDetection, setting.PublicURLNever)()
assert.Equal(t, "http://cfg-host", GuessCurrentHostURL(t.Context()))
ctx := context.WithValue(t.Context(), RequestContextKey, &http.Request{Host: "req-host:3000"})
assert.Equal(t, "http://cfg-host", GuessCurrentHostURL(ctx))
ctx = context.WithValue(t.Context(), RequestContextKey, &http.Request{Host: "req-host:3000", TLS: &tls.ConnectionState{}})
assert.Equal(t, "http://cfg-host", GuessCurrentHostURL(ctx))
ctx = context.WithValue(t.Context(), RequestContextKey, &http.Request{Host: "req-host:3000", Header: headersWithProto})
assert.Equal(t, "http://cfg-host", GuessCurrentHostURL(ctx))
})
}
func TestMakeAbsoluteURL(t *testing.T) {

View File

@@ -44,6 +44,7 @@ const (
const (
PublicURLAuto = "auto"
PublicURLLegacy = "legacy"
PublicURLNever = "never"
)
// Server settings
@@ -286,7 +287,7 @@ func loadServerFrom(rootCfg ConfigProvider) {
defaultAppURL := string(Protocol) + "://" + Domain + ":" + HTTPPort
AppURL = sec.Key("ROOT_URL").MustString(defaultAppURL)
PublicURLDetection = sec.Key("PUBLIC_URL_DETECTION").MustString(PublicURLLegacy)
if PublicURLDetection != PublicURLAuto && PublicURLDetection != PublicURLLegacy {
if PublicURLDetection != PublicURLAuto && PublicURLDetection != PublicURLLegacy && PublicURLDetection != PublicURLNever {
log.Fatal("Invalid PUBLIC_URL_DETECTION value: %s", PublicURLDetection)
}