Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ type CacheConfig struct {
IgnorePaths []string
ShouldHashQuery bool
HashQueryIgnore map[string]bool
HashHeaders []string
}

type Config struct {
ServerConfig ServerConfig
CacheConfig CacheConfig
Expand All @@ -48,7 +50,7 @@ func New() Config {
serverConfig := ServerConfig{
Port: getEnv("SERVER_PORT", "8000"),
GracePeriod: getEnvAsInt("SHUTDOWN_GRACE_PERIOD", "30"),
LogLevel: getEnvAsLogLevel("SERVER_LOG_LEVEL"),
LogLevel: getEnvAsLogLevel("LOG_LEVEL"),
Storage: getEnv("SERVER_STORAGE", ""),
}

Expand All @@ -57,9 +59,10 @@ func New() Config {
DownstreamHost: getEnvAsURL("DOWNSTREAM_HOST", ""),
Size: getEnvAsFloat("CACHE_SIZE_MB", "10"),
IgnorePaths: getEnvAsSlice("CACHE_IGNORE_ENDPOINTS"),
StaleInSeconds: getEnvAsInt("CACHE_STALE_WHILE_REVALIDATE_SEC", "5"),
StaleInSeconds: getEnvAsInt("CACHE_STALE_WHILE_REVALIDATE_SEC", "60"),
ShouldHashQuery: getEnvAsBool("CACHE_SHOULD_HASH_QUERY", "true"),
HashQueryIgnore: hashQueryIgnoreMap(getEnvAsSlice("CACHE_HASH_QUERY_IGNORE")),
HashHeaders: getEnvAsSlice("CACHE_HASH_HEADERS"),
}

if strings.ToLower(serverConfig.Storage) == "memory" {
Expand Down
125 changes: 125 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
func TestConfig(t *testing.T) {
t.Run("inMemory config", func(t *testing.T) {
defer setupEnv(t, "SERVER_STORAGE", "memory")()
defer setupEnv(t, "CACHE_STRATEGY", "memory")()
defer setupEnv(t, "DOWNSTREAM_HOST", "http://localhost:8080")()
config := New()

assert.NotNil(t, config)
Expand All @@ -17,9 +19,132 @@ func TestConfig(t *testing.T) {
t.Run("redis config", func(t *testing.T) {
defer setupEnv(t, "SERVER_STORAGE", "redis")()
defer setupEnv(t, "REDIS_CONNECTION_STRING", "redis")()
defer setupEnv(t, "CACHE_STRATEGY", "redis")()
defer setupEnv(t, "DOWNSTREAM_HOST", "http://localhost:8080")()
config := New()

assert.NotNil(t, config)
assert.Equal(t, "redis", config.RedisConfig.ConnectionString)
})

t.Run("header configuration", func(t *testing.T) {
tests := []struct {
name string
hashHeaders string
hashHeadersIgnore string
wantHeaders []string
}{
{
name: "empty headers",
hashHeaders: "",
hashHeadersIgnore: "",
wantHeaders: []string{},
},
{
name: "single header",
hashHeaders: "Authorization",
hashHeadersIgnore: "",
wantHeaders: []string{"Authorization"},
},
{
name: "multiple headers",
hashHeaders: "Authorization,X-User-ID,Accept",
hashHeadersIgnore: "",
wantHeaders: []string{"Authorization", "X-User-ID", "Accept"},
},
{
name: "headers with ignore",
hashHeaders: "Authorization,X-User-ID,Accept",
hashHeadersIgnore: "X-User-ID",
wantHeaders: []string{"Authorization", "X-User-ID", "Accept"},
},
{
name: "case insensitive headers",
hashHeaders: "AUTHORIZATION,x-user-id,accept",
hashHeadersIgnore: "X-USER-ID",
wantHeaders: []string{"AUTHORIZATION", "x-user-id", "accept"},
},
{
name: "whitespace in headers",
hashHeaders: " Authorization , X-User-ID , Accept ",
hashHeadersIgnore: " X-User-ID ",
wantHeaders: []string{"Authorization", "X-User-ID", "Accept"},
},
{
name: "duplicate headers",
hashHeaders: "Authorization,Authorization,X-User-ID",
hashHeadersIgnore: "",
wantHeaders: []string{"Authorization", "Authorization", "X-User-ID"},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer setupEnv(t, "CACHE_HASH_HEADERS", tt.hashHeaders)()
defer setupEnv(t, "CACHE_HASH_HEADERS_IGNORE", tt.hashHeadersIgnore)()

config := New()

assert.Equal(t, tt.wantHeaders, config.CacheConfig.HashHeaders)
})
}
})

t.Run("query configuration", func(t *testing.T) {
tests := []struct {
name string
shouldHashQuery string
queryIgnore string
wantHashQuery bool
wantIgnore map[string]bool
}{
{
name: "default query hashing",
shouldHashQuery: "",
queryIgnore: "",
wantHashQuery: true,
wantIgnore: map[string]bool{},
},
{
name: "disabled query hashing",
shouldHashQuery: "false",
queryIgnore: "",
wantHashQuery: false,
wantIgnore: map[string]bool{},
},
{
name: "query ignore parameters",
shouldHashQuery: "true",
queryIgnore: "timestamp,request_id",
wantHashQuery: true,
wantIgnore: map[string]bool{"timestamp": true, "request_id": true},
},
{
name: "whitespace in query ignore",
shouldHashQuery: "true",
queryIgnore: " timestamp , request_id ",
wantHashQuery: true,
wantIgnore: map[string]bool{"timestamp": true, "request_id": true},
},
{
name: "case sensitive query ignore",
shouldHashQuery: "true",
queryIgnore: "Timestamp,Request_ID",
wantHashQuery: true,
wantIgnore: map[string]bool{"timestamp": true, "request_id": true},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer setupEnv(t, "CACHE_SHOULD_HASH_QUERY", tt.shouldHashQuery)()
defer setupEnv(t, "CACHE_HASH_QUERY_IGNORE", tt.queryIgnore)()

config := New()

assert.Equal(t, tt.wantHashQuery, config.CacheConfig.ShouldHashQuery)
assert.Equal(t, tt.wantIgnore, config.CacheConfig.HashQueryIgnore)
})
}
})
}
13 changes: 7 additions & 6 deletions config/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ import (

func hashQueryIgnoreMap(queryIgnore []string) map[string]bool {
hashQueryIgnoreMap := make(map[string]bool)

for i := 0; i < len(queryIgnore); i++ {
hashQueryIgnoreMap[queryIgnore[i]] = true
for _, q := range queryIgnore {
hashQueryIgnoreMap[strings.ToLower(strings.TrimSpace(q))] = true
}

return hashQueryIgnoreMap
}

Expand Down Expand Up @@ -55,8 +53,11 @@ func getEnvAsSlice(key string) []string {
if strSlice == "" {
return []string{}
}

return strings.Split(strSlice, ",")
parts := strings.Split(strSlice, ",")
for i, p := range parts {
parts[i] = strings.TrimSpace(p)
}
return parts
}

func getEnvAsInt(key, defaultVal string) int {
Expand Down
Loading