5
5
"bytes"
6
6
"log"
7
7
"net/http"
8
+ "sync"
8
9
"time"
9
10
)
10
11
@@ -13,6 +14,7 @@ import (
13
14
// Response are indexed by the request URL path and are stored
14
15
// only if they contain the "Expires" header.
15
16
type CacheMiddleware struct {
17
+ mutex sync.RWMutex
16
18
cache map [string ]* cachedResponse
17
19
}
18
20
@@ -33,17 +35,22 @@ func NewCacheMiddleware() *CacheMiddleware {
33
35
func (c * CacheMiddleware ) ProcessRequest (rw http.ResponseWriter , req * http.Request ) {
34
36
log .Printf ("Processing request for: '%v'" , req .URL .Path )
35
37
36
- entry , ok := c .cache [ req .URL .Path ]
38
+ cached , ok := c .get ( req .URL .Path )
37
39
38
- // Response is not on cache or already expired
39
- if ! ok || entry . expires <= time . Now (). Unix () {
40
+ // Response is not on cache
41
+ if ! ok {
40
42
setCacheStatus (rw , "MISS" )
41
- delete (c .cache , req .URL .Path ) // not necessary?
43
+ return
44
+ }
45
+ // Response in cache expired
46
+ if cached .expires <= time .Now ().Unix () {
47
+ setCacheStatus (rw , "MISS" )
48
+ c .delete (req .URL .Path )
42
49
return
43
50
}
44
51
45
52
// Read cached response
46
- res , err := http .ReadResponse (bufio .NewReader (bytes .NewReader (entry .responseData )), req )
53
+ res , err := http .ReadResponse (bufio .NewReader (bytes .NewReader (cached .responseData )), req )
47
54
if err != nil {
48
55
log .Printf ("Error reading response stored in cache: %v" , err )
49
56
setCacheStatus (rw , "MISS" )
@@ -72,7 +79,27 @@ func (c *CacheMiddleware) ProcessResponse(res *http.Response, req *http.Request)
72
79
}
73
80
74
81
b := DumpResponse (res )
75
- c .cache [req .URL .Path ] = & cachedResponse {responseData : b .Bytes (), expires : t .Unix ()}
82
+
83
+ c .update (req .URL .Path , & cachedResponse {responseData : b .Bytes (), expires : t .Unix ()})
84
+ }
85
+
86
+ func (c * CacheMiddleware ) get (URLPath string ) (entry * cachedResponse , ok bool ) {
87
+ c .mutex .RLock ()
88
+ defer c .mutex .RUnlock ()
89
+ entry , ok = c .cache [URLPath ]
90
+ return
91
+ }
92
+
93
+ func (c * CacheMiddleware ) update (URLPath string , response * cachedResponse ) {
94
+ c .mutex .Lock ()
95
+ defer c .mutex .Unlock ()
96
+ c .cache [URLPath ] = response
97
+ }
98
+
99
+ func (c * CacheMiddleware ) delete (URLPath string ) {
100
+ c .mutex .Lock ()
101
+ defer c .mutex .Unlock ()
102
+ delete (c .cache , URLPath )
76
103
}
77
104
78
105
func setCacheStatus (rw http.ResponseWriter , status string ) {
0 commit comments