Skip to content

Commit f926867

Browse files
committed
refactor(param): decouple headers cli param deserialization and normalization
1 parent f9b623a commit f926867

File tree

5 files changed

+87
-97
lines changed

5 files changed

+87
-97
lines changed

src/param/cli.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package param
33
import (
44
"../goNixArgParser"
55
"../serverError"
6-
"../util"
76
"errors"
87
"net/http"
98
"os"
@@ -278,7 +277,6 @@ func ParseCli() (params []*Param, printVersion, printHelp bool, errs []error) {
278277

279278
// init param data
280279
params = make([]*Param, 0, len(results))
281-
var es []error
282280
for _, result := range results {
283281
param := &Param{}
284282

@@ -329,14 +327,12 @@ func ParseCli() (params []*Param, printVersion, printHelp bool, errs []error) {
329327
param.GlobalHeaders = entriesToHeaders(globalHeaders)
330328

331329
// headers urls
332-
arrHeadersUrls, _ := result.GetStrings("headersurls")
333-
param.HeadersUrls, es = normalizePathHeadersMap(arrHeadersUrls, util.NormalizeUrlPath)
334-
errs = append(errs, es...)
330+
headersUrls, _ := result.GetStrings("headersurls")
331+
param.HeadersUrls = splitAllKeyValues(headersUrls)
335332

336333
// headers dirs
337-
arrHeadersDirs, _ := result.GetStrings("headersdirs")
338-
param.HeadersDirs, es = normalizePathHeadersMap(arrHeadersDirs, util.NormalizeFsPath)
339-
errs = append(errs, es...)
334+
headersDirs, _ := result.GetStrings("headersdirs")
335+
param.HeadersDirs = splitAllKeyValues(headersDirs)
340336

341337
// certificate
342338
certFiles, _ := result.GetStrings("certs")

src/param/main.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ type Param struct {
2626

2727
// value: [name, value]
2828
GlobalHeaders [][2]string
29-
HeadersUrls map[string][][2]string
30-
HeadersDirs map[string][][2]string
29+
// value: [path, (name, value)...]
30+
HeadersUrls [][]string
31+
HeadersDirs [][]string
3132

3233
GlobalUpload bool
3334
UploadUrls []string
@@ -130,10 +131,17 @@ func (param *Param) normalize() (errs []error) {
130131
}
131132

132133
// restrict access
133-
param.RestrictAccessUrls, es = normalizePathRestrictAccesses(param.RestrictAccessUrls, util.NormalizeUrlPath)
134+
param.RestrictAccessUrls, es = normalizePathValues(param.RestrictAccessUrls, true, util.NormalizeUrlPath, util.ExtractHostsFromUrls)
134135
errs = append(errs, es...)
135136

136-
param.RestrictAccessDirs, es = normalizePathRestrictAccesses(param.RestrictAccessDirs, util.NormalizeFsPath)
137+
param.RestrictAccessDirs, es = normalizePathValues(param.RestrictAccessDirs, true, util.NormalizeFsPath, util.ExtractHostsFromUrls)
138+
errs = append(errs, es...)
139+
140+
// headers
141+
param.HeadersUrls, es = normalizePathValues(param.HeadersUrls, false, util.NormalizeUrlPath, normalizeHeaders)
142+
errs = append(errs, es...)
143+
144+
param.HeadersDirs, es = normalizePathValues(param.HeadersDirs, false, util.NormalizeFsPath, normalizeHeaders)
137145
errs = append(errs, es...)
138146

139147
// upload/mkdir/delete/archive/cors/auth urls/dirs

src/param/strUtil.go

Lines changed: 30 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ func splitAllKeyValues(inputs []string) (results [][]string) {
4747
return
4848
}
4949

50-
func splitKeyValue(input string) (sep rune, sepLen int, k, v string, ok bool) {
51-
sep, sepLen = utf8.DecodeRuneInString(input)
50+
func splitKeyValue(input string) (k, v string, ok bool) {
51+
sep, sepLen := utf8.DecodeRuneInString(input)
5252
if sepLen == 0 {
5353
return
5454
}
@@ -64,23 +64,25 @@ func splitKeyValue(input string) (sep rune, sepLen int, k, v string, ok bool) {
6464

6565
k = entry[:sepIndex]
6666
v = entry[sepIndex+sepLen:]
67-
return sep, sepLen, k, v, true
67+
return k, v, true
6868
}
6969

7070
func splitAllKeyValue(inputs []string) (results [][2]string) {
7171
results = make([][2]string, 0, len(inputs))
7272
for i := range inputs {
73-
_, _, k, v, ok := splitKeyValue(inputs[i])
73+
k, v, ok := splitKeyValue(inputs[i])
7474
if ok {
7575
results = append(results, [2]string{k, v})
7676
}
7777
}
7878
return
7979
}
8080

81-
func normalizePathRestrictAccesses(
81+
func normalizePathValues(
8282
inputs [][]string,
83+
keepEmptyValuesEntry bool,
8384
normalizePath func(string) (string, error),
85+
normalizeEntryValues func([]string) []string,
8486
) (results [][]string, errs []error) {
8587
var err error
8688
results = make([][]string, 0, len(inputs))
@@ -101,58 +103,26 @@ eachInput:
101103
continue
102104
}
103105

104-
hosts := inputs[i][1:]
105-
if len(hosts) > 0 {
106-
hosts = util.ExtractHostsFromUrls(hosts)
107-
for j := range results {
108-
if util.IsPathEqual(results[j][0], reqPath) {
109-
results[j] = append(results[j], hosts...)
110-
continue eachInput
111-
}
106+
values := inputs[i][1:]
107+
if normalizeEntryValues != nil {
108+
values = normalizeEntryValues(values)
109+
}
110+
for j := range results {
111+
if util.IsPathEqual(results[j][0], reqPath) {
112+
results[j] = append(results[j], values...)
113+
continue eachInput
112114
}
113115
}
114116

115-
restrict := make([]string, 1+len(hosts))
116-
restrict[0] = reqPath
117-
copy(restrict[1:], hosts)
118-
119-
results = append(results, restrict)
120-
}
121-
122-
return
123-
}
124-
125-
func normalizePathHeadersMap(
126-
inputs []string,
127-
normalizePath func(string) (string, error),
128-
) (maps map[string][][2]string, errs []error) {
129-
maps = make(map[string][][2]string, len(inputs))
130-
131-
for _, input := range inputs {
132-
sep, sepLen, reqPath, header, ok := splitKeyValue(input)
133-
if !ok {
134-
continue
135-
}
136-
sepIndex := strings.IndexRune(header, sep)
137-
if sepIndex <= 0 || sepIndex+sepLen == len(header) {
117+
if len(values) == 0 && !keepEmptyValuesEntry {
138118
continue
139119
}
140120

141-
normalizedPath, err := normalizePath(reqPath)
142-
if err != nil {
143-
errs = append(errs, err)
144-
}
145-
headerName := header[:sepIndex]
146-
headerValue := header[sepIndex+1:]
121+
entry := make([]string, 1+len(values))
122+
entry[0] = reqPath
123+
copy(entry[1:], values)
147124

148-
for existingPath := range maps {
149-
if util.IsPathEqual(existingPath, normalizedPath) {
150-
normalizedPath = existingPath
151-
break
152-
}
153-
}
154-
155-
maps[normalizedPath] = append(maps[normalizedPath], [2]string{headerName, headerValue})
125+
results = append(results, entry)
156126
}
157127

158128
return
@@ -188,6 +158,16 @@ eachInput:
188158
return
189159
}
190160

161+
func normalizeHeaders(inputs []string) []string {
162+
if len(inputs) != 2 {
163+
return nil
164+
}
165+
if len(inputs[0]) == 0 || len(inputs[1]) == 0 {
166+
return nil
167+
}
168+
return inputs
169+
}
170+
191171
func normalizeUrlPaths(inputs []string) []string {
192172
outputs := make([]string, 0, len(inputs))
193173

src/param/strUtil_test.go

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -73,27 +73,27 @@ func TestSplitKeyValue(t *testing.T) {
7373
var k, v string
7474
var ok bool
7575

76-
_, _, k, v, ok = splitKeyValue("")
76+
k, v, ok = splitKeyValue("")
7777
if ok {
7878
t.Error("empty string should not OK")
7979
}
8080

81-
_, _, k, v, ok = splitKeyValue(":")
81+
k, v, ok = splitKeyValue(":")
8282
if ok {
8383
t.Error("separator-only string should not OK")
8484
}
8585

86-
_, _, k, v, ok = splitKeyValue("::world")
86+
k, v, ok = splitKeyValue("::world")
8787
if ok {
8888
t.Error("empty key should not OK")
8989
}
9090

91-
_, _, k, v, ok = splitKeyValue(":hello:")
91+
k, v, ok = splitKeyValue(":hello:")
9292
if ok {
9393
t.Error("empty value should not OK")
9494
}
9595

96-
_, _, k, v, ok = splitKeyValue(":key:value")
96+
k, v, ok = splitKeyValue(":key:value")
9797
if !ok {
9898
t.Fail()
9999
}
@@ -104,7 +104,7 @@ func TestSplitKeyValue(t *testing.T) {
104104
t.Fail()
105105
}
106106

107-
_, _, k, v, ok = splitKeyValue("@KEY@VALUE")
107+
k, v, ok = splitKeyValue("@KEY@VALUE")
108108
if !ok {
109109
t.Fail()
110110
}
@@ -130,11 +130,11 @@ func TestSplitAllKeyValue(t *testing.T) {
130130
}
131131

132132
func TestNormalizePathRestrictAccesses(t *testing.T) {
133-
results, _ := normalizePathRestrictAccesses([][]string{
133+
results, _ := normalizePathValues([][]string{
134134
{"/foo", "host1", "host2"},
135135
{"/foo/", "host3", "host4"},
136136
{"/bar"},
137-
}, util.NormalizeUrlPath)
137+
}, true, util.NormalizeUrlPath, util.ExtractHostsFromUrls)
138138

139139
if len(results) != 2 {
140140
t.Error()
@@ -148,37 +148,28 @@ func TestNormalizePathRestrictAccesses(t *testing.T) {
148148
}
149149

150150
func TestNormalizePathHeadersMap(t *testing.T) {
151-
var result map[string][][2]string
152-
153-
result, _ = normalizePathHeadersMap([]string{
154-
":/foo:X-header1:X-Value1",
155-
":/foo/:X-header2:X-Value2",
156-
":/bar:X-header3:X-Value3",
157-
":baz",
158-
":baz:",
159-
":baz:X-Not-Valid",
160-
":baz:X-Not-Valid:",
161-
}, util.NormalizeUrlPath)
151+
var result [][]string
152+
153+
result, _ = normalizePathValues([][]string{
154+
{"/foo", "X-header1", "X-Value1"},
155+
{"/foo/", "X-header2", "X-Value2"},
156+
{"/bar", "X-header3", "X-Value3"},
157+
{"baz"},
158+
{"baz", ""},
159+
{"baz", "X-Not-Valid"},
160+
{"baz", "X-Not-Valid", ""},
161+
}, false, util.NormalizeUrlPath, normalizeHeaders)
162162

163163
if len(result) != 2 {
164164
t.Error(result)
165165
}
166166

167-
if len(result["/foo"]) != 2 {
168-
t.Error(result["/foo"])
169-
}
170-
if result["/foo"][0][0] != "X-header1" || result["/foo"][0][1] != "X-Value1" {
171-
t.Error(result["/foo"][0])
172-
}
173-
if result["/foo"][1][0] != "X-header2" || result["/foo"][1][1] != "X-Value2" {
174-
t.Error(result["/foo"][0])
167+
if !expectStrings(result[0], "/foo", "X-header1", "X-Value1", "X-header2", "X-Value2") {
168+
t.Error(result[0])
175169
}
176170

177-
if len(result["/bar"]) != 1 {
178-
t.Error(result["/foo"])
179-
}
180-
if result["/bar"][0][0] != "X-header3" || result["/bar"][0][1] != "X-Value3" {
181-
t.Error(result["/foo"][0])
171+
if !expectStrings(result[1], "/bar", "X-header3", "X-Value3") {
172+
t.Error(result[1])
182173
}
183174
}
184175

src/serverHandler/header.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,25 @@ type pathHeaders struct {
1010
headers [][2]string
1111
}
1212

13-
func newPathHeaders(pathHeadersMap map[string][][2]string) []pathHeaders {
14-
results := make([]pathHeaders, 0, len(pathHeadersMap))
13+
func newPathHeaders(pathHeadersList [][]string) []pathHeaders {
14+
results := make([]pathHeaders, 0, len(pathHeadersList))
15+
16+
for _, pathHeadersSeq := range pathHeadersList {
17+
if len(pathHeadersSeq) <= 1 { // no headers
18+
continue
19+
}
20+
refPath := pathHeadersSeq[0]
21+
22+
pathHeadersSeq = pathHeadersSeq[1:]
23+
headerPairCount := len(pathHeadersSeq) / 2
24+
if headerPairCount == 0 {
25+
continue
26+
}
27+
headers := make([][2]string, headerPairCount)
28+
for i := 0; i < headerPairCount; i++ {
29+
headers[i] = [2]string{pathHeadersSeq[i*2], pathHeadersSeq[i*2+1]}
30+
}
1531

16-
for refPath, headers := range pathHeadersMap {
1732
results = append(results, pathHeaders{refPath, headers})
1833
}
1934

0 commit comments

Comments
 (0)