-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: aarnautu <[email protected]>
- Loading branch information
aarnautu
committed
Mar 7, 2023
1 parent
ff45093
commit f9839d6
Showing
12 changed files
with
1,283 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package encoding | ||
|
||
import ( | ||
"compress/gzip" | ||
"fmt" | ||
|
||
"github.com/open-policy-agent/opa/util" | ||
) | ||
|
||
var defaultGzipMinLength = 1024 | ||
var defaultGzipCompressionLevel = gzip.BestCompression | ||
|
||
// Config represents the configuration for the Server.Encoding settings | ||
type Config struct { | ||
Gzip *Gzip `json:"gzip,omitempty"` | ||
} | ||
|
||
// Gzip represents the configuration for the Server.Encoding.Gzip settings | ||
type Gzip struct { | ||
MinLength *int `json:"min_length,omitempty"` // the minimum length of a response that will be gzipped | ||
CompressionLevel *int `json:"compression_level,omitempty"` // the compression level for gzip | ||
} | ||
|
||
// ConfigBuilder assists in the construction of the plugin configuration. | ||
type ConfigBuilder struct { | ||
raw []byte | ||
} | ||
|
||
// NewConfigBuilder returns a new ConfigBuilder to build and parse the server config | ||
func NewConfigBuilder() *ConfigBuilder { | ||
return &ConfigBuilder{} | ||
} | ||
|
||
// WithBytes sets the raw server config | ||
func (b *ConfigBuilder) WithBytes(config []byte) *ConfigBuilder { | ||
b.raw = config | ||
return b | ||
} | ||
|
||
// Parse returns a valid Config object with defaults injected. | ||
func (b *ConfigBuilder) Parse() (*Config, error) { | ||
if b.raw == nil { | ||
defaultConfig := &Config{ | ||
Gzip: &Gzip{ | ||
MinLength: &defaultGzipMinLength, | ||
CompressionLevel: &defaultGzipCompressionLevel, | ||
}, | ||
} | ||
return defaultConfig, nil | ||
} | ||
|
||
var result Config | ||
|
||
if err := util.Unmarshal(b.raw, &result); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &result, result.validateAndInjectDefaults() | ||
} | ||
|
||
func (c *Config) validateAndInjectDefaults() error { | ||
if c.Gzip == nil { | ||
c.Gzip = &Gzip{ | ||
MinLength: &defaultGzipMinLength, | ||
CompressionLevel: &defaultGzipCompressionLevel, | ||
} | ||
} | ||
if c.Gzip.MinLength == nil { | ||
c.Gzip.MinLength = &defaultGzipMinLength | ||
} | ||
|
||
if c.Gzip.CompressionLevel == nil { | ||
c.Gzip.CompressionLevel = &defaultGzipCompressionLevel | ||
} | ||
|
||
if *c.Gzip.MinLength <= 0 { | ||
return fmt.Errorf("invalid value for server.encoding.gzip.min_length field, should be a positive number") | ||
} | ||
|
||
acceptedCompressionLevels := map[int]bool{ | ||
gzip.NoCompression: true, | ||
gzip.BestSpeed: true, | ||
gzip.BestCompression: true, | ||
} | ||
_, compressionLevelAccepted := acceptedCompressionLevels[*c.Gzip.CompressionLevel] | ||
if !compressionLevelAccepted { | ||
return fmt.Errorf("invalid value for server.encoding.gzip.compression_level field, accepted values are 0, 1 or 9") | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package encoding | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
) | ||
|
||
func TestConfigValidation(t *testing.T) { | ||
tests := []struct { | ||
input string | ||
wantErr bool | ||
}{ | ||
{ | ||
input: `{}`, | ||
wantErr: false, | ||
}, | ||
{ | ||
input: `{"gzip": {"min_length": "not-a-number"}}`, | ||
wantErr: true, | ||
}, | ||
{ | ||
input: `{"gzip": {min_length": 42}}`, | ||
wantErr: false, | ||
}, | ||
{ | ||
input: `{"gzip":{"min_length": "42"}}`, | ||
wantErr: true, | ||
}, | ||
{ | ||
input: `{"gzip":{"min_length": 0}}`, | ||
wantErr: true, | ||
}, | ||
{ | ||
input: `{"gzip":{"min_length": -10}}`, | ||
wantErr: true, | ||
}, | ||
{ | ||
input: `{"gzip":{"random_key": 0}}`, | ||
wantErr: false, | ||
}, | ||
{ | ||
input: `{"gzip": {"min_length": -10, "compression_level": 13}}`, | ||
wantErr: true, | ||
}, | ||
{ | ||
input: `{"gzip":{"compression_level": "not-an-number"}}`, | ||
wantErr: true, | ||
}, | ||
{ | ||
input: `{"gzip":{"compression_level": 1}}`, | ||
wantErr: false, | ||
}, | ||
{ | ||
input: `{"gzip":{"compression_level": 13}}`, | ||
wantErr: true, | ||
}, | ||
{ | ||
input: `{"gzip":{"min_length": 42, "compression_level": 9}}`, | ||
wantErr: false, | ||
}, | ||
} | ||
|
||
for i, test := range tests { | ||
t.Run(fmt.Sprintf("TestConfigValidation_case_%d", i), func(t *testing.T) { | ||
_, err := NewConfigBuilder().WithBytes([]byte(test.input)).Parse() | ||
if err != nil && !test.wantErr { | ||
t.Fail() | ||
} | ||
if err == nil && test.wantErr { | ||
t.Fail() | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestConfigValue(t *testing.T) { | ||
tests := []struct { | ||
input string | ||
minLengthExpectedValue int | ||
compressionLevelExpectedValue int | ||
}{ | ||
{ | ||
input: `{}`, | ||
minLengthExpectedValue: 1024, | ||
compressionLevelExpectedValue: 9, | ||
}, | ||
{ | ||
input: `{"gzip":{"min_length": 42, "compression_level": 1}}`, | ||
minLengthExpectedValue: 42, | ||
compressionLevelExpectedValue: 1, | ||
}, | ||
} | ||
|
||
for i, test := range tests { | ||
t.Run(fmt.Sprintf("TestConfigValue_case_%d", i), func(t *testing.T) { | ||
config, err := NewConfigBuilder().WithBytes([]byte(test.input)).Parse() | ||
if err != nil { | ||
t.Fail() | ||
} | ||
if *config.Gzip.MinLength != test.minLengthExpectedValue || *config.Gzip.CompressionLevel != test.compressionLevelExpectedValue { | ||
t.Fail() | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.