Skip to content

Commit e67258d

Browse files
committed
clarify the behavior and add more comments
1 parent 5a3d0c9 commit e67258d

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

modules/httplib/url.go

+20-11
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func IsRelativeURL(s string) bool {
3232
return err == nil && urlIsRelative(s, u)
3333
}
3434

35-
func guessRequestScheme(req *http.Request, def string) string {
35+
func getRequestScheme(req *http.Request) string {
3636
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto
3737
if s := req.Header.Get("X-Forwarded-Proto"); s != "" {
3838
return s
@@ -49,10 +49,10 @@ func guessRequestScheme(req *http.Request, def string) string {
4949
if s := req.Header.Get("X-Forwarded-Ssl"); s != "" {
5050
return util.Iif(s == "on", "https", "http")
5151
}
52-
return def
52+
return ""
5353
}
5454

55-
func guessForwardedHost(req *http.Request) string {
55+
func getForwardedHost(req *http.Request) string {
5656
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host
5757
return req.Header.Get("X-Forwarded-Host")
5858
}
@@ -63,15 +63,24 @@ func GuessCurrentAppURL(ctx context.Context) string {
6363
if !ok {
6464
return setting.AppURL
6565
}
66-
if host := guessForwardedHost(req); host != "" {
67-
// if it is behind a reverse proxy, use "https" as default scheme in case the site admin forgets to set the correct forwarded-protocol headers
68-
return guessRequestScheme(req, "https") + "://" + host + setting.AppSubURL + "/"
69-
} else if req.Host != "" {
70-
// if it is not behind a reverse proxy, use the scheme from config options, meanwhile use "https" as much as possible
71-
defaultScheme := util.Iif(setting.Protocol == "http", "http", "https")
72-
return guessRequestScheme(req, defaultScheme) + "://" + req.Host + setting.AppSubURL + "/"
66+
// If no scheme provided by reverse proxy, then do not guess the AppURL, use the configured one.
67+
// At the moment, if site admin doesn't configure the proxy headers correctly, then Gitea would guess wrong.
68+
// There are some cases:
69+
// 1. The reverse proxy is configured correctly, it passes "X-Forwarded-Proto/Host" headers. Perfect, Gitea can handle it correctly.
70+
// 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.
71+
// 3. There is no reverse proxy.
72+
// Without an extra config option, Gitea is impossible to distinguish between case 2 and case 3,
73+
// then case 2 would result in wrong guess like guessed AppURL becomes "http://gitea:3000/", which is not accessible by end users.
74+
// So in the future maybe it should introduce a new config option, to let site admin decide how to guess the AppURL.
75+
reqScheme := getRequestScheme(req)
76+
if reqScheme == "" {
77+
return setting.AppURL
78+
}
79+
reqHost := getForwardedHost(req)
80+
if reqHost == "" {
81+
reqHost = req.Host
7382
}
74-
return setting.AppURL
83+
return reqScheme + "://" + reqHost + setting.AppSubURL + "/"
7584
}
7685

7786
func MakeAbsoluteURL(ctx context.Context, s string) string {

modules/httplib/url_test.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,27 @@ func TestIsRelativeURL(t *testing.T) {
4141

4242
func TestMakeAbsoluteURL(t *testing.T) {
4343
defer test.MockVariableValue(&setting.Protocol, "http")()
44-
defer test.MockVariableValue(&setting.AppURL, "http://the-host/sub/")()
44+
defer test.MockVariableValue(&setting.AppURL, "http://cfg-host/sub/")()
4545
defer test.MockVariableValue(&setting.AppSubURL, "/sub")()
4646

4747
ctx := context.Background()
48-
assert.Equal(t, "http://the-host/sub/", MakeAbsoluteURL(ctx, ""))
49-
assert.Equal(t, "http://the-host/sub/foo", MakeAbsoluteURL(ctx, "foo"))
50-
assert.Equal(t, "http://the-host/sub/foo", MakeAbsoluteURL(ctx, "/foo"))
48+
assert.Equal(t, "http://cfg-host/sub/", MakeAbsoluteURL(ctx, ""))
49+
assert.Equal(t, "http://cfg-host/sub/foo", MakeAbsoluteURL(ctx, "foo"))
50+
assert.Equal(t, "http://cfg-host/sub/foo", MakeAbsoluteURL(ctx, "/foo"))
5151
assert.Equal(t, "http://other/foo", MakeAbsoluteURL(ctx, "http://other/foo"))
5252

5353
ctx = context.WithValue(ctx, RequestContextKey, &http.Request{
5454
Host: "user-host",
5555
})
56-
assert.Equal(t, "http://user-host/sub/foo", MakeAbsoluteURL(ctx, "/foo"))
56+
assert.Equal(t, "http://cfg-host/sub/foo", MakeAbsoluteURL(ctx, "/foo"))
5757

5858
ctx = context.WithValue(ctx, RequestContextKey, &http.Request{
5959
Host: "user-host",
6060
Header: map[string][]string{
6161
"X-Forwarded-Host": {"forwarded-host"},
6262
},
6363
})
64-
assert.Equal(t, "https://forwarded-host/sub/foo", MakeAbsoluteURL(ctx, "/foo"))
64+
assert.Equal(t, "http://cfg-host/sub/foo", MakeAbsoluteURL(ctx, "/foo"))
6565

6666
ctx = context.WithValue(ctx, RequestContextKey, &http.Request{
6767
Host: "user-host",

0 commit comments

Comments
 (0)