-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathhttp.go
More file actions
96 lines (80 loc) · 2.4 KB
/
http.go
File metadata and controls
96 lines (80 loc) · 2.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Package httpcache introduces an in-memory-cached http client into the KrakenD stack
package httpcache
import (
"context"
"encoding/json"
"net/http"
"github.com/krakend/httpcache"
"github.com/krakend/lru"
"github.com/luraproject/lura/v2/config"
"github.com/luraproject/lura/v2/transport/http/client"
)
type Cache interface {
// Get returns the []byte representation of a cached response and a bool
// set to true if the value isn't empty
Get(key string) (responseBytes []byte, ok bool)
// Set stores the []byte representation of a response against a key
Set(key string, responseBytes []byte)
// Delete removes the value associated with the key
Delete(key string)
}
// Namespace is the key to use to store and access the custom config data
const Namespace = "github.com/devopsfaith/krakend-httpcache"
// NewHTTPClient creates a HTTPClientFactory using an in-memory-cached http client
func NewHTTPClient(cfg *config.Backend, nextF client.HTTPClientFactory) client.HTTPClientFactory {
raw, ok := cfg.ExtraConfig[Namespace]
if !ok {
return nextF
}
b, err := json.Marshal(raw)
if err != nil {
return defaultClient(nextF)
}
var opts options
if err := json.Unmarshal(b, &opts); err != nil {
return defaultClient(nextF)
}
return getCachedClient(nextF, selectCache(opts))
}
func defaultClient(nextF client.HTTPClientFactory) client.HTTPClientFactory {
return getCachedClient(nextF, httpcache.NewMemoryCache())
}
func getCachedClient(nextF client.HTTPClientFactory, cache Cache) client.HTTPClientFactory {
return func(ctx context.Context) *http.Client {
httpClient := nextF(ctx)
return &http.Client{
Transport: &httpcache.Transport{
Transport: httpClient.Transport,
Cache: cache,
},
CheckRedirect: httpClient.CheckRedirect,
Jar: httpClient.Jar,
Timeout: httpClient.Timeout,
}
}
}
func selectCache(opts options) Cache {
if opts.MaxSize == 0 || opts.MaxItems == 0 {
if opts.Shared {
return globalCache
}
return httpcache.NewMemoryCache()
}
if !opts.Shared {
cache, _ := lru.NewLruCache(opts.MaxSize, opts.MaxItems)
return cache
}
if globalLruCache == nil {
globalLruCache, _ = lru.NewLruCache(opts.MaxSize, opts.MaxItems)
}
return globalLruCache
}
var (
globalLruCache Cache
globalCache = httpcache.NewMemoryCache()
)
type options struct {
Shared bool `json:"shared"`
MaxSize uint64 `json:"max_size"`
MaxItems uint64 `json:"max_items"`
}