Skip to content

Commit 4da62d9

Browse files
committed
chore: upgrade goVirtualHost
1 parent 30d333a commit 4da62d9

File tree

6 files changed

+204
-41
lines changed

6 files changed

+204
-41
lines changed

src/app/main.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,18 @@ func NewApp(params param.Params, setting *setting.Setting) (*App, []error) {
103103
}
104104
}
105105

106-
errs = vhSvc.Add(&goVirtualHost.HostInfo{
106+
var warns []error
107+
errs, warns = vhSvc.Add(&goVirtualHost.HostInfo{
107108
Listens: listens,
108109
ListensPlain: p.ListensPlain,
109110
ListensTLS: p.ListensTLS,
110111
Certs: p.Certificates,
111112
HostNames: p.HostNames,
112113
Handler: vhHandler,
113114
})
115+
if len(warns) > 0 {
116+
logger.LogErrors(warns...)
117+
}
114118
if len(errs) > 0 {
115119
logger.LogErrors(errs...)
116120
return nil, errs

src/goVirtualHost/param.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,31 @@ func (param *param) hasHostNames(checkHostNames []string) bool {
1212
return false
1313
}
1414

15-
for _, ownHostName := range param.hostNames {
16-
for _, checkHostName := range checkHostNames {
17-
if ownHostName == checkHostName {
18-
return true
19-
}
15+
for _, checkHostName := range checkHostNames {
16+
if contains(param.hostNames, checkHostName) {
17+
return true
2018
}
2119
}
20+
2221
return false
2322
}
2423

24+
func (param *param) hasHostName(checkHostName string) bool {
25+
if len(param.hostNames) == 0 || len(checkHostName) == 0 {
26+
return false
27+
}
28+
29+
if contains(param.hostNames, checkHostName) {
30+
return true
31+
}
32+
33+
return false
34+
}
35+
36+
func (param *param) stacksEqual(other *param) bool {
37+
return param.proto == other.proto && param.ip == other.ip && param.port == other.port
38+
}
39+
2540
func (param *param) validate() (errs []error) {
2641
if param.useTLS && len(param.certs) == 0 {
2742
err := wrapError(CertificateNotFound, fmt.Sprintf("certificate not found for TLS listens: %+v", param))

src/goVirtualHost/params.go

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,38 +32,66 @@ func (params params) validateParam(param *param) (errs []error) {
3232
}
3333
}
3434

35-
if ownParam.proto == param.proto && ownParam.ip == param.ip && ownParam.port == param.port {
35+
if ownParam.stacksEqual(param) {
3636
if ownParam.useTLS != param.useTLS {
3737
err := wrapError(ConflictTLSMode, fmt.Sprintf("cannot serve for both Plain and TLS mode: %+v, %+v", ownParam, param))
3838
errs = append(errs, err)
3939
}
40+
}
41+
}
4042

41-
if (len(param.hostNames) == 0 && len(ownParam.hostNames) == 0) || (ownParam.hasHostNames(param.hostNames)) {
42-
err := wrapError(DuplicatedAddressHostname, fmt.Sprintf("duplicated address and hostname: %+v, %+v", ownParam, param))
43-
errs = append(errs, err)
43+
return
44+
}
45+
46+
func (params params) validateShadows(param *param) (errs []error) {
47+
if len(params) == 0 {
48+
return nil
49+
}
50+
51+
if len(param.hostNames) == 0 {
52+
shadowed := false
53+
for _, ownParam := range params {
54+
if ownParam.stacksEqual(param) && len(ownParam.hostNames) == 0 {
55+
shadowed = true
56+
break
57+
}
58+
}
59+
if !shadowed {
60+
return nil
61+
}
62+
} else {
63+
for _, hostName := range param.hostNames {
64+
shadowed := false
65+
for _, ownParam := range params {
66+
if ownParam.stacksEqual(param) && ownParam.hasHostName(hostName) {
67+
shadowed = true
68+
break
69+
}
70+
}
71+
if !shadowed {
72+
return nil
4473
}
4574
}
4675
}
4776

77+
err := wrapError(DuplicatedAddressHostname, fmt.Sprintf("duplicated address and hostname: %+v", param))
78+
errs = append(errs, err)
4879
return
4980
}
5081

51-
func (params params) validate(inputs params) (errs []error) {
82+
func (params params) validate(inputs params) (errs, warns []error) {
5283
for _, p := range inputs {
5384
es := p.validate()
54-
if len(es) > 0 {
55-
errs = append(errs, es...)
56-
}
85+
errs = append(errs, es...)
5786

5887
es = inputs.validateParam(p)
59-
if len(es) > 0 {
60-
errs = append(errs, es...)
61-
}
88+
errs = append(errs, es...)
6289

6390
es = params.validateParam(p)
64-
if len(es) > 0 {
65-
errs = append(errs, es...)
66-
}
91+
errs = append(errs, es...)
92+
93+
ws := params.validateShadows(p)
94+
warns = append(warns, ws...)
6795
}
6896

6997
return

src/goVirtualHost/params_test.go

Lines changed: 114 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,6 @@ func TestParamsValidateParam(t *testing.T) {
6262
t.Error()
6363
}
6464

65-
// duplicated address and hostname
66-
p = &param{
67-
proto: "tcp",
68-
ip: "",
69-
port: ":80",
70-
hostNames: []string{"localhost"},
71-
}
72-
errs = ps.validateParam(p)
73-
if len(errs) == 0 {
74-
t.Error()
75-
} else if !errors.Is(errs[0], DuplicatedAddressHostname) {
76-
t.Error()
77-
}
78-
7965
// cannot serve for both Plain and TLS mode
8066
p = &param{
8167
proto: "tcp",
@@ -91,3 +77,117 @@ func TestParamsValidateParam(t *testing.T) {
9177
t.Error()
9278
}
9379
}
80+
81+
func TestParamsValidateShadow(t *testing.T) {
82+
var p *param
83+
var ps params
84+
var warns []error
85+
86+
// empty params
87+
88+
p = &param{
89+
proto: "tcp",
90+
ip: "",
91+
port: ":80",
92+
}
93+
warns = ps.validateShadows(p)
94+
if len(warns) != 0 {
95+
t.Error(warns)
96+
}
97+
98+
p = &param{
99+
proto: "tcp",
100+
ip: "",
101+
port: ":80",
102+
hostNames: []string{"www.example.com"},
103+
}
104+
warns = ps.validateShadows(p)
105+
if len(warns) != 0 {
106+
t.Error(warns)
107+
}
108+
109+
// params with no hostname
110+
111+
ps = params{&param{
112+
proto: "tcp",
113+
ip: "",
114+
port: ":80",
115+
}}
116+
117+
p = &param{
118+
proto: "tcp",
119+
ip: "",
120+
port: ":80",
121+
}
122+
warns = ps.validateShadows(p)
123+
if len(warns) == 0 {
124+
t.Error()
125+
} else if !errors.Is(warns[0], DuplicatedAddressHostname) {
126+
t.Error()
127+
}
128+
129+
p = &param{
130+
proto: "tcp",
131+
ip: "",
132+
port: ":80",
133+
hostNames: []string{"www.example.com"},
134+
}
135+
warns = ps.validateShadows(p)
136+
if len(warns) != 0 {
137+
t.Error(warns)
138+
}
139+
140+
// params with hostname
141+
142+
ps = params{&param{
143+
proto: "tcp",
144+
ip: "",
145+
port: ":80",
146+
hostNames: []string{"www.example.com"},
147+
}}
148+
149+
p = &param{
150+
proto: "tcp",
151+
ip: "",
152+
port: ":80",
153+
}
154+
warns = ps.validateShadows(p)
155+
if len(warns) != 0 {
156+
t.Error(warns)
157+
}
158+
159+
p = &param{
160+
proto: "tcp",
161+
ip: "",
162+
port: ":80",
163+
hostNames: []string{"www.foobar.com"},
164+
}
165+
warns = ps.validateShadows(p)
166+
if len(warns) != 0 {
167+
t.Error(warns)
168+
}
169+
170+
p = &param{
171+
proto: "tcp",
172+
ip: "",
173+
port: ":80",
174+
hostNames: []string{"www.example.com"},
175+
}
176+
warns = ps.validateShadows(p)
177+
if len(warns) == 0 {
178+
t.Error()
179+
} else if !errors.Is(warns[0], DuplicatedAddressHostname) {
180+
t.Error()
181+
}
182+
183+
p = &param{
184+
proto: "tcp",
185+
ip: "",
186+
port: ":80",
187+
hostNames: []string{"www.example.com", "www.foobar.com"},
188+
}
189+
warns = ps.validateShadows(p)
190+
if len(warns) != 0 {
191+
t.Error(warns)
192+
}
193+
}

src/goVirtualHost/service.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func (svc *Service) addVhostToServers(vhost *vhost, params params) {
4242
}
4343
}
4444

45-
func (svc *Service) Add(info *HostInfo) (errs []error) {
45+
func (svc *Service) Add(info *HostInfo) (errs, warns []error) {
4646
svc.mu.Lock()
4747
defer svc.mu.Unlock()
4848

@@ -53,7 +53,7 @@ func (svc *Service) Add(info *HostInfo) (errs []error) {
5353

5454
hostNames, vhostParams, certs := info.parse()
5555

56-
errs = svc.params.validate(vhostParams)
56+
errs, warns = svc.params.validate(vhostParams)
5757
if len(errs) > 0 {
5858
return
5959
}
@@ -179,7 +179,7 @@ func (svc *Service) Close() {
179179
func (svc *Service) GetAccessibleURLs(includeLoopback bool) [][]string {
180180
gotIPList := false
181181
var ipv46s, ipv4s, ipv6s []string
182-
182+
var allHostNameUrls []string
183183
vhUrls := make(map[*vhost][]string)
184184

185185
for _, listener := range svc.listeners {
@@ -205,7 +205,10 @@ func (svc *Service) GetAccessibleURLs(includeLoopback bool) [][]string {
205205
url = httpUrl
206206
}
207207
url = url + hostname + port
208-
vhUrls[vh] = append(vhUrls[vh], url)
208+
if !contains(allHostNameUrls, url) {
209+
allHostNameUrls = append(allHostNameUrls, url)
210+
vhUrls[vh] = append(vhUrls[vh], url)
211+
}
209212
}
210213
if vh == defaultVh {
211214
var url string

src/goVirtualHost/util.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,14 @@ func normalizeHostNames(inputs []string) []string {
4040
output := make([]string, 0, len(inputs))
4141

4242
for _, str := range inputs {
43-
if len(str) > 0 {
44-
name := strings.ToLower(str)
45-
output = append(output, name)
43+
if len(str) == 0 {
44+
continue
45+
}
46+
name := strings.ToLower(strings.TrimSpace(str))
47+
if len(name) == 0 {
48+
continue
4649
}
50+
output = append(output, name)
4751
}
4852

4953
return output
@@ -214,3 +218,12 @@ func getAllIfaceIPs(includeLoopback bool) (all, allv4, allv6 []string) {
214218
allv6 = allAddrsV6.String()
215219
return
216220
}
221+
222+
func contains(list []string, item string) bool {
223+
for i, length := 0, len(list); i < length; i++ {
224+
if list[i] == item {
225+
return true
226+
}
227+
}
228+
return false
229+
}

0 commit comments

Comments
 (0)