Skip to content

Commit 0f43e24

Browse files
committed
made rwInterceptor properly transparent to support optional interfaces
1 parent 8a54c36 commit 0f43e24

File tree

1 file changed

+227
-1
lines changed

1 file changed

+227
-1
lines changed

middleware/http/server.go

Lines changed: 227 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package http
22

33
import (
4+
"io"
45
"net/http"
56
"strconv"
67
"sync/atomic"
@@ -114,7 +115,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
114115
}()
115116

116117
// call next http Handler func using our updated context.
117-
h.next.ServeHTTP(ri, r.WithContext(ctx))
118+
h.next.ServeHTTP(ri.wrap(), r.WithContext(ctx))
118119
}
119120

120121
// rwInterceptor intercepts the ResponseWriter so it can track response size
@@ -147,3 +148,228 @@ func (r *rwInterceptor) getStatusCode() int {
147148
func (r *rwInterceptor) getResponseSize() string {
148149
return strconv.FormatUint(atomic.LoadUint64(&r.size), 10)
149150
}
151+
152+
func (t *rwInterceptor) wrap() http.ResponseWriter {
153+
var (
154+
hj, i0 = t.w.(http.Hijacker)
155+
cn, i1 = t.w.(http.CloseNotifier)
156+
pu, i2 = t.w.(http.Pusher)
157+
fl, i3 = t.w.(http.Flusher)
158+
rf, i4 = t.w.(io.ReaderFrom)
159+
)
160+
161+
switch {
162+
case !i0 && !i1 && !i2 && !i3 && !i4:
163+
return struct {
164+
http.ResponseWriter
165+
}{t}
166+
case !i0 && !i1 && !i2 && !i3 && i4:
167+
return struct {
168+
http.ResponseWriter
169+
io.ReaderFrom
170+
}{t, rf}
171+
case !i0 && !i1 && !i2 && i3 && !i4:
172+
return struct {
173+
http.ResponseWriter
174+
http.Flusher
175+
}{t, fl}
176+
case !i0 && !i1 && !i2 && i3 && i4:
177+
return struct {
178+
http.ResponseWriter
179+
http.Flusher
180+
io.ReaderFrom
181+
}{t, fl, rf}
182+
case !i0 && !i1 && i2 && !i3 && !i4:
183+
return struct {
184+
http.ResponseWriter
185+
http.Pusher
186+
}{t, pu}
187+
case !i0 && !i1 && i2 && !i3 && i4:
188+
return struct {
189+
http.ResponseWriter
190+
http.Pusher
191+
io.ReaderFrom
192+
}{t, pu, rf}
193+
case !i0 && !i1 && i2 && i3 && !i4:
194+
return struct {
195+
http.ResponseWriter
196+
http.Pusher
197+
http.Flusher
198+
}{t, pu, fl}
199+
case !i0 && !i1 && i2 && i3 && i4:
200+
return struct {
201+
http.ResponseWriter
202+
http.Pusher
203+
http.Flusher
204+
io.ReaderFrom
205+
}{t, pu, fl, rf}
206+
case !i0 && i1 && !i2 && !i3 && !i4:
207+
return struct {
208+
http.ResponseWriter
209+
http.CloseNotifier
210+
}{t, cn}
211+
case !i0 && i1 && !i2 && !i3 && i4:
212+
return struct {
213+
http.ResponseWriter
214+
http.CloseNotifier
215+
io.ReaderFrom
216+
}{t, cn, rf}
217+
case !i0 && i1 && !i2 && i3 && !i4:
218+
return struct {
219+
http.ResponseWriter
220+
http.CloseNotifier
221+
http.Flusher
222+
}{t, cn, fl}
223+
case !i0 && i1 && !i2 && i3 && i4:
224+
return struct {
225+
http.ResponseWriter
226+
http.CloseNotifier
227+
http.Flusher
228+
io.ReaderFrom
229+
}{t, cn, fl, rf}
230+
case !i0 && i1 && i2 && !i3 && !i4:
231+
return struct {
232+
http.ResponseWriter
233+
http.CloseNotifier
234+
http.Pusher
235+
}{t, cn, pu}
236+
case !i0 && i1 && i2 && !i3 && i4:
237+
return struct {
238+
http.ResponseWriter
239+
http.CloseNotifier
240+
http.Pusher
241+
io.ReaderFrom
242+
}{t, cn, pu, rf}
243+
case !i0 && i1 && i2 && i3 && !i4:
244+
return struct {
245+
http.ResponseWriter
246+
http.CloseNotifier
247+
http.Pusher
248+
http.Flusher
249+
}{t, cn, pu, fl}
250+
case !i0 && i1 && i2 && i3 && i4:
251+
return struct {
252+
http.ResponseWriter
253+
http.CloseNotifier
254+
http.Pusher
255+
http.Flusher
256+
io.ReaderFrom
257+
}{t, cn, pu, fl, rf}
258+
case i0 && !i1 && !i2 && !i3 && !i4:
259+
return struct {
260+
http.ResponseWriter
261+
http.Hijacker
262+
}{t, hj}
263+
case i0 && !i1 && !i2 && !i3 && i4:
264+
return struct {
265+
http.ResponseWriter
266+
http.Hijacker
267+
io.ReaderFrom
268+
}{t, hj, rf}
269+
case i0 && !i1 && !i2 && i3 && !i4:
270+
return struct {
271+
http.ResponseWriter
272+
http.Hijacker
273+
http.Flusher
274+
}{t, hj, fl}
275+
case i0 && !i1 && !i2 && i3 && i4:
276+
return struct {
277+
http.ResponseWriter
278+
http.Hijacker
279+
http.Flusher
280+
io.ReaderFrom
281+
}{t, hj, fl, rf}
282+
case i0 && !i1 && i2 && !i3 && !i4:
283+
return struct {
284+
http.ResponseWriter
285+
http.Hijacker
286+
http.Pusher
287+
}{t, hj, pu}
288+
case i0 && !i1 && i2 && !i3 && i4:
289+
return struct {
290+
http.ResponseWriter
291+
http.Hijacker
292+
http.Pusher
293+
io.ReaderFrom
294+
}{t, hj, pu, rf}
295+
case i0 && !i1 && i2 && i3 && !i4:
296+
return struct {
297+
http.ResponseWriter
298+
http.Hijacker
299+
http.Pusher
300+
http.Flusher
301+
}{t, hj, pu, fl}
302+
case i0 && !i1 && i2 && i3 && i4:
303+
return struct {
304+
http.ResponseWriter
305+
http.Hijacker
306+
http.Pusher
307+
http.Flusher
308+
io.ReaderFrom
309+
}{t, hj, pu, fl, rf}
310+
case i0 && i1 && !i2 && !i3 && !i4:
311+
return struct {
312+
http.ResponseWriter
313+
http.Hijacker
314+
http.CloseNotifier
315+
}{t, hj, cn}
316+
case i0 && i1 && !i2 && !i3 && i4:
317+
return struct {
318+
http.ResponseWriter
319+
http.Hijacker
320+
http.CloseNotifier
321+
io.ReaderFrom
322+
}{t, hj, cn, rf}
323+
case i0 && i1 && !i2 && i3 && !i4:
324+
return struct {
325+
http.ResponseWriter
326+
http.Hijacker
327+
http.CloseNotifier
328+
http.Flusher
329+
}{t, hj, cn, fl}
330+
case i0 && i1 && !i2 && i3 && i4:
331+
return struct {
332+
http.ResponseWriter
333+
http.Hijacker
334+
http.CloseNotifier
335+
http.Flusher
336+
io.ReaderFrom
337+
}{t, hj, cn, fl, rf}
338+
case i0 && i1 && i2 && !i3 && !i4:
339+
return struct {
340+
http.ResponseWriter
341+
http.Hijacker
342+
http.CloseNotifier
343+
http.Pusher
344+
}{t, hj, cn, pu}
345+
case i0 && i1 && i2 && !i3 && i4:
346+
return struct {
347+
http.ResponseWriter
348+
http.Hijacker
349+
http.CloseNotifier
350+
http.Pusher
351+
io.ReaderFrom
352+
}{t, hj, cn, pu, rf}
353+
case i0 && i1 && i2 && i3 && !i4:
354+
return struct {
355+
http.ResponseWriter
356+
http.Hijacker
357+
http.CloseNotifier
358+
http.Pusher
359+
http.Flusher
360+
}{t, hj, cn, pu, fl}
361+
case i0 && i1 && i2 && i3 && i4:
362+
return struct {
363+
http.ResponseWriter
364+
http.Hijacker
365+
http.CloseNotifier
366+
http.Pusher
367+
http.Flusher
368+
io.ReaderFrom
369+
}{t, hj, cn, pu, fl, rf}
370+
default:
371+
return struct {
372+
http.ResponseWriter
373+
}{t}
374+
}
375+
}

0 commit comments

Comments
 (0)