Skip to content

Commit 72502e5

Browse files
committed
don't reverse host pattern while parsing
1 parent 3de4875 commit 72502e5

File tree

2 files changed

+23
-27
lines changed

2 files changed

+23
-27
lines changed

rules/rules.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -337,11 +337,8 @@ func parseAllowRule(ruleStr string) (Rule, error) {
337337
return Rule{}, fmt.Errorf("failed to parse domain: %v", err)
338338
}
339339

340-
// Convert labels to strings in reverse order (TLD first)
341-
rule.HostPattern = make([]labelPattern, len(hostLabels))
342-
for i, label := range hostLabels {
343-
rule.HostPattern[len(hostLabels)-1-i] = label
344-
}
340+
// Convert labels to strings
341+
rule.HostPattern = append(rule.HostPattern, hostLabels...)
345342
rest = remaining
346343

347344
case "path":
@@ -351,8 +348,7 @@ func parseAllowRule(ruleStr string) (Rule, error) {
351348
}
352349

353350
// Convert segments to strings
354-
rule.PathPattern = make([]segmentPattern, len(segments))
355-
copy(rule.PathPattern, segments)
351+
rule.PathPattern = append(rule.PathPattern, segments...)
356352
rest = remaining
357353

358354
default:
@@ -444,9 +440,9 @@ func (re *Engine) matches(r Rule, method, url string) bool {
444440

445441
if r.HostPattern != nil {
446442
// For a host pattern to match, every label has to match or be an `*`.
447-
// Subdomains also match automatically, meaning if the pattern is "wobble.com"
448-
// and the real is "wibble.wobble.com", it should match. We check this by comparing
449-
// from the end since patterns are stored in reverse order (TLD first).
443+
// Subdomains also match automatically, meaning if the pattern is "example.com"
444+
// and the real is "api.example.com", it should match. We check this by comparing
445+
// from the end of the actual hostname with the pattern (which is in normal order).
450446

451447
labels := strings.Split(parsedUrl.Hostname(), ".")
452448

@@ -455,9 +451,9 @@ func (re *Engine) matches(r Rule, method, url string) bool {
455451
return false
456452
}
457453

458-
// Compare from the end of both arrays since pattern is stored in reverse order
454+
// Compare pattern with the end of labels (allowing subdomains)
459455
for i, lp := range r.HostPattern {
460-
labelIndex := len(labels) - 1 - i
456+
labelIndex := len(labels) - len(r.HostPattern) + i
461457
if string(lp) != labels[labelIndex] && lp != "*" {
462458
return false
463459
}

rules/rules_test.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,7 @@ func TestParseAllowRule(t *testing.T) {
898898
input: "domain=google.com",
899899
expectedRule: Rule{
900900
Raw: "domain=google.com",
901-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("google")},
901+
HostPattern: []labelPattern{labelPattern("google"), labelPattern("com")},
902902
},
903903
expectError: false,
904904
},
@@ -917,7 +917,7 @@ func TestParseAllowRule(t *testing.T) {
917917
expectedRule: Rule{
918918
Raw: "method=POST domain=api.example.com",
919919
MethodPatterns: map[methodPattern]struct{}{methodPattern("POST"): {}},
920-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("example"), labelPattern("api")},
920+
HostPattern: []labelPattern{labelPattern("api"), labelPattern("example"), labelPattern("com")},
921921
},
922922
expectError: false,
923923
},
@@ -927,7 +927,7 @@ func TestParseAllowRule(t *testing.T) {
927927
expectedRule: Rule{
928928
Raw: "method=DELETE domain=test.com path=/resources/456",
929929
MethodPatterns: map[methodPattern]struct{}{methodPattern("DELETE"): {}},
930-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("test")},
930+
HostPattern: []labelPattern{labelPattern("test"), labelPattern("com")},
931931
PathPattern: []segmentPattern{segmentPattern("resources"), segmentPattern("456")},
932932
},
933933
expectError: false,
@@ -937,7 +937,7 @@ func TestParseAllowRule(t *testing.T) {
937937
input: "domain=*.example.com",
938938
expectedRule: Rule{
939939
Raw: "domain=*.example.com",
940-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("example"), labelPattern("*")},
940+
HostPattern: []labelPattern{labelPattern("*"), labelPattern("example"), labelPattern("com")},
941941
},
942942
expectError: false,
943943
},
@@ -1104,7 +1104,7 @@ func TestEngineMatches(t *testing.T) {
11041104
{
11051105
name: "no method pattern allows all methods",
11061106
rule: Rule{
1107-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("example")},
1107+
HostPattern: []labelPattern{labelPattern("example"), labelPattern("com")},
11081108
},
11091109
method: "DELETE",
11101110
url: "https://example.com/api",
@@ -1115,7 +1115,7 @@ func TestEngineMatches(t *testing.T) {
11151115
{
11161116
name: "host matches exact",
11171117
rule: Rule{
1118-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("example")},
1118+
HostPattern: []labelPattern{labelPattern("example"), labelPattern("com")},
11191119
},
11201120
method: "GET",
11211121
url: "https://example.com/api",
@@ -1124,7 +1124,7 @@ func TestEngineMatches(t *testing.T) {
11241124
{
11251125
name: "host does not match",
11261126
rule: Rule{
1127-
HostPattern: []labelPattern{labelPattern("org"), labelPattern("example")},
1127+
HostPattern: []labelPattern{labelPattern("example"), labelPattern("org")},
11281128
},
11291129
method: "GET",
11301130
url: "https://example.com/api",
@@ -1133,7 +1133,7 @@ func TestEngineMatches(t *testing.T) {
11331133
{
11341134
name: "subdomain matches",
11351135
rule: Rule{
1136-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("example")},
1136+
HostPattern: []labelPattern{labelPattern("example"), labelPattern("com")},
11371137
},
11381138
method: "GET",
11391139
url: "https://api.example.com/users",
@@ -1142,7 +1142,7 @@ func TestEngineMatches(t *testing.T) {
11421142
{
11431143
name: "host pattern too long",
11441144
rule: Rule{
1145-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("example"), labelPattern("api"), labelPattern("v1")},
1145+
HostPattern: []labelPattern{labelPattern("v1"), labelPattern("api"), labelPattern("example"), labelPattern("com")},
11461146
},
11471147
method: "GET",
11481148
url: "https://api.example.com/users",
@@ -1151,7 +1151,7 @@ func TestEngineMatches(t *testing.T) {
11511151
{
11521152
name: "host wildcard matches",
11531153
rule: Rule{
1154-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("*")},
1154+
HostPattern: []labelPattern{labelPattern("*"), labelPattern("com")},
11551155
},
11561156
method: "GET",
11571157
url: "https://test.com/api",
@@ -1228,7 +1228,7 @@ func TestEngineMatches(t *testing.T) {
12281228
name: "all patterns match",
12291229
rule: Rule{
12301230
MethodPatterns: map[methodPattern]struct{}{methodPattern("POST"): {}},
1231-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("api")},
1231+
HostPattern: []labelPattern{labelPattern("api"), labelPattern("com")},
12321232
PathPattern: []segmentPattern{segmentPattern(""), segmentPattern("users")},
12331233
},
12341234
method: "POST",
@@ -1239,7 +1239,7 @@ func TestEngineMatches(t *testing.T) {
12391239
name: "method fails combined test",
12401240
rule: Rule{
12411241
MethodPatterns: map[methodPattern]struct{}{methodPattern("POST"): {}},
1242-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("api")},
1242+
HostPattern: []labelPattern{labelPattern("api"), labelPattern("com")},
12431243
PathPattern: []segmentPattern{segmentPattern(""), segmentPattern("users")},
12441244
},
12451245
method: "GET",
@@ -1250,7 +1250,7 @@ func TestEngineMatches(t *testing.T) {
12501250
name: "host fails combined test",
12511251
rule: Rule{
12521252
MethodPatterns: map[methodPattern]struct{}{methodPattern("POST"): {}},
1253-
HostPattern: []labelPattern{labelPattern("org"), labelPattern("api")},
1253+
HostPattern: []labelPattern{labelPattern("api"), labelPattern("org")},
12541254
PathPattern: []segmentPattern{segmentPattern(""), segmentPattern("users")},
12551255
},
12561256
method: "POST",
@@ -1261,7 +1261,7 @@ func TestEngineMatches(t *testing.T) {
12611261
name: "path fails combined test",
12621262
rule: Rule{
12631263
MethodPatterns: map[methodPattern]struct{}{methodPattern("POST"): {}},
1264-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("api")},
1264+
HostPattern: []labelPattern{labelPattern("api"), labelPattern("com")},
12651265
PathPattern: []segmentPattern{segmentPattern(""), segmentPattern("posts")},
12661266
},
12671267
method: "POST",
@@ -1291,7 +1291,7 @@ func TestEngineMatches(t *testing.T) {
12911291
{
12921292
name: "invalid URL",
12931293
rule: Rule{
1294-
HostPattern: []labelPattern{labelPattern("com"), labelPattern("example")},
1294+
HostPattern: []labelPattern{labelPattern("example"), labelPattern("com")},
12951295
},
12961296
method: "GET",
12971297
url: "not-a-valid-url",

0 commit comments

Comments
 (0)