@@ -10,28 +10,35 @@ package cache
10
10
// Repo: https://github.com/fabiocicerchia/go-proxy-cache
11
11
12
12
import (
13
- "errors"
14
- "fmt"
15
13
"net/http"
16
14
"net/url"
17
15
"strings"
18
16
"time"
19
17
18
+ "github.com/pkg/errors"
19
+
20
20
"github.com/fabiocicerchia/go-proxy-cache/cache/engine"
21
21
"github.com/fabiocicerchia/go-proxy-cache/utils"
22
22
"github.com/fabiocicerchia/go-proxy-cache/utils/slice"
23
23
log "github.com/sirupsen/logrus"
24
24
)
25
25
26
- // CacheObj - Contains cache settings and current cached/cacheable object.
27
- type CacheObj struct {
28
- AllowedStatuses []int
29
- AllowedMethods []string
30
- CurrentObj URIObj
31
- DomainID string
26
+ var errMissingRedisConnection = errors .New ("missing redis connection" )
27
+ var errNotAllowed = errors .New ("not allowed" )
28
+ var errCannotFetchMetadata = errors .New ("cannot fetch metadata" )
29
+ var errCannotGetKey = errors .New ("cannot get key" )
30
+ var errCannotDecode = errors .New ("cannot decode" )
31
+ var errVaryWildcard = errors .New ("vary: *" )
32
+
33
+ // Object - Contains cache settings and current cached/cacheable object.
34
+ type Object struct {
35
+ AllowedStatuses []int
36
+ AllowedMethods []string
37
+ CurrentURIObject URIObj
38
+ DomainID string
32
39
}
33
40
34
- // URIObj - Holds details about the response
41
+ // URIObj - Holds details about the response.
35
42
type URIObj struct {
36
43
URL url.URL
37
44
Host string
@@ -44,35 +51,34 @@ type URIObj struct {
44
51
}
45
52
46
53
// IsStatusAllowed - Checks if a status code is allowed to be cached.
47
- func (c CacheObj ) IsStatusAllowed () bool {
48
- return slice .ContainsInt (c .AllowedStatuses , c .CurrentObj .StatusCode )
54
+ func (c Object ) IsStatusAllowed () bool {
55
+ return slice .ContainsInt (c .AllowedStatuses , c .CurrentURIObject .StatusCode )
49
56
}
50
57
51
58
// IsMethodAllowed - Checks if a HTTP method is allowed to be cached.
52
- func (c CacheObj ) IsMethodAllowed () bool {
53
- return slice .ContainsString (c .AllowedMethods , c .CurrentObj .Method )
59
+ func (c Object ) IsMethodAllowed () bool {
60
+ return slice .ContainsString (c .AllowedMethods , c .CurrentURIObject .Method )
54
61
}
55
62
56
63
// IsValid - Verifies the validity of a cacheable object.
57
- func (c CacheObj ) IsValid () (bool , error ) {
58
- if ! c .IsStatusAllowed () || slice .LenSliceBytes (c .CurrentObj .Content ) == 0 {
59
- return false , fmt .Errorf (
60
- "not allowed. status %d - content length %d" ,
61
- c .CurrentObj .StatusCode ,
62
- slice .LenSliceBytes (c .CurrentObj .Content ),
63
- )
64
+ func (c Object ) IsValid () (bool , error ) {
65
+ if ! c .IsStatusAllowed () || slice .LenSliceBytes (c .CurrentURIObject .Content ) == 0 {
66
+ return false , errors .Wrapf (errNotAllowed ,
67
+ "status %d - content length %d" ,
68
+ c .CurrentURIObject .StatusCode ,
69
+ slice .LenSliceBytes (c .CurrentURIObject .Content ))
64
70
}
65
71
66
72
return true , nil
67
73
}
68
74
69
- func (c CacheObj ) handleMetadata (domainID string , targetURL url.URL , expiration time.Duration ) ([]string , error ) {
70
- meta , err := GetVary (c .CurrentObj .ResponseHeaders )
75
+ func (c Object ) handleMetadata (domainID string , targetURL url.URL , expiration time.Duration ) ([]string , error ) {
76
+ meta , err := GetVary (c .CurrentURIObject .ResponseHeaders )
71
77
if err != nil {
72
78
return []string {}, err
73
79
}
74
80
75
- _ , err = StoreMetadata (domainID , c .CurrentObj .Method , targetURL , meta , expiration )
81
+ _ , err = StoreMetadata (domainID , c .CurrentURIObject .Method , targetURL , meta , expiration )
76
82
if err != nil {
77
83
return []string {}, err
78
84
}
@@ -81,15 +87,21 @@ func (c CacheObj) handleMetadata(domainID string, targetURL url.URL, expiration
81
87
}
82
88
83
89
// StoreFullPage - Stores the whole page response in cache.
84
- func (c CacheObj ) StoreFullPage (expiration time.Duration ) (bool , error ) {
90
+ func (c Object ) StoreFullPage (expiration time.Duration ) (bool , error ) {
85
91
if ! c .IsStatusAllowed () || ! c .IsMethodAllowed () || expiration < 1 {
86
- log .Debugf ("Not allowed to be stored. Status: %v - Method: %v - Expiration: %v" , c .IsStatusAllowed (), c .IsMethodAllowed (), expiration )
92
+ log .Debugf (
93
+ "Not allowed to be stored. Status: %v - Method: %v - Expiration: %v" ,
94
+ c .IsStatusAllowed (),
95
+ c .IsMethodAllowed (),
96
+ expiration ,
97
+ )
98
+
87
99
return false , nil
88
100
}
89
101
90
- targetURL := c .CurrentObj .URL
91
- targetURL .Scheme = c .CurrentObj .Scheme
92
- targetURL .Host = c .CurrentObj .Host
102
+ targetURL := c .CurrentURIObject .URL
103
+ targetURL .Scheme = c .CurrentURIObject .Scheme
104
+ targetURL .Host = c .CurrentURIObject .Host
93
105
94
106
meta , err := c .handleMetadata (c .DomainID , targetURL , expiration )
95
107
if err != nil {
@@ -98,61 +110,61 @@ func (c CacheObj) StoreFullPage(expiration time.Duration) (bool, error) {
98
110
99
111
conn := engine .GetConn (c .DomainID )
100
112
if conn == nil {
101
- return false , fmt . Errorf ( "missing redis connection for %s" , c .DomainID )
113
+ return false , errors . Wrapf ( errMissingRedisConnection , "Error for %s" , c .DomainID )
102
114
}
103
115
104
- encoded , err := conn .Encode (c .CurrentObj )
116
+ encoded , err := conn .Encode (c .CurrentURIObject )
105
117
if err != nil {
106
118
return false , err
107
119
}
108
120
109
- key := StorageKey (c .CurrentObj .Method , targetURL , meta , c .CurrentObj .RequestHeaders )
121
+ key := StorageKey (c .CurrentURIObject .Method , targetURL , meta , c .CurrentURIObject .RequestHeaders )
110
122
111
123
return conn .Set (key , encoded , expiration )
112
124
}
113
125
114
126
// RetrieveFullPage - Retrieves the whole page response from cache.
115
- func (c * CacheObj ) RetrieveFullPage (method string , url url.URL , reqHeaders http.Header ) error {
127
+ func (c * Object ) RetrieveFullPage (method string , url url.URL , reqHeaders http.Header ) error {
116
128
obj := & URIObj {}
117
129
118
130
meta , err := FetchMetadata (c .DomainID , method , url )
119
131
if err != nil {
120
- return fmt . Errorf ( "cannot fetch metadata: %s" , err )
132
+ return errors . Wrap ( errCannotFetchMetadata , err . Error () )
121
133
}
122
134
123
135
conn := engine .GetConn (c .DomainID )
124
136
if conn == nil {
125
- return fmt . Errorf ( "missing redis connection for %s" , c .DomainID )
137
+ return errors . Wrapf ( errMissingRedisConnection , "Error for %s" , c .DomainID )
126
138
}
127
139
128
140
key := StorageKey (method , url , meta , reqHeaders )
129
141
log .Debugf ("StorageKey: %s" , key )
130
142
131
143
encoded , err := conn .Get (key )
132
144
if err != nil {
133
- return fmt . Errorf ( "cannot get key: %s" , err )
145
+ return errors . Wrap ( errCannotGetKey , err . Error () )
134
146
}
135
147
136
148
err = conn .Decode (encoded , obj )
137
149
if err != nil {
138
- return fmt . Errorf ( "cannot decode: %s" , err )
150
+ return errors . Wrap ( errCannotDecode , err . Error () )
139
151
}
140
152
141
- c .CurrentObj = * obj
153
+ c .CurrentURIObject = * obj
142
154
143
155
return nil
144
156
}
145
157
146
158
// PurgeFullPage - Deletes the whole page response from cache.
147
- func (c CacheObj ) PurgeFullPage (method string , url url.URL ) (bool , error ) {
159
+ func (c Object ) PurgeFullPage (method string , url url.URL ) (bool , error ) {
148
160
err := PurgeMetadata (c .DomainID , url )
149
161
if err != nil {
150
162
return false , err
151
163
}
152
164
153
165
conn := engine .GetConn (c .DomainID )
154
166
if conn == nil {
155
- return false , fmt . Errorf ( "missing redis connection for %s" , c .DomainID )
167
+ return false , errors . Wrapf ( errMissingRedisConnection , "Error for %s" , c .DomainID )
156
168
}
157
169
158
170
var meta []string
@@ -161,6 +173,7 @@ func (c CacheObj) PurgeFullPage(method string, url url.URL) (bool, error) {
161
173
match := utils .StringSeparatorOne + "PURGE" + utils .StringSeparatorOne
162
174
replace := utils .StringSeparatorOne + "*" + utils .StringSeparatorOne
163
175
keyPattern := strings .Replace (key , match , replace , 1 ) + "*"
176
+
164
177
affected , err := conn .DelWildcard (keyPattern )
165
178
if err != nil {
166
179
return false , err
@@ -192,7 +205,7 @@ func FetchMetadata(domainID string, method string, url url.URL) ([]string, error
192
205
193
206
conn := engine .GetConn (domainID )
194
207
if conn == nil {
195
- return []string {}, fmt . Errorf ( "missing redis connection for %s" , domainID )
208
+ return []string {}, errors . Wrapf ( errMissingRedisConnection , "Error for %s" , domainID )
196
209
}
197
210
198
211
return conn .List (key )
@@ -204,10 +217,11 @@ func PurgeMetadata(domainID string, url url.URL) error {
204
217
205
218
conn := engine .GetConn (domainID )
206
219
if conn == nil {
207
- return fmt . Errorf ( "missing redis connection for %s" , domainID )
220
+ return errors . Wrapf ( errMissingRedisConnection , "Error for %s" , domainID )
208
221
}
209
222
210
223
_ , err := conn .DelWildcard (keyPattern )
224
+
211
225
return err
212
226
}
213
227
@@ -217,10 +231,11 @@ func StoreMetadata(domainID string, method string, url url.URL, meta []string, e
217
231
218
232
conn := engine .GetConn (domainID )
219
233
if conn == nil {
220
- return false , fmt . Errorf ( "missing redis connection for %s" , domainID )
234
+ return false , errors . Wrapf ( errMissingRedisConnection , "Error for %s" , domainID )
221
235
}
222
236
223
- _ = conn .Del (key ) //nolint:golint,errcheck
237
+ _ = conn .Del (key )
238
+
224
239
err := conn .Push (key , meta )
225
240
if err != nil {
226
241
return false , err
@@ -242,7 +257,7 @@ func GetVary(headers http.Header) ([]string, error) {
242
257
vary := headers .Get ("Vary" )
243
258
244
259
if vary == "*" {
245
- return []string {}, errors . New ( "vary: *" )
260
+ return []string {}, errVaryWildcard
246
261
}
247
262
248
263
varyList := strings .Split (vary , "," )
0 commit comments