Skip to content

Commit 5774737

Browse files
committed
Handle default and concrete server match conflict #192
- Drop default server match if a concrete server match is found - Add test case to validate behavior
1 parent 084e167 commit 5774737

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

app/discovery/discovery.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,16 @@ func (s *Service) Match(srv, src string) (res Matches) {
214214
}
215215
}
216216

217+
// if match returns both default and concrete server(s), drop default as we have a better match with concrete
218+
if len(res.Routes) > 1 {
219+
for i := range res.Routes {
220+
if res.Routes[i].Mapper.Server == "*" || res.Routes[i].Mapper.Server == "" {
221+
res.Routes = append(res.Routes[:i], res.Routes[i+1:]...)
222+
break
223+
}
224+
}
225+
}
226+
217227
return res
218228
}
219229

app/discovery/discovery_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,73 @@ func TestService_MatchConflictRegex(t *testing.T) {
370370
}
371371
}
372372

373+
// https://github.com/umputun/reproxy/issues/192
374+
func TestService_Match192(t *testing.T) {
375+
p1 := &ProviderMock{
376+
EventsFunc: func(ctx context.Context) <-chan ProviderID {
377+
res := make(chan ProviderID, 1)
378+
res <- PIFile
379+
return res
380+
},
381+
ListFunc: func() ([]URLMapper, error) {
382+
return []URLMapper{
383+
{
384+
Server: "*",
385+
SrcMatch: *regexp.MustCompile("^/(.*)"),
386+
Dst: "@temp https://site1.ru/",
387+
ProviderID: PIFile,
388+
},
389+
{
390+
Server: "example1.ru",
391+
SrcMatch: *regexp.MustCompile("^/(.*)"),
392+
Dst: "@temp https://site2.ru/",
393+
ProviderID: PIFile,
394+
},
395+
{
396+
Server: "example2.ru",
397+
SrcMatch: *regexp.MustCompile("^/(.*)"),
398+
Dst: "@temp https://site2.ru/",
399+
ProviderID: PIFile,
400+
},
401+
}, nil
402+
},
403+
}
404+
405+
svc := NewService([]Provider{p1}, time.Millisecond*100)
406+
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
407+
defer cancel()
408+
409+
err := svc.Run(ctx)
410+
require.Error(t, err)
411+
assert.Equal(t, context.DeadlineExceeded, err)
412+
assert.Equal(t, 3, len(svc.Mappers()))
413+
414+
tbl := []struct {
415+
server, src string
416+
res Matches
417+
}{
418+
{"example2.ru", "/something", Matches{MTProxy, []MatchedRoute{
419+
{Destination: "https://site2.ru/", Alive: true}}}},
420+
{"example1.ru", "/something", Matches{MTProxy, []MatchedRoute{
421+
{Destination: "https://site2.ru/", Alive: true}}}},
422+
{"example123.ru", "/something", Matches{MTProxy, []MatchedRoute{
423+
{Destination: "https://site1.ru/", Alive: true}}}},
424+
}
425+
426+
for i, tt := range tbl {
427+
tt := tt
428+
t.Run(strconv.Itoa(i), func(t *testing.T) {
429+
res := svc.Match(tt.server, tt.src)
430+
require.Equal(t, len(tt.res.Routes), len(res.Routes), res.Routes)
431+
for i := 0; i < len(res.Routes); i++ {
432+
assert.Equal(t, tt.res.Routes[i].Alive, res.Routes[i].Alive)
433+
assert.Equal(t, tt.res.Routes[i].Destination, res.Routes[i].Destination)
434+
}
435+
assert.Equal(t, tt.res.MatchType, res.MatchType)
436+
})
437+
}
438+
}
439+
373440
func TestService_Servers(t *testing.T) {
374441
p1 := &ProviderMock{
375442
EventsFunc: func(ctx context.Context) <-chan ProviderID {

0 commit comments

Comments
 (0)