|
|
|
@ -1,7 +1,6 @@ |
|
|
|
|
package httpcache |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"encoding/json" |
|
|
|
|
"regexp" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
@ -10,7 +9,12 @@ import ( |
|
|
|
|
"github.com/go-kratos/kratos/v2/config" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
const configuration_key = "httpcache" |
|
|
|
|
const ( |
|
|
|
|
configurationKey = "httpcache" |
|
|
|
|
path = "path" |
|
|
|
|
url = "url" |
|
|
|
|
configurationPK = "configuration" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
func parseRecursively(values map[string]config.Value) map[string]interface{} { |
|
|
|
|
result := make(map[string]interface{}) |
|
|
|
@ -19,15 +23,20 @@ func parseRecursively(values map[string]config.Value) map[string]interface{} { |
|
|
|
|
result[key] = v |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
if v, e := value.Duration(); e == nil { |
|
|
|
|
switch value.Load().(type) { |
|
|
|
|
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: |
|
|
|
|
if v, e := value.Int(); e == nil { |
|
|
|
|
result[key] = v |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
case float32, float64: |
|
|
|
|
if v, e := value.Float(); e == nil { |
|
|
|
|
result[key] = v |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
if v, e := value.Int(); e == nil { |
|
|
|
|
} |
|
|
|
|
svalue, _ := value.String() |
|
|
|
|
if v, e := time.ParseDuration(svalue); e == nil { |
|
|
|
|
result[key] = v |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
@ -40,28 +49,17 @@ func parseRecursively(values map[string]config.Value) map[string]interface{} { |
|
|
|
|
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": |
|
|
|
|
func parseAPI(apiConfiguration map[string]config.Value) configurationtypes.API { |
|
|
|
|
var a configurationtypes.API |
|
|
|
|
var prometheusConfiguration, souinConfiguration, securityConfiguration map[string]config.Value |
|
|
|
|
apiConfiguration, _ := v.Map() |
|
|
|
|
var prometheusConfiguration, souinConfiguration map[string]config.Value |
|
|
|
|
|
|
|
|
|
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{} |
|
|
|
@ -69,9 +67,6 @@ func ParseConfiguration(c config.Config) plugins.BaseConfiguration { |
|
|
|
|
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{} |
|
|
|
@ -79,35 +74,14 @@ func ParseConfiguration(c config.Config) plugins.BaseConfiguration { |
|
|
|
|
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, |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return a |
|
|
|
|
} |
|
|
|
|
configuration.API = a |
|
|
|
|
case "cache_keys": |
|
|
|
|
|
|
|
|
|
func parseCacheKeys(ccConfiguration map[string]config.Value) map[configurationtypes.RegValue]configurationtypes.Key { |
|
|
|
|
cacheKeys := make(map[configurationtypes.RegValue]configurationtypes.Key) |
|
|
|
|
cacheKeysConfiguration, _ := v.Map() |
|
|
|
|
for cacheKeysConfigurationK, cacheKeysConfigurationV := range cacheKeysConfiguration { |
|
|
|
|
for cacheKeysConfigurationK, cacheKeysConfigurationV := range ccConfiguration { |
|
|
|
|
ck := configurationtypes.Key{} |
|
|
|
|
cacheKeysConfigurationVMap, _ := cacheKeysConfigurationV.Map() |
|
|
|
|
for cacheKeysConfigurationVMapK := range cacheKeysConfigurationVMap { |
|
|
|
@ -123,8 +97,11 @@ func ParseConfiguration(c config.Config) plugins.BaseConfiguration { |
|
|
|
|
rg := regexp.MustCompile(cacheKeysConfigurationK) |
|
|
|
|
cacheKeys[configurationtypes.RegValue{Regexp: rg}] = ck |
|
|
|
|
} |
|
|
|
|
configuration.CacheKeys = cacheKeys |
|
|
|
|
case "default_cache": |
|
|
|
|
|
|
|
|
|
return cacheKeys |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func parseDefaultCache(dcConfiguration map[string]config.Value) *configurationtypes.DefaultCache { |
|
|
|
|
dc := configurationtypes.DefaultCache{ |
|
|
|
|
Distributed: false, |
|
|
|
|
Headers: []string{}, |
|
|
|
@ -137,29 +114,35 @@ func ParseConfiguration(c config.Config) plugins.BaseConfiguration { |
|
|
|
|
TTL: configurationtypes.Duration{}, |
|
|
|
|
DefaultCacheControl: "", |
|
|
|
|
} |
|
|
|
|
defaultCache, _ := v.Map() |
|
|
|
|
for defaultCacheK, defaultCacheV := range defaultCache { |
|
|
|
|
for defaultCacheK, defaultCacheV := range dcConfiguration { |
|
|
|
|
switch defaultCacheK { |
|
|
|
|
case "allowed_http_verbs": |
|
|
|
|
headers, _ := defaultCacheV.Slice() |
|
|
|
|
dc.AllowedHTTPVerbs = make([]string, 0) |
|
|
|
|
for _, header := range headers { |
|
|
|
|
h, _ := header.String() |
|
|
|
|
dc.AllowedHTTPVerbs = append(dc.AllowedHTTPVerbs, h) |
|
|
|
|
} |
|
|
|
|
case "badger": |
|
|
|
|
provider := configurationtypes.CacheProvider{} |
|
|
|
|
badgerConfiguration, _ := v.Map() |
|
|
|
|
badgerConfiguration, _ := defaultCacheV.Map() |
|
|
|
|
for badgerConfigurationK, badgerConfigurationV := range badgerConfiguration { |
|
|
|
|
switch badgerConfigurationK { |
|
|
|
|
case "url": |
|
|
|
|
case url: |
|
|
|
|
provider.URL, _ = badgerConfigurationV.String() |
|
|
|
|
case "path": |
|
|
|
|
case path: |
|
|
|
|
provider.Path, _ = badgerConfigurationV.String() |
|
|
|
|
case "configuration": |
|
|
|
|
case configurationPK: |
|
|
|
|
configMap, e := badgerConfigurationV.Map() |
|
|
|
|
if e == nil { |
|
|
|
|
provider.Configuration = parseRecursively(configMap) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
configuration.DefaultCache.Badger = provider |
|
|
|
|
dc.Badger = provider |
|
|
|
|
case "cdn": |
|
|
|
|
cdn := configurationtypes.CDN{} |
|
|
|
|
cdnConfiguration, _ := v.Map() |
|
|
|
|
cdnConfiguration, _ := defaultCacheV.Map() |
|
|
|
|
for cdnConfigurationK, cdnConfigurationV := range cdnConfiguration { |
|
|
|
|
switch cdnConfigurationK { |
|
|
|
|
case "api_key": |
|
|
|
@ -176,24 +159,24 @@ func ParseConfiguration(c config.Config) plugins.BaseConfiguration { |
|
|
|
|
cdn.Strategy, _ = cdnConfigurationV.String() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
configuration.DefaultCache.CDN = cdn |
|
|
|
|
dc.CDN = cdn |
|
|
|
|
case "etcd": |
|
|
|
|
provider := configurationtypes.CacheProvider{} |
|
|
|
|
etcdConfiguration, _ := v.Map() |
|
|
|
|
etcdConfiguration, _ := defaultCacheV.Map() |
|
|
|
|
for etcdConfigurationK, etcdConfigurationV := range etcdConfiguration { |
|
|
|
|
switch etcdConfigurationK { |
|
|
|
|
case "url": |
|
|
|
|
case url: |
|
|
|
|
provider.URL, _ = etcdConfigurationV.String() |
|
|
|
|
case "path": |
|
|
|
|
case path: |
|
|
|
|
provider.Path, _ = etcdConfigurationV.String() |
|
|
|
|
case "configuration": |
|
|
|
|
case configurationPK: |
|
|
|
|
configMap, e := etcdConfigurationV.Map() |
|
|
|
|
if e == nil { |
|
|
|
|
provider.Configuration = parseRecursively(configMap) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
configuration.DefaultCache.Etcd = provider |
|
|
|
|
dc.Etcd = provider |
|
|
|
|
case "headers": |
|
|
|
|
headers, _ := defaultCacheV.Slice() |
|
|
|
|
dc.Headers = make([]string, 0) |
|
|
|
@ -203,39 +186,39 @@ func ParseConfiguration(c config.Config) plugins.BaseConfiguration { |
|
|
|
|
} |
|
|
|
|
case "nuts": |
|
|
|
|
provider := configurationtypes.CacheProvider{} |
|
|
|
|
nutsConfiguration, _ := v.Map() |
|
|
|
|
nutsConfiguration, _ := defaultCacheV.Map() |
|
|
|
|
for nutsConfigurationK, nutsConfigurationV := range nutsConfiguration { |
|
|
|
|
switch nutsConfigurationK { |
|
|
|
|
case "url": |
|
|
|
|
case url: |
|
|
|
|
provider.URL, _ = nutsConfigurationV.String() |
|
|
|
|
case "path": |
|
|
|
|
case path: |
|
|
|
|
provider.Path, _ = nutsConfigurationV.String() |
|
|
|
|
case "configuration": |
|
|
|
|
case configurationPK: |
|
|
|
|
configMap, e := nutsConfigurationV.Map() |
|
|
|
|
if e == nil { |
|
|
|
|
provider.Configuration = parseRecursively(configMap) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
configuration.DefaultCache.Nuts = provider |
|
|
|
|
dc.Nuts = provider |
|
|
|
|
case "olric": |
|
|
|
|
provider := configurationtypes.CacheProvider{} |
|
|
|
|
olricConfiguration, _ := v.Map() |
|
|
|
|
olricConfiguration, _ := defaultCacheV.Map() |
|
|
|
|
for olricConfigurationK, olricConfigurationV := range olricConfiguration { |
|
|
|
|
switch olricConfigurationK { |
|
|
|
|
case "url": |
|
|
|
|
case url: |
|
|
|
|
provider.URL, _ = olricConfigurationV.String() |
|
|
|
|
case "path": |
|
|
|
|
case path: |
|
|
|
|
provider.Path, _ = olricConfigurationV.String() |
|
|
|
|
case "configuration": |
|
|
|
|
case configurationPK: |
|
|
|
|
configMap, e := olricConfigurationV.Map() |
|
|
|
|
if e == nil { |
|
|
|
|
provider.Configuration = parseRecursively(configMap) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
configuration.DefaultCache.Distributed = true |
|
|
|
|
configuration.DefaultCache.Olric = provider |
|
|
|
|
dc.Distributed = true |
|
|
|
|
dc.Olric = provider |
|
|
|
|
case "regex": |
|
|
|
|
regex, _ := defaultCacheV.Map() |
|
|
|
|
exclude, _ := regex["exclude"].String() |
|
|
|
@ -258,12 +241,12 @@ func ParseConfiguration(c config.Config) plugins.BaseConfiguration { |
|
|
|
|
dc.DefaultCacheControl, _ = defaultCacheV.String() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
configuration.DefaultCache = &dc |
|
|
|
|
case "log_level": |
|
|
|
|
configuration.LogLevel, _ = v.String() |
|
|
|
|
case "urls": |
|
|
|
|
|
|
|
|
|
return &dc |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func parseURLs(urls map[string]config.Value) map[string]configurationtypes.URL { |
|
|
|
|
u := make(map[string]configurationtypes.URL) |
|
|
|
|
urls, _ := v.Map() |
|
|
|
|
|
|
|
|
|
for urlK, urlV := range urls { |
|
|
|
|
currentURL := configurationtypes.URL{ |
|
|
|
@ -271,12 +254,14 @@ func ParseConfiguration(c config.Config) plugins.BaseConfiguration { |
|
|
|
|
Headers: nil, |
|
|
|
|
} |
|
|
|
|
currentValue, _ := urlV.Map() |
|
|
|
|
if currentValue["headers"] != nil { |
|
|
|
|
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 { |
|
|
|
@ -287,17 +272,66 @@ func ParseConfiguration(c config.Config) plugins.BaseConfiguration { |
|
|
|
|
} |
|
|
|
|
u[urlK] = currentURL |
|
|
|
|
} |
|
|
|
|
configuration.URLs = u |
|
|
|
|
|
|
|
|
|
return u |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func parseSurrogateKeys(surrogates map[string]config.Value) map[string]configurationtypes.SurrogateKeys { |
|
|
|
|
u := make(map[string]configurationtypes.SurrogateKeys) |
|
|
|
|
|
|
|
|
|
for surrogateK, surrogateV := range surrogates { |
|
|
|
|
surrogate := configurationtypes.SurrogateKeys{} |
|
|
|
|
currentValue, _ := surrogateV.Map() |
|
|
|
|
for key, value := range currentValue { |
|
|
|
|
switch key { |
|
|
|
|
case "headers": |
|
|
|
|
surrogate.Headers = map[string]string{} |
|
|
|
|
headers, e := value.Map() |
|
|
|
|
if e == nil { |
|
|
|
|
for hKey, hValue := range headers { |
|
|
|
|
v, _ := hValue.String() |
|
|
|
|
surrogate.Headers[hKey] = v |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
case "url": |
|
|
|
|
surl, _ := currentValue["url"].String() |
|
|
|
|
surrogate.URL = surl |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
u[surrogateK] = surrogate |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return u |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 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(configurationKey).Map() |
|
|
|
|
for key, v := range values { |
|
|
|
|
switch key { |
|
|
|
|
case "api": |
|
|
|
|
apiConfiguration, _ := v.Map() |
|
|
|
|
configuration.API = parseAPI(apiConfiguration) |
|
|
|
|
case "cache_keys": |
|
|
|
|
cacheKeysConfiguration, _ := v.Map() |
|
|
|
|
configuration.CacheKeys = parseCacheKeys(cacheKeysConfiguration) |
|
|
|
|
case "default_cache": |
|
|
|
|
defaultCache, _ := v.Map() |
|
|
|
|
configuration.DefaultCache = parseDefaultCache(defaultCache) |
|
|
|
|
case "log_level": |
|
|
|
|
configuration.LogLevel, _ = v.String() |
|
|
|
|
case "urls": |
|
|
|
|
urls, _ := v.Map() |
|
|
|
|
configuration.URLs = parseURLs(urls) |
|
|
|
|
case "ykeys": |
|
|
|
|
ykeys := make(map[string]configurationtypes.SurrogateKeys) |
|
|
|
|
d, _ := json.Marshal(v) |
|
|
|
|
_ = json.Unmarshal(d, &ykeys) |
|
|
|
|
configuration.Ykeys = ykeys |
|
|
|
|
ykeys, _ := v.Map() |
|
|
|
|
configuration.Ykeys = parseSurrogateKeys(ykeys) |
|
|
|
|
case "surrogate_keys": |
|
|
|
|
ykeys := make(map[string]configurationtypes.SurrogateKeys) |
|
|
|
|
d, _ := json.Marshal(v) |
|
|
|
|
_ = json.Unmarshal(d, &ykeys) |
|
|
|
|
configuration.Ykeys = ykeys |
|
|
|
|
surrogates, _ := v.Map() |
|
|
|
|
configuration.SurrogateKeys = parseSurrogateKeys(surrogates) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|