You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
kratos/filter/httpcache/configuration.go

305 lines
9.5 KiB

package httpcache
import (
"encoding/json"
"regexp"
"time"
"github.com/darkweak/souin/configurationtypes"
"github.com/darkweak/souin/plugins"
"github.com/go-kratos/kratos/v2/config"
)
const configuration_key = "httpcache"
func parseRecursively(values map[string]config.Value) map[string]interface{} {
result := make(map[string]interface{})
for key, value := range values {
if v, e := value.Bool(); e == nil {
result[key] = v
continue
}
if v, e := value.Duration(); e == nil {
result[key] = v
continue
}
if v, e := value.Float(); e == nil {
result[key] = v
continue
}
if v, e := value.Int(); e == nil {
result[key] = v
continue
}
if v, e := value.Map(); e == nil {
result[key] = parseRecursively(v)
continue
}
}
return result
}
// ParseConfiguration parse the Kratos configuration into a valid HTTP
// cache configuration object.
func ParseConfiguration(c config.Config) plugins.BaseConfiguration {
var configuration plugins.BaseConfiguration
values, _ := c.Value(configuration_key).Map()
for key, v := range values {
switch key {
case "api":
var a configurationtypes.API
var prometheusConfiguration, souinConfiguration, securityConfiguration map[string]config.Value
apiConfiguration, _ := v.Map()
for apiK, apiV := range apiConfiguration {
switch apiK {
case "prometheus":
prometheusConfiguration, _ = apiV.Map()
case "souin":
souinConfiguration, _ = apiV.Map()
case "security":
securityConfiguration, _ = apiV.Map()
}
}
if prometheusConfiguration != nil {
a.Prometheus = configurationtypes.APIEndpoint{}
a.Prometheus.Enable = true
if prometheusConfiguration["basepath"] != nil {
a.Prometheus.BasePath, _ = prometheusConfiguration["basepath"].String()
}
if prometheusConfiguration["security"] != nil {
a.Prometheus.Security, _ = prometheusConfiguration["security"].Bool()
}
}
if souinConfiguration != nil {
a.Souin = configurationtypes.APIEndpoint{}
a.Souin.Enable = true
if souinConfiguration["basepath"] != nil {
a.Souin.BasePath, _ = souinConfiguration["basepath"].String()
}
if souinConfiguration["security"] != nil {
a.Souin.Security, _ = souinConfiguration["security"].Bool()
}
}
if securityConfiguration != nil {
a.Security = configurationtypes.SecurityAPI{}
a.Security.Enable = true
if securityConfiguration["basepath"] != nil {
a.Security.BasePath, _ = securityConfiguration["basepath"].String()
}
if securityConfiguration["users"] != nil {
users, _ := securityConfiguration["users"].Slice()
a.Security.Users = make([]configurationtypes.User, 0)
for _, user := range users {
currentUser, _ := user.Map()
username, _ := currentUser["username"].String()
password, _ := currentUser["password"].String()
a.Security.Users = append(a.Security.Users, configurationtypes.User{
Username: username,
Password: password,
})
}
}
}
configuration.API = a
case "cache_keys":
cacheKeys := make(map[configurationtypes.RegValue]configurationtypes.Key)
cacheKeysConfiguration, _ := v.Map()
for cacheKeysConfigurationK, cacheKeysConfigurationV := range cacheKeysConfiguration {
ck := configurationtypes.Key{}
cacheKeysConfigurationVMap, _ := cacheKeysConfigurationV.Map()
for cacheKeysConfigurationVMapK := range cacheKeysConfigurationVMap {
switch cacheKeysConfigurationVMapK {
case "disable_body":
ck.DisableBody = true
case "disable_host":
ck.DisableHost = true
case "disable_method":
ck.DisableMethod = true
}
}
rg := regexp.MustCompile(cacheKeysConfigurationK)
cacheKeys[configurationtypes.RegValue{Regexp: rg}] = ck
}
configuration.CacheKeys = cacheKeys
case "default_cache":
dc := configurationtypes.DefaultCache{
Distributed: false,
Headers: []string{},
Olric: configurationtypes.CacheProvider{
URL: "",
Path: "",
Configuration: nil,
},
Regex: configurationtypes.Regex{},
TTL: configurationtypes.Duration{},
DefaultCacheControl: "",
}
defaultCache, _ := v.Map()
for defaultCacheK, defaultCacheV := range defaultCache {
switch defaultCacheK {
case "badger":
provider := configurationtypes.CacheProvider{}
badgerConfiguration, _ := v.Map()
for badgerConfigurationK, badgerConfigurationV := range badgerConfiguration {
switch badgerConfigurationK {
case "url":
provider.URL, _ = badgerConfigurationV.String()
case "path":
provider.Path, _ = badgerConfigurationV.String()
case "configuration":
configMap, e := badgerConfigurationV.Map()
if e == nil {
provider.Configuration = parseRecursively(configMap)
}
}
}
configuration.DefaultCache.Badger = provider
case "cdn":
cdn := configurationtypes.CDN{}
cdnConfiguration, _ := v.Map()
for cdnConfigurationK, cdnConfigurationV := range cdnConfiguration {
switch cdnConfigurationK {
case "api_key":
cdn.APIKey, _ = cdnConfigurationV.String()
case "dynamic":
cdn.Dynamic = true
case "hostname":
cdn.Hostname, _ = cdnConfigurationV.String()
case "network":
cdn.Network, _ = cdnConfigurationV.String()
case "provider":
cdn.Provider, _ = cdnConfigurationV.String()
case "strategy":
cdn.Strategy, _ = cdnConfigurationV.String()
}
}
configuration.DefaultCache.CDN = cdn
case "etcd":
provider := configurationtypes.CacheProvider{}
etcdConfiguration, _ := v.Map()
for etcdConfigurationK, etcdConfigurationV := range etcdConfiguration {
switch etcdConfigurationK {
case "url":
provider.URL, _ = etcdConfigurationV.String()
case "path":
provider.Path, _ = etcdConfigurationV.String()
case "configuration":
configMap, e := etcdConfigurationV.Map()
if e == nil {
provider.Configuration = parseRecursively(configMap)
}
}
}
configuration.DefaultCache.Etcd = provider
case "headers":
headers, _ := defaultCacheV.Slice()
dc.Headers = make([]string, 0)
for _, header := range headers {
h, _ := header.String()
dc.Headers = append(dc.Headers, h)
}
case "nuts":
provider := configurationtypes.CacheProvider{}
nutsConfiguration, _ := v.Map()
for nutsConfigurationK, nutsConfigurationV := range nutsConfiguration {
switch nutsConfigurationK {
case "url":
provider.URL, _ = nutsConfigurationV.String()
case "path":
provider.Path, _ = nutsConfigurationV.String()
case "configuration":
configMap, e := nutsConfigurationV.Map()
if e == nil {
provider.Configuration = parseRecursively(configMap)
}
}
}
configuration.DefaultCache.Nuts = provider
case "olric":
provider := configurationtypes.CacheProvider{}
olricConfiguration, _ := v.Map()
for olricConfigurationK, olricConfigurationV := range olricConfiguration {
switch olricConfigurationK {
case "url":
provider.URL, _ = olricConfigurationV.String()
case "path":
provider.Path, _ = olricConfigurationV.String()
case "configuration":
configMap, e := olricConfigurationV.Map()
if e == nil {
provider.Configuration = parseRecursively(configMap)
}
}
}
configuration.DefaultCache.Distributed = true
configuration.DefaultCache.Olric = provider
case "regex":
regex, _ := defaultCacheV.Map()
exclude, _ := regex["exclude"].String()
if exclude != "" {
dc.Regex = configurationtypes.Regex{Exclude: exclude}
}
case "ttl":
sttl, err := defaultCacheV.String()
ttl, _ := time.ParseDuration(sttl)
if err == nil {
dc.TTL = configurationtypes.Duration{Duration: ttl}
}
case "stale":
sstale, err := defaultCacheV.String()
stale, _ := time.ParseDuration(sstale)
if err == nil {
dc.Stale = configurationtypes.Duration{Duration: stale}
}
case "default_cache_control":
dc.DefaultCacheControl, _ = defaultCacheV.String()
}
}
configuration.DefaultCache = &dc
case "log_level":
configuration.LogLevel, _ = v.String()
case "urls":
u := make(map[string]configurationtypes.URL)
urls, _ := v.Map()
for urlK, urlV := range urls {
currentURL := configurationtypes.URL{
TTL: configurationtypes.Duration{},
Headers: nil,
}
currentValue, _ := urlV.Map()
currentURL.Headers = make([]string, 0)
headers, _ := currentValue["headers"].Slice()
for _, header := range headers {
h, _ := header.String()
currentURL.Headers = append(currentURL.Headers, h)
}
sttl, err := currentValue["ttl"].String()
ttl, _ := time.ParseDuration(sttl)
if err == nil {
currentURL.TTL = configurationtypes.Duration{Duration: ttl}
}
if _, exists := currentValue["default_cache_control"]; exists {
currentURL.DefaultCacheControl, _ = currentValue["default_cache_control"].String()
}
u[urlK] = currentURL
}
configuration.URLs = u
case "ykeys":
ykeys := make(map[string]configurationtypes.SurrogateKeys)
d, _ := json.Marshal(v)
_ = json.Unmarshal(d, &ykeys)
configuration.Ykeys = ykeys
case "surrogate_keys":
ykeys := make(map[string]configurationtypes.SurrogateKeys)
d, _ := json.Marshal(v)
_ = json.Unmarshal(d, &ykeys)
configuration.Ykeys = ykeys
}
}
return configuration
}