| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- // Copyright 2023 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package httplib
-
- import (
- "context"
- "crypto/tls"
- "net/http"
- "testing"
-
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
-
- "github.com/stretchr/testify/assert"
- )
-
- func TestIsRelativeURL(t *testing.T) {
- defer test.MockVariableValue(&setting.AppURL, "http://localhost:3000/sub/")()
- defer test.MockVariableValue(&setting.AppSubURL, "/sub")()
- rel := []string{
- "",
- "foo",
- "/",
- "/foo?k=%20#abc",
- }
- for _, s := range rel {
- assert.True(t, IsRelativeURL(s), "rel = %q", s)
- }
- abs := []string{
- "//",
- "\\\\",
- "/\\",
- "\\/",
- "mailto:a@b.com",
- "https://test.com",
- }
- for _, s := range abs {
- assert.False(t, IsRelativeURL(s), "abs = %q", s)
- }
- }
-
- func TestGuessCurrentHostURL(t *testing.T) {
- defer test.MockVariableValue(&setting.AppURL, "http://cfg-host/sub/")()
- defer test.MockVariableValue(&setting.AppSubURL, "/sub")()
- headersWithProto := http.Header{"X-Forwarded-Proto": {"https"}}
-
- t.Run("Legacy", func(t *testing.T) {
- defer test.MockVariableValue(&setting.PublicURLDetection, setting.PublicURLLegacy)()
-
- assert.Equal(t, "http://cfg-host", GuessCurrentHostURL(t.Context()))
-
- // legacy: "Host" is not used when there is no "X-Forwarded-Proto" header
- ctx := context.WithValue(t.Context(), RequestContextKey, &http.Request{Host: "req-host:3000"})
- assert.Equal(t, "http://cfg-host", GuessCurrentHostURL(ctx))
-
- // if "X-Forwarded-Proto" exists, then use it and "Host" header
- 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("Auto", func(t *testing.T) {
- defer test.MockVariableValue(&setting.PublicURLDetection, setting.PublicURLAuto)()
-
- assert.Equal(t, "http://cfg-host", GuessCurrentHostURL(t.Context()))
-
- // auto: always use "Host" header, the scheme is determined by "X-Forwarded-Proto" header, or TLS config if no "X-Forwarded-Proto" header
- ctx := context.WithValue(t.Context(), RequestContextKey, &http.Request{Host: "req-host:3000"})
- assert.Equal(t, "http://req-host:3000", GuessCurrentHostURL(ctx))
-
- ctx = context.WithValue(t.Context(), RequestContextKey, &http.Request{Host: "req-host", TLS: &tls.ConnectionState{}})
- assert.Equal(t, "https://req-host", GuessCurrentHostURL(ctx))
-
- ctx = context.WithValue(t.Context(), RequestContextKey, &http.Request{Host: "req-host:3000", Header: headersWithProto})
- assert.Equal(t, "https://req-host:3000", GuessCurrentHostURL(ctx))
- })
- }
-
- func TestMakeAbsoluteURL(t *testing.T) {
- defer test.MockVariableValue(&setting.Protocol, "http")()
- defer test.MockVariableValue(&setting.AppURL, "http://cfg-host/sub/")()
- defer test.MockVariableValue(&setting.AppSubURL, "/sub")()
-
- ctx := t.Context()
- assert.Equal(t, "http://cfg-host/sub/", MakeAbsoluteURL(ctx, ""))
- assert.Equal(t, "http://cfg-host/foo", MakeAbsoluteURL(ctx, "foo"))
- assert.Equal(t, "http://cfg-host/foo", MakeAbsoluteURL(ctx, "/foo"))
- assert.Equal(t, "http://other/foo", MakeAbsoluteURL(ctx, "http://other/foo"))
-
- ctx = context.WithValue(ctx, RequestContextKey, &http.Request{
- Host: "user-host",
- })
- assert.Equal(t, "http://cfg-host/foo", MakeAbsoluteURL(ctx, "/foo"))
-
- ctx = context.WithValue(ctx, RequestContextKey, &http.Request{
- Host: "user-host",
- Header: map[string][]string{
- "X-Forwarded-Host": {"forwarded-host"},
- },
- })
- assert.Equal(t, "http://cfg-host/foo", MakeAbsoluteURL(ctx, "/foo"))
-
- ctx = context.WithValue(ctx, RequestContextKey, &http.Request{
- Host: "user-host",
- Header: map[string][]string{
- "X-Forwarded-Host": {"forwarded-host"},
- "X-Forwarded-Proto": {"https"},
- },
- })
- assert.Equal(t, "https://user-host/foo", MakeAbsoluteURL(ctx, "/foo"))
- }
-
- func TestIsCurrentGiteaSiteURL(t *testing.T) {
- defer test.MockVariableValue(&setting.AppURL, "http://localhost:3000/sub/")()
- defer test.MockVariableValue(&setting.AppSubURL, "/sub")()
- ctx := t.Context()
- good := []string{
- "?key=val",
- "/sub",
- "/sub/",
- "/sub/foo",
- "/sub/foo/",
- "http://localhost:3000/sub?key=val",
- "http://localhost:3000/sub/",
- }
- for _, s := range good {
- assert.True(t, IsCurrentGiteaSiteURL(ctx, s), "good = %q", s)
- }
- bad := []string{
- ".",
- "foo",
- "/",
- "//",
- "\\\\",
- "/foo",
- "http://localhost:3000/sub/..",
- "http://localhost:3000/other",
- "http://other/",
- }
- for _, s := range bad {
- assert.False(t, IsCurrentGiteaSiteURL(ctx, s), "bad = %q", s)
- }
-
- setting.AppURL = "http://localhost:3000/"
- setting.AppSubURL = ""
- assert.False(t, IsCurrentGiteaSiteURL(ctx, "//"))
- assert.False(t, IsCurrentGiteaSiteURL(ctx, "\\\\"))
- assert.False(t, IsCurrentGiteaSiteURL(ctx, "http://localhost"))
- assert.True(t, IsCurrentGiteaSiteURL(ctx, "http://localhost:3000?key=val"))
-
- ctx = context.WithValue(ctx, RequestContextKey, &http.Request{
- Host: "user-host",
- Header: map[string][]string{
- "X-Forwarded-Host": {"forwarded-host"},
- "X-Forwarded-Proto": {"https"},
- },
- })
- assert.True(t, IsCurrentGiteaSiteURL(ctx, "http://localhost:3000"))
- assert.True(t, IsCurrentGiteaSiteURL(ctx, "https://user-host"))
- assert.False(t, IsCurrentGiteaSiteURL(ctx, "https://forwarded-host"))
- }
-
- func TestParseGiteaSiteURL(t *testing.T) {
- defer test.MockVariableValue(&setting.AppURL, "http://localhost:3000/sub/")()
- defer test.MockVariableValue(&setting.AppSubURL, "/sub")()
- ctx := t.Context()
- tests := []struct {
- url string
- exp *GiteaSiteURL
- }{
- {"http://localhost:3000/sub?k=v", &GiteaSiteURL{RoutePath: ""}},
- {"http://localhost:3000/sub/", &GiteaSiteURL{RoutePath: ""}},
- {"http://localhost:3000/sub/foo", &GiteaSiteURL{RoutePath: "/foo"}},
- {"http://localhost:3000/sub/foo/bar", &GiteaSiteURL{RoutePath: "/foo/bar", OwnerName: "foo", RepoName: "bar"}},
- {"http://localhost:3000/sub/foo/bar/", &GiteaSiteURL{RoutePath: "/foo/bar", OwnerName: "foo", RepoName: "bar"}},
- {"http://localhost:3000/sub/attachments/bar", &GiteaSiteURL{RoutePath: "/attachments/bar"}},
- {"http://localhost:3000/other", nil},
- {"http://other/", nil},
- }
- for _, test := range tests {
- su := ParseGiteaSiteURL(ctx, test.url)
- assert.Equal(t, test.exp, su, "URL = %s", test.url)
- }
- }
|