diff --git a/configuration/backend_test.go b/configuration/backend_test.go index e21d50c2..026fee54 100644 --- a/configuration/backend_test.go +++ b/configuration/backend_test.go @@ -376,6 +376,36 @@ func TestGetBackend(t *testing.T) { if b.Compression.Direction != "both" { t.Errorf("%v: Compression.Direction not both: %v", b.Name, b.Compression.Direction) } + if b.Compression.AlgoReq != "raw-deflate" { + t.Errorf("%v: Compression.AlgoReq wrong: %v", b.Name, b.Compression.AlgoReq) + } + if len(b.Compression.AlgosRes) != 2 { + t.Errorf("%v: len Compression.AlgosRes not 2: %v", b.Name, len(b.Compression.AlgosRes)) + } else { + if !(b.Compression.AlgosRes[0] == "identity" || b.Compression.AlgosRes[0] == "raw-deflate") { + t.Errorf("%v: Compression.AlgosRes[0] wrong: %v", b.Name, b.Compression.AlgosRes[0]) + } + if !(b.Compression.AlgosRes[1] != "identity" || b.Compression.AlgosRes[0] == "raw-deflate") { + t.Errorf("%v: Compression.AlgosRes[1] wrong: %v", b.Name, b.Compression.AlgosRes[1]) + } + } + if len(b.Compression.TypesReq) != 2 { + t.Errorf("%v: len Compression.TypesReq not 2: %v", b.Name, len(b.Compression.TypesReq)) + } else { + if !(b.Compression.TypesReq[0] == "text/plain" || b.Compression.TypesReq[0] == "application/json") { + t.Errorf("%v: Compression.TypesReq[0] wrong: %v", b.Name, b.Compression.TypesReq[0]) + } + if !(b.Compression.TypesReq[1] != "text/plain" || b.Compression.TypesReq[0] == "application/json") { + t.Errorf("%v: Compression.TypesReq[1] wrong: %v", b.Name, b.Compression.TypesReq[1]) + } + } + if len(b.Compression.TypesRes) != 1 { + t.Errorf("%v: len Compression.TypesRes not 1: %v", b.Name, len(b.Compression.TypesRes)) + } else { + if !(b.Compression.TypesReq[0] == "text/plain") { + t.Errorf("%v: Compression.TypesReq[0] wrong: %v", b.Name, b.Compression.TypesReq[0]) + } + } } if b.Checkcache != "enabled" { t.Errorf("%v: Checkcache not enabled: %v", b.Name, b.Checkcache) diff --git a/configuration/configuration.go b/configuration/configuration.go index ad71b790..e6d9e603 100644 --- a/configuration/configuration.go +++ b/configuration/configuration.go @@ -1140,7 +1140,7 @@ func (s *SectionParser) monitorFail() interface{} { return nil } -func (s *SectionParser) compression() interface{} { +func (s *SectionParser) compression() interface{} { //nolint:gocognit compressionFound := false compression := &models.Compression{} @@ -1154,6 +1154,24 @@ func (s *SectionParser) compression() interface{} { } } + data, err = s.get("compression algo-req", false) + if err == nil { + d, ok := data.(*types.StringC) + if ok && d != nil { + compressionFound = true + compression.AlgoReq = d.Value + } + } + + data, err = s.get("compression algo-res", false) + if err == nil { + d, ok := data.(*types.StringSliceC) + if ok && d != nil && len(d.Value) > 0 { + compressionFound = true + compression.AlgosRes = d.Value + } + } + data, err = s.get("compression type", false) if err == nil { d, ok := data.(*types.StringSliceC) @@ -1163,6 +1181,24 @@ func (s *SectionParser) compression() interface{} { } } + data, err = s.get("compression type-req", false) + if err == nil { + d, ok := data.(*types.StringSliceC) + if ok && d != nil && len(d.Value) > 0 { + compressionFound = true + compression.TypesReq = d.Value + } + } + + data, err = s.get("compression type-res", false) + if err == nil { + d, ok := data.(*types.StringSliceC) + if ok && d != nil && len(d.Value) > 0 { + compressionFound = true + compression.TypesRes = d.Value + } + } + data, err = s.get("compression offload", false) if err == nil { d, ok := data.(*types.Enabled) @@ -2594,17 +2630,33 @@ func (s *SectionObject) statsOptions(field reflect.Value) error { return s.set("stats", ss) } -func (s *SectionObject) compression(field reflect.Value) error { +func (s *SectionObject) compression(field reflect.Value) error { //nolint:gocognit var err error if valueIsNil(field) { err = s.set("compression algo", nil) if err != nil { return err } + err = s.set("compression algo-req", nil) + if err != nil { + return err + } + err = s.set("compression algo-res", nil) + if err != nil { + return err + } err = s.set("compression type", nil) if err != nil { return err } + err = s.set("compression type-req", nil) + if err != nil { + return err + } + err = s.set("compression type-res", nil) + if err != nil { + return err + } err = s.set("compression offload", nil) if err != nil { return err @@ -2632,12 +2684,36 @@ func (s *SectionObject) compression(field reflect.Value) error { return err } } + if len(compression.AlgoReq) > 0 { + err = s.set("compression algo-req", &types.StringC{Value: compression.AlgoReq}) + if err != nil { + return err + } + } + if len(compression.AlgosRes) > 0 { + err = s.set("compression algo-res", &types.StringSliceC{Value: compression.AlgosRes}) + if err != nil { + return err + } + } if len(compression.Types) > 0 { err = s.set("compression type", &types.StringSliceC{Value: compression.Types}) if err != nil { return err } } + if len(compression.TypesReq) > 0 { + err = s.set("compression type-req", &types.StringSliceC{Value: compression.TypesReq}) + if err != nil { + return err + } + } + if len(compression.TypesRes) > 0 { + err = s.set("compression type-res", &types.StringSliceC{Value: compression.TypesRes}) + if err != nil { + return err + } + } if compression.Offload { err = s.set("compression offload", &types.Enabled{}) if err != nil { diff --git a/configuration/configuration_test.go b/configuration/configuration_test.go index 9f92560d..b851cb48 100644 --- a/configuration/configuration_test.go +++ b/configuration/configuration_test.go @@ -492,6 +492,10 @@ frontend test compression algo identity gzip compression type text/plain compression offload + compression algo-req raw-deflate + compression algo-res raw-deflate identity + compression type-req text/plain application/json + compression type-res text/plain clitcpka-cnt 10 clitcpka-idle 10s clitcpka-intvl 10 @@ -644,6 +648,10 @@ backend test no option h1-case-adjust-bogus-server compression type application/json text/plain compression direction both + compression algo-req raw-deflate + compression algo-res raw-deflate identity + compression type-req text/plain application/json + compression type-res text/plain srvtcpka-cnt 10 srvtcpka-idle 10s srvtcpka-intvl 10 diff --git a/configuration/frontend_test.go b/configuration/frontend_test.go index c3896dce..545326ae 100644 --- a/configuration/frontend_test.go +++ b/configuration/frontend_test.go @@ -318,6 +318,36 @@ func TestGetFrontend(t *testing.T) { if !f.Compression.Offload { t.Errorf("%v: Compression.Offload wrong: %v", f.Name, f.Compression.Offload) } + if f.Compression.AlgoReq != "raw-deflate" { + t.Errorf("%v: Compression.AlgoReq wrong: %v", f.Name, f.Compression.AlgoReq) + } + if len(f.Compression.AlgosRes) != 2 { + t.Errorf("%v: len Compression.AlgosRes not 2: %v", f.Name, len(f.Compression.AlgosRes)) + } else { + if !(f.Compression.AlgosRes[0] == "identity" || f.Compression.AlgosRes[0] == "raw-deflate") { + t.Errorf("%v: Compression.AlgosRes[0] wrong: %v", f.Name, f.Compression.AlgosRes[0]) + } + if !(f.Compression.AlgosRes[1] != "identity" || f.Compression.AlgosRes[0] == "raw-deflate") { + t.Errorf("%v: Compression.AlgosRes[1] wrong: %v", f.Name, f.Compression.AlgosRes[1]) + } + } + if len(f.Compression.TypesReq) != 2 { + t.Errorf("%v: len Compression.TypesReq not 2: %v", f.Name, len(f.Compression.TypesReq)) + } else { + if !(f.Compression.TypesReq[0] == "text/plain" || f.Compression.TypesReq[0] == "application/json") { + t.Errorf("%v: Compression.TypesReq[0] wrong: %v", f.Name, f.Compression.TypesReq[0]) + } + if !(f.Compression.TypesReq[1] != "text/plain" || f.Compression.TypesReq[0] == "application/json") { + t.Errorf("%v: Compression.TypesReq[1] wrong: %v", f.Name, f.Compression.TypesReq[1]) + } + } + if len(f.Compression.TypesRes) != 1 { + t.Errorf("%v: len Compression.TypesRes not 1: %v", f.Name, len(f.Compression.TypesRes)) + } else { + if !(f.Compression.TypesReq[0] == "text/plain") { + t.Errorf("%v: Compression.TypesReq[0] wrong: %v", f.Name, f.Compression.TypesReq[0]) + } + } } if f.HTTPIgnoreProbes != "enabled" { diff --git a/go.mod b/go.mod index e008256e..d782ce24 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/google/go-cmp v0.6.0 github.com/google/renameio v1.0.1 github.com/google/uuid v1.6.0 - github.com/haproxytech/config-parser/v5 v5.1.1-0.20240220100901-1145ec548975 + github.com/haproxytech/config-parser/v5 v5.1.1-0.20240221073837-5b782186def2 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/mitchellh/mapstructure v1.5.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 3dcbbf30..e4900e6c 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/google/renameio v1.0.1 h1:Lh/jXZmvZxb0BBeSY5VKEfidcbcbenKjZFzM/q0fSeU github.com/google/renameio v1.0.1/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/haproxytech/config-parser/v5 v5.1.1-0.20240220100901-1145ec548975 h1:CL/3SEvayajAyRHHOmKLsqiwZ8SVwAstCbKEvuxNknI= -github.com/haproxytech/config-parser/v5 v5.1.1-0.20240220100901-1145ec548975/go.mod h1:iy8nBB1eopwYbyeh3FQpjxZUxfcIDyTV9bW0F1t+cVA= +github.com/haproxytech/config-parser/v5 v5.1.1-0.20240221073837-5b782186def2 h1:YXI/15X8xJPrnyO8brmiNaFhOD17Ib9nszHRrlEtuIw= +github.com/haproxytech/config-parser/v5 v5.1.1-0.20240221073837-5b782186def2/go.mod h1:iy8nBB1eopwYbyeh3FQpjxZUxfcIDyTV9bW0F1t+cVA= github.com/haproxytech/go-logger v1.1.0 h1:HgGtYaI1ApkvbQdsm7f9AzQQoxTB7w37criTflh7IQE= github.com/haproxytech/go-logger v1.1.0/go.mod h1:OekUd8HCb7ubxMplzHUPBTHNxZmddOWfOjWclZsqIeM= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= diff --git a/models/compression.go b/models/compression.go index 895dbd41..3720cdd9 100644 --- a/models/compression.go +++ b/models/compression.go @@ -36,9 +36,16 @@ import ( // swagger:model compression type Compression struct { + // algo req + // Enum: [identity gzip deflate raw-deflate] + AlgoReq string `json:"algo-req,omitempty"` + // algorithms Algorithms []string `json:"algorithms,omitempty"` + // algos res + AlgosRes []string `json:"algos-res,omitempty"` + // direction // Enum: [request response both] Direction string `json:"direction,omitempty"` @@ -48,16 +55,30 @@ type Compression struct { // types Types []string `json:"types,omitempty"` + + // types req + TypesReq []string `json:"types-req,omitempty"` + + // types res + TypesRes []string `json:"types-res,omitempty"` } // Validate validates this compression func (m *Compression) Validate(formats strfmt.Registry) error { var res []error + if err := m.validateAlgoReq(formats); err != nil { + res = append(res, err) + } + if err := m.validateAlgorithms(formats); err != nil { res = append(res, err) } + if err := m.validateAlgosRes(formats); err != nil { + res = append(res, err) + } + if err := m.validateDirection(formats); err != nil { res = append(res, err) } @@ -68,6 +89,54 @@ func (m *Compression) Validate(formats strfmt.Registry) error { return nil } +var compressionTypeAlgoReqPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["identity","gzip","deflate","raw-deflate"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + compressionTypeAlgoReqPropEnum = append(compressionTypeAlgoReqPropEnum, v) + } +} + +const ( + + // CompressionAlgoReqIdentity captures enum value "identity" + CompressionAlgoReqIdentity string = "identity" + + // CompressionAlgoReqGzip captures enum value "gzip" + CompressionAlgoReqGzip string = "gzip" + + // CompressionAlgoReqDeflate captures enum value "deflate" + CompressionAlgoReqDeflate string = "deflate" + + // CompressionAlgoReqRawDashDeflate captures enum value "raw-deflate" + CompressionAlgoReqRawDashDeflate string = "raw-deflate" +) + +// prop value enum +func (m *Compression) validateAlgoReqEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, compressionTypeAlgoReqPropEnum, true); err != nil { + return err + } + return nil +} + +func (m *Compression) validateAlgoReq(formats strfmt.Registry) error { + if swag.IsZero(m.AlgoReq) { // not required + return nil + } + + // value enum + if err := m.validateAlgoReqEnum("algo-req", "body", m.AlgoReq); err != nil { + return err + } + + return nil +} + var compressionAlgorithmsItemsEnum []interface{} func init() { @@ -104,6 +173,42 @@ func (m *Compression) validateAlgorithms(formats strfmt.Registry) error { return nil } +var compressionAlgosResItemsEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["identity","gzip","deflate","raw-deflate"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + compressionAlgosResItemsEnum = append(compressionAlgosResItemsEnum, v) + } +} + +func (m *Compression) validateAlgosResItemsEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, compressionAlgosResItemsEnum, true); err != nil { + return err + } + return nil +} + +func (m *Compression) validateAlgosRes(formats strfmt.Registry) error { + if swag.IsZero(m.AlgosRes) { // not required + return nil + } + + for i := 0; i < len(m.AlgosRes); i++ { + + // value enum + if err := m.validateAlgosResItemsEnum("algos-res"+"."+strconv.Itoa(i), "body", m.AlgosRes[i]); err != nil { + return err + } + + } + + return nil +} + var compressionTypeDirectionPropEnum []interface{} func init() { diff --git a/specification/build/haproxy_spec.yaml b/specification/build/haproxy_spec.yaml index a0d58451..8cfdcd99 100644 --- a/specification/build/haproxy_spec.yaml +++ b/specification/build/haproxy_spec.yaml @@ -9626,6 +9626,14 @@ definitions: x-go-name: ReturnHeader compression: properties: + algo-req: + enum: + - identity + - gzip + - deflate + - raw-deflate + type: string + x-omitempty: true algorithms: items: enum: @@ -9636,6 +9644,16 @@ definitions: type: string type: array x-omitempty: true + algos-res: + items: + enum: + - identity + - gzip + - deflate + - raw-deflate + type: string + type: array + x-omitempty: true direction: enum: - request @@ -9650,6 +9668,16 @@ definitions: type: string type: array x-omitempty: true + types-req: + items: + type: string + type: array + x-omitempty: true + types-res: + items: + type: string + type: array + x-omitempty: true type: object source: properties: diff --git a/specification/models/configuration/misc.yaml b/specification/models/configuration/misc.yaml index b2144f33..ddd0374b 100644 --- a/specification/models/configuration/misc.yaml +++ b/specification/models/configuration/misc.yaml @@ -314,6 +314,26 @@ compression: type: string enum: [request, response, both] x-omitempty: true + types-req: + type: array + x-omitempty: true + items: + type: string + types-res: + type: array + x-omitempty: true + items: + type: string + algo-req: + type: string + x-omitempty: true + enum: [identity, gzip, deflate, raw-deflate] + algos-res: + type: array + x-omitempty: true + items: + type: string + enum: [identity, gzip, deflate, raw-deflate] stats_http_request: type: object required: