-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheader.go
132 lines (111 loc) · 2.26 KB
/
header.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package pgs
import (
"fmt"
"slices"
"strings"
)
type HeaderRule struct {
Path string
Headers []*HeaderLine
}
type HeaderLine struct {
Path string
Name string
Value string
}
var headerDenyList = []string{
"accept-ranges",
"age",
"allow",
"alt-svc",
"connection",
"content-encoding",
"content-length",
"content-range",
"date",
"location",
"server",
"trailer",
"transfer-encoding",
"upgrade",
}
// from https://github.com/netlify/build/tree/main/packages/headers-parser
func parseHeaderText(text string) ([]*HeaderRule, error) {
rules := []*HeaderRule{}
parsed := []*HeaderLine{}
lines := strings.Split(text, "\n")
for _, line := range lines {
parsedLine, err := parseLine(strings.TrimSpace(line))
if parsedLine == nil {
continue
}
if err != nil {
return rules, err
}
parsed = append(parsed, parsedLine)
}
var prevPath *HeaderRule
for _, rule := range parsed {
if rule.Path != "" {
if prevPath != nil {
if len(prevPath.Headers) > 0 {
rules = append(rules, prevPath)
}
}
prevPath = &HeaderRule{
Path: rule.Path,
}
} else if prevPath != nil {
// do not add headers in deny list
if slices.Contains(headerDenyList, rule.Name) {
continue
}
prevPath.Headers = append(
prevPath.Headers,
&HeaderLine{Name: rule.Name, Value: rule.Value},
)
}
}
// cleanup
if prevPath != nil && len(prevPath.Headers) > 0 {
rules = append(rules, prevPath)
}
return rules, nil
}
func parseLine(line string) (*HeaderLine, error) {
rule := &HeaderLine{}
if isPathLine(line) {
rule.Path = line
return rule, nil
}
if isEmpty(line) {
return nil, nil
}
if isComment(line) {
return nil, nil
}
if !strings.Contains(line, ":") {
return nil, nil
}
results := strings.SplitN(line, ":", 2)
name := strings.ToLower(strings.TrimSpace(results[0]))
value := strings.TrimSpace(results[1])
if name == "" {
return nil, fmt.Errorf("header name cannot be empty")
}
if value == "" {
return nil, fmt.Errorf("header value cannot be empty")
}
rule.Name = name
rule.Value = value
return rule, nil
}
func isComment(line string) bool {
return strings.HasPrefix(line, "#")
}
func isEmpty(line string) bool {
return line == ""
}
func isPathLine(line string) bool {
return strings.HasPrefix(line, "/")
}