Skip to content

Commit d9843d5

Browse files
authored
Fix Subpath parsing (#1900)
1 parent 9c64c57 commit d9843d5

File tree

2 files changed

+149
-8
lines changed

2 files changed

+149
-8
lines changed

restapi/configure_console.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"log"
2828
"net"
2929
"net/http"
30+
"path"
3031
"path/filepath"
3132
"regexp"
3233
"strings"
@@ -53,6 +54,10 @@ var additionalServerFlags = struct {
5354
CertsDir string `long:"certs-dir" description:"path to certs directory" env:"CONSOLE_CERTS_DIR"`
5455
}{}
5556

57+
const (
58+
SubPath = "CONSOLE_SUBPATH"
59+
)
60+
5661
var subPath = "/"
5762
var subPathOnce sync.Once
5863

@@ -363,18 +368,29 @@ func configureServer(s *http.Server, _, _ string) {
363368

364369
func getSubPath() string {
365370
subPathOnce.Do(func() {
366-
if v := env.Get("CONSOLE_SUBPATH", ""); v != "" {
367-
// Replace all unnecessary `\` to `/`
368-
// also add pro-actively at the end.
369-
subPath = filepath.Clean(filepath.ToSlash(v)) + SlashSeparator
370-
if !strings.HasPrefix(subPath, SlashSeparator) {
371-
subPath = SlashSeparator + subPath
372-
}
373-
}
371+
372+
subPath = parseSubPath(env.Get(SubPath, ""))
374373
})
375374
return subPath
376375
}
377376

377+
func parseSubPath(v string) string {
378+
v = strings.TrimSpace(v)
379+
if v == "" {
380+
return SlashSeparator
381+
}
382+
// Replace all unnecessary `\` to `/`
383+
// also add pro-actively at the end.
384+
subPath = path.Clean(filepath.ToSlash(v))
385+
if !strings.HasPrefix(subPath, SlashSeparator) {
386+
subPath = SlashSeparator + subPath
387+
}
388+
if !strings.HasSuffix(subPath, SlashSeparator) {
389+
subPath = subPath + SlashSeparator
390+
}
391+
return subPath
392+
}
393+
378394
func replaceBaseInIndex(indexPageBytes []byte, basePath string) []byte {
379395
if basePath != "" {
380396
validBasePath := regexp.MustCompile(`^[0-9a-zA-Z\/-]+$`)

restapi/configure_console_test.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2022 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package restapi
18+
19+
import (
20+
"os"
21+
"sync"
22+
"testing"
23+
24+
"github.com/stretchr/testify/assert"
25+
)
26+
27+
func Test_parseSubPath(t *testing.T) {
28+
type args struct {
29+
v string
30+
}
31+
tests := []struct {
32+
name string
33+
args args
34+
want string
35+
}{
36+
{
37+
name: "Empty",
38+
args: args{
39+
v: "",
40+
},
41+
want: "/",
42+
},
43+
{
44+
name: "Slash",
45+
args: args{
46+
v: "/",
47+
},
48+
want: "/",
49+
},
50+
{
51+
name: "Double Slash",
52+
args: args{
53+
v: "//",
54+
},
55+
want: "/",
56+
},
57+
{
58+
name: "No slashes",
59+
args: args{
60+
v: "route",
61+
},
62+
want: "/route/",
63+
},
64+
{
65+
name: "No trailing slashes",
66+
args: args{
67+
v: "/route",
68+
},
69+
want: "/route/",
70+
},
71+
}
72+
for _, tt := range tests {
73+
t.Run(tt.name, func(t *testing.T) {
74+
assert.Equalf(t, tt.want, parseSubPath(tt.args.v), "parseSubPath(%v)", tt.args.v)
75+
})
76+
}
77+
}
78+
79+
func Test_getSubPath(t *testing.T) {
80+
type args struct {
81+
envValue string
82+
}
83+
tests := []struct {
84+
name string
85+
args args
86+
want string
87+
}{
88+
{
89+
name: "Empty",
90+
args: args{
91+
envValue: "",
92+
},
93+
want: "/",
94+
},
95+
{
96+
name: "Slash",
97+
args: args{
98+
envValue: "/",
99+
},
100+
want: "/",
101+
},
102+
{
103+
name: "Valid Value",
104+
args: args{
105+
envValue: "/subpath/",
106+
},
107+
want: "/subpath/",
108+
},
109+
{
110+
name: "No starting slash",
111+
args: args{
112+
envValue: "subpath/",
113+
},
114+
want: "/subpath/",
115+
},
116+
}
117+
for _, tt := range tests {
118+
t.Run(tt.name, func(t *testing.T) {
119+
os.Setenv(SubPath, tt.args.envValue)
120+
defer os.Unsetenv(SubPath)
121+
subPathOnce = sync.Once{}
122+
assert.Equalf(t, tt.want, getSubPath(), "getSubPath()")
123+
})
124+
}
125+
}

0 commit comments

Comments
 (0)