@@ -13,8 +13,13 @@ import (
13
13
"time"
14
14
)
15
15
16
+ const CACHE_STATUS_BYPASS = "BYPASS"
17
+ const CACHE_STATUS_HIT = "HIT"
18
+ const CACHE_STATUS_MISS = "MISS"
19
+
16
20
func GetCacheHandler (cache * graphcache.GraphCache , cfg * config.Config ) http.HandlerFunc {
17
21
return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
22
+
18
23
w .Header ().Add ("Content-Type" , "application/json" )
19
24
20
25
// Create a new HTTP request with the same method, URL, and body as the original request
@@ -24,17 +29,34 @@ func GetCacheHandler(cache *graphcache.GraphCache, cfg *config.Config) http.Hand
24
29
http .Error (w , "Error parsing target URL" , http .StatusInternalServerError )
25
30
}
26
31
27
- proxyReq , err := http .NewRequest (r .Method , targetURL .String (), r .Body )
28
- if err != nil {
29
- fmt .Println (err )
30
- http .Error (w , "Error creating proxy request" , http .StatusInternalServerError )
31
- }
32
+ // only handle if the request is of content type application/json
33
+ // for all other content types, pass the request to the origin server
34
+ if r .Header .Get ("Content-Type" ) != "application/json" {
35
+ proxyReq , err := CopyRequest (r , cfg .Origin )
36
+ if err != nil {
37
+ fmt .Println (err )
38
+ http .Error (w , "Error copying request" , http .StatusInternalServerError )
39
+ }
32
40
33
- // Copy the headers from the original request to the proxy request
34
- for name , values := range r .Header {
35
- for _ , value := range values {
36
- proxyReq .Header .Add (name , value )
41
+ resp , err := SendRequest (proxyReq , w , map [string ]interface {}{
42
+ cfg .CacheHeaderName : CACHE_STATUS_BYPASS ,
43
+ })
44
+ if err != nil {
45
+ fmt .Println (err )
46
+ http .Error (w , "error sending proxy request" , http .StatusInternalServerError )
37
47
}
48
+ defer resp .Body .Close ()
49
+
50
+ responseBody := new (bytes.Buffer )
51
+ io .Copy (responseBody , resp .Body )
52
+ w .Write (responseBody .Bytes ())
53
+ return
54
+ }
55
+
56
+ proxyReq , err := CopyRequest (r , targetURL .String ())
57
+ if err != nil {
58
+ fmt .Println (err )
59
+ http .Error (w , "Error copying request" , http .StatusInternalServerError )
38
60
}
39
61
40
62
requestBody , err := io .ReadAll (proxyReq .Body )
@@ -78,27 +100,15 @@ func GetCacheHandler(cache *graphcache.GraphCache, cfg *config.Config) http.Hand
78
100
proxyReq .Body = io .NopCloser (bytes .NewBuffer (transformedRequest .Bytes ()))
79
101
proxyReq .ContentLength = - 1
80
102
81
- client := http. Client {}
82
- // Send the proxy request using the custom transport
83
- resp , err := client . Do ( proxyReq )
84
- if err != nil || resp == nil {
85
- http . Error ( w , "Error sending proxy request" , http . StatusInternalServerError )
86
-
103
+ resp , err := SendRequest ( proxyReq , w , map [ string ] interface {}{
104
+ cfg . CacheHeaderName : CACHE_STATUS_BYPASS ,
105
+ } )
106
+ if err != nil {
107
+ fmt . Println ( err )
108
+ http . Error ( w , "error sending proxy request" , http . StatusInternalServerError )
87
109
}
88
110
defer resp .Body .Close ()
89
111
90
- // Copy the headers from the proxy response to the original response
91
- for name , values := range resp .Header {
92
- if name != "Content-Length" {
93
- for _ , value := range values {
94
- w .Header ().Add (name , value )
95
- }
96
- }
97
- }
98
-
99
- // Set the status code of the original response to the status code of the proxy response
100
- w .WriteHeader (resp .StatusCode )
101
-
102
112
responseBody := new (bytes.Buffer )
103
113
io .Copy (responseBody , resp .Body )
104
114
@@ -116,6 +126,7 @@ func GetCacheHandler(cache *graphcache.GraphCache, cfg *config.Config) http.Hand
116
126
if err != nil {
117
127
http .Error (w , "error removing __typename" , http .StatusInternalServerError )
118
128
}
129
+
119
130
w .Write (res .Bytes ())
120
131
return
121
132
}
@@ -133,32 +144,23 @@ func GetCacheHandler(cache *graphcache.GraphCache, cfg *config.Config) http.Hand
133
144
if err != nil {
134
145
http .Error (w , "error removing __typename" , http .StatusInternalServerError )
135
146
}
147
+ w .Header ().Add (cfg .CacheHeaderName , CACHE_STATUS_HIT )
136
148
w .Write (res .Bytes ())
137
149
return
138
150
}
139
151
140
152
proxyReq .Body = io .NopCloser (bytes .NewBuffer (transformedRequest .Bytes ()))
141
153
proxyReq .ContentLength = - 1
142
154
143
- client := http.Client {}
144
-
145
- // Send the proxy request using the custom transport
146
- resp , err := client .Do (proxyReq )
155
+ resp , err := SendRequest (proxyReq , w , map [string ]interface {}{
156
+ cfg .CacheHeaderName : CACHE_STATUS_MISS ,
157
+ })
147
158
if err != nil {
148
159
fmt .Println (err )
149
160
http .Error (w , "error sending proxy request" , http .StatusInternalServerError )
150
161
}
151
162
defer resp .Body .Close ()
152
163
153
- // copy the headers from the proxy response to the original response
154
- for name , values := range resp .Header {
155
- if name != "Content-Length" { // copy all headers except Content-Length
156
- for _ , value := range values {
157
- w .Header ().Add (name , value )
158
- }
159
- }
160
- }
161
-
162
164
responseBody := new (bytes.Buffer )
163
165
io .Copy (responseBody , resp .Body )
164
166
@@ -211,7 +213,54 @@ func GetCacheHandler(cache *graphcache.GraphCache, cfg *config.Config) http.Hand
211
213
if err != nil {
212
214
http .Error (w , "error removing __typename" , http .StatusInternalServerError )
213
215
}
216
+
214
217
w .Write (res .Bytes ())
215
- w .Header ().Add ("graphql_cache" , "miss" )
216
218
})
217
219
}
220
+
221
+ func CopyRequest (r * http.Request , targetURL string ) (* http.Request , error ) {
222
+ proxyReq , err := http .NewRequest (r .Method , targetURL , r .Body )
223
+ if err != nil {
224
+ fmt .Println (err )
225
+ // http.Error(w, "Error creating proxy request", http.StatusInternalServerError)
226
+ return nil , err
227
+ }
228
+
229
+ // Copy the headers from the original request to the proxy request
230
+ for name , values := range r .Header {
231
+ for _ , value := range values {
232
+ proxyReq .Header .Add (name , value )
233
+ }
234
+ }
235
+
236
+ proxyReq .ContentLength = - 1
237
+
238
+ return proxyReq , nil
239
+ }
240
+
241
+ func SendRequest (proxyReq * http.Request , w http.ResponseWriter , headers map [string ]interface {}) (* http.Response , error ) {
242
+ client := http.Client {}
243
+ // Send the proxy request using the custom transport
244
+ resp , err := client .Do (proxyReq )
245
+ if err != nil || resp == nil {
246
+ http .Error (w , "Error sending proxy request" , http .StatusInternalServerError )
247
+ return resp , err
248
+ }
249
+
250
+ // Copy the headers from the proxy response to the original response
251
+ for name , values := range resp .Header {
252
+ if name != "Content-Length" {
253
+ for _ , value := range values {
254
+ w .Header ().Add (name , value )
255
+ }
256
+ }
257
+ }
258
+
259
+ for key , value := range headers {
260
+ w .Header ().Add (key , fmt .Sprintf ("%v" , value ))
261
+ }
262
+
263
+ w .WriteHeader (resp .StatusCode )
264
+
265
+ return resp , nil
266
+ }
0 commit comments