Skip to content

Commit

Permalink
BUG/MEDIUM: support multiple force-persist statements in backends
Browse files Browse the repository at this point in the history
  • Loading branch information
George Vine committed May 10, 2024
1 parent 40048e2 commit 12464ee
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 26 deletions.
33 changes: 28 additions & 5 deletions configuration/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,12 +651,18 @@ func TestGetBackend(t *testing.T) {
t.Errorf("IgnorePersistList[1].CondTest is %s, expected 'local_dst'", *b.IgnorePersistList[1].CondTest)
}

if *b.ForcePersist.Cond != "unless" {
t.Errorf("ForcePersist Cond not if: %v", *b.ForcePersist.Cond)
}
if *b.ForcePersist.CondTest != "acl-name-2" {
t.Errorf("ForcePersist CondTest not acl-name-2: %v", *b.ForcePersist.CondTest)
if len(b.ForcePersistList) != 2 {
t.Errorf("ForcePersistList has %d items, expected 2", len(b.ForcePersistList))
} else if *b.ForcePersistList[0].Cond != "unless" {
t.Errorf("ForcePersistList[0].Cond is %s, expected 'unless'", *b.ForcePersistList[0].Cond)
} else if *b.ForcePersistList[0].CondTest != "acl-name-2" {
t.Errorf("ForcePersistList[0].CondTest is %s, expected 'acl-name-2'", *b.ForcePersistList[0].CondTest)
} else if *b.ForcePersistList[1].Cond != "if" {
t.Errorf("ForcePersistList[1].Cond is %s, expected 'if'", *b.ForcePersistList[1].Cond)
} else if *b.ForcePersistList[1].CondTest != "acl-name-3" {
t.Errorf("ForcePersistList[1].CondTest is %s, expected 'acl-name-3'", *b.ForcePersistList[1].CondTest)
}

if b.RetryOn != "504 505" {
t.Errorf("RetryOn CondTest not 504 505: %v", b.RetryOn)
}
Expand Down Expand Up @@ -939,6 +945,10 @@ func TestCreateEditDeleteBackend(t *testing.T) {
Enabled: misc.StringP("enabled"),
Header: "X-Client-Dst",
},
ForcePersistList: []*models.ForcePersist{
{Cond: misc.StringP("unless"), CondTest: misc.StringP("invalid_src")},
{Cond: misc.StringP("if"), CondTest: misc.StringP("auth_ok")},
},
IgnorePersistList: []*models.IgnorePersist{
{Cond: misc.StringP("if"), CondTest: misc.StringP("host_www")},
{Cond: misc.StringP("unless"), CondTest: misc.StringP("missing_cl")},
Expand Down Expand Up @@ -1260,6 +1270,19 @@ func compareBackends(x, y *models.Backend, t *testing.T) bool { //nolint:gocogni
x.HTTPConnectionMode = ""
}

if len(x.ForcePersistList) != len(y.ForcePersistList) {
return false
}
for i := range x.ForcePersistList {
if *x.ForcePersistList[i].Cond != *y.ForcePersistList[i].Cond {
return false
}
if *x.ForcePersistList[i].CondTest != *y.ForcePersistList[i].CondTest {
return false
}
}
x.ForcePersistList, y.ForcePersistList = nil, nil

if len(x.IgnorePersistList) != len(y.IgnorePersistList) {
return false
}
Expand Down
60 changes: 40 additions & 20 deletions configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,8 @@ func (s *SectionParser) checkSpecialFields(fieldName string) (match bool, data i
return true, s.defaultBind()
case "HTTPSendNameHeader":
return true, s.httpSendNameHeader()
case "ForcePersist":
return true, s.forcePersist()
case "ForcePersistList":
return true, s.forcePersistList()
case "IgnorePersistList":
return true, s.ignorePersistList()
case "Source":
Expand Down Expand Up @@ -1356,19 +1356,27 @@ func (s *SectionParser) httpSendNameHeader() interface{} {
return nil
}

func (s *SectionParser) forcePersist() interface{} {
if s.Section == parser.Backends {
data, err := s.get("force-persist", false)
if err != nil {
return nil
}
d := data.(*types.ForcePersist)
return &models.BackendForcePersist{
Cond: &d.Cond,
CondTest: &d.CondTest,
func (s *SectionParser) forcePersistList() interface{} {
if s.Section != parser.Backends {
return nil
}
data, err := s.get("force-persist", false)
if err != nil {
return nil
}
d := data.([]types.ForcePersist)
if len(d) == 0 {
return nil
}

items := make([]*models.ForcePersist, len(d))
for i := range d {
items[i] = &models.ForcePersist{
Cond: &d[i].Cond,
CondTest: &d[i].CondTest,
}
}
return nil
return items
}

func (s *SectionParser) ignorePersistList() interface{} {
Expand Down Expand Up @@ -1625,8 +1633,15 @@ func (s *SectionObject) checkSpecialFields(fieldName string, field reflect.Value
return true, s.defaultBind(field)
case "HTTPSendNameHeader":
return true, s.httpSendNameHeader(field)
case "ForcePersistList":
return true, s.forcePersistList(field)
case "ForcePersist":
return true, s.forcePersist(field)
// "ForcePersist" field (force_persist) is deprecated in favour of "ForcePersistList" (force_persist_list).
// Backward compatibility during the sunset period is handled by callers of this library that perform payload
// transformation as necessary and remove the deprecated field.
// "ForcePersist" is explicitly caught and ignored here as a safeguard against a runtime panic that can occur
// if callers behave unexpectedly. It should be removed at the end of the sunset period along with the field.
return true, nil
case "IgnorePersistList":
return true, s.ignorePersistList(field)
case "IgnorePersist":
Expand Down Expand Up @@ -2880,18 +2895,23 @@ func (s *SectionObject) httpSendNameHeader(field reflect.Value) error {
return s.set("http-send-name-header", types.HTTPSendNameHeader{Name: v})
}

func (s *SectionObject) forcePersist(field reflect.Value) error {
func (s *SectionObject) forcePersistList(field reflect.Value) error {
if valueIsNil(field) {
return s.set("force-persist", nil)
}
opt, ok := field.Elem().Interface().(models.BackendForcePersist)
data, ok := field.Interface().([]*models.ForcePersist)
if !ok {
return misc.CreateTypeAssertError("force-persist")
}
return s.set("force-persist", types.ForcePersist{
Cond: *opt.Cond,
CondTest: *opt.CondTest,
})

items := make([]types.ForcePersist, len(data))
for i := range data {
items[i] = types.ForcePersist{
Cond: *data[i].Cond,
CondTest: *data[i].CondTest,
}
}
return s.set("force-persist", items)
}

func (s *SectionObject) ignorePersistList(field reflect.Value) error {
Expand Down
1 change: 1 addition & 0 deletions configuration/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ backend test
ignore-persist if acl-name
ignore-persist unless local_dst
force-persist unless acl-name-2
force-persist if acl-name-3
retry-on 504 505
http-send-name-header X-My-Awesome-Header
persist rdp-cookie(name)
Expand Down
167 changes: 166 additions & 1 deletion models/backend.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 12464ee

Please sign in to comment.