Skip to content

Commit

Permalink
Allow LocalURL to be passed in the Host header
Browse files Browse the repository at this point in the history
  • Loading branch information
jannispl committed Nov 18, 2024
1 parent 5eb0ee4 commit 2afe51a
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
9 changes: 8 additions & 1 deletion modules/httplib/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,19 @@ func GuessCurrentHostURL(ctx context.Context) string {
// There are some cases:
// 1. The reverse proxy is configured correctly, it passes "X-Forwarded-Proto/Host" headers. Perfect, Gitea can handle it correctly.
// 2. The reverse proxy is not configured correctly, doesn't pass "X-Forwarded-Proto/Host" headers, eg: only one "proxy_pass http://gitea:3000" in Nginx.
// 3. There is no reverse proxy.
// 3. There is no reverse proxy. In this case, we allow the configured LocalURL to be passed in the Host header.
// Without an extra config option, Gitea is impossible to distinguish between case 2 and case 3,
// then case 2 would result in wrong guess like guessed AppURL becomes "http://gitea:3000/", which is not accessible by end users.
// So in the future maybe it should introduce a new config option, to let site admin decide how to guess the AppURL.
reqScheme := getRequestScheme(req)
if reqScheme == "" {
localURL, err := url.Parse(setting.LocalURL)
if err == nil &&
strings.EqualFold(req.Host, localURL.Host) &&
(req.TLS != nil) == (localURL.Scheme == "https") {
return strings.TrimSuffix(setting.LocalURL, setting.AppSubURL+"/")
}

return strings.TrimSuffix(setting.AppURL, setting.AppSubURL+"/")
}
// X-Forwarded-Host has many problems: non-standard, not well-defined (X-Forwarded-Port or not), conflicts with Host header.
Expand Down
28 changes: 28 additions & 0 deletions modules/httplib/url_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package httplib

import (
"context"
"crypto/tls"
"net/http"
"testing"

Expand Down Expand Up @@ -39,6 +40,33 @@ func TestIsRelativeURL(t *testing.T) {
}
}

func TestGuessCurrentHostURL(t *testing.T) {
defer test.MockVariableValue(&setting.AppURL, "http://cfg-host/sub/")()
defer test.MockVariableValue(&setting.LocalURL, "http://localhost:3000/sub/")()
defer test.MockVariableValue(&setting.AppSubURL, "/sub")()

ctx := context.Background()
assert.Equal(t, "http://cfg-host", GuessCurrentHostURL(ctx))

ctx = context.WithValue(ctx, RequestContextKey, &http.Request{
Host: "localhost:3000",
})
assert.Equal(t, "http://localhost:3000", GuessCurrentHostURL(ctx))

ctx = context.WithValue(ctx, RequestContextKey, &http.Request{
Host: "localhost:3000",
TLS: &tls.ConnectionState{},
})
assert.Equal(t, "http://cfg-host", GuessCurrentHostURL(ctx))

defer test.MockVariableValue(&setting.LocalURL, "https://localhost/sub/")()
ctx = context.WithValue(ctx, RequestContextKey, &http.Request{
Host: "localhost",
TLS: &tls.ConnectionState{},
})
assert.Equal(t, "https://localhost", GuessCurrentHostURL(ctx))
}

func TestMakeAbsoluteURL(t *testing.T) {
defer test.MockVariableValue(&setting.Protocol, "http")()
defer test.MockVariableValue(&setting.AppURL, "http://cfg-host/sub/")()
Expand Down

0 comments on commit 2afe51a

Please sign in to comment.