wrap_generated_gteq_1.8.go

  1// +build go1.8
  2// Code generated by "httpsnoop/codegen"; DO NOT EDIT.
  3
  4package httpsnoop
  5
  6import (
  7	"bufio"
  8	"io"
  9	"net"
 10	"net/http"
 11)
 12
 13// HeaderFunc is part of the http.ResponseWriter interface.
 14type HeaderFunc func() http.Header
 15
 16// WriteHeaderFunc is part of the http.ResponseWriter interface.
 17type WriteHeaderFunc func(code int)
 18
 19// WriteFunc is part of the http.ResponseWriter interface.
 20type WriteFunc func(b []byte) (int, error)
 21
 22// FlushFunc is part of the http.Flusher interface.
 23type FlushFunc func()
 24
 25// CloseNotifyFunc is part of the http.CloseNotifier interface.
 26type CloseNotifyFunc func() <-chan bool
 27
 28// HijackFunc is part of the http.Hijacker interface.
 29type HijackFunc func() (net.Conn, *bufio.ReadWriter, error)
 30
 31// ReadFromFunc is part of the io.ReaderFrom interface.
 32type ReadFromFunc func(src io.Reader) (int64, error)
 33
 34// PushFunc is part of the http.Pusher interface.
 35type PushFunc func(target string, opts *http.PushOptions) error
 36
 37// Hooks defines a set of method interceptors for methods included in
 38// http.ResponseWriter as well as some others. You can think of them as
 39// middleware for the function calls they target. See Wrap for more details.
 40type Hooks struct {
 41	Header      func(HeaderFunc) HeaderFunc
 42	WriteHeader func(WriteHeaderFunc) WriteHeaderFunc
 43	Write       func(WriteFunc) WriteFunc
 44	Flush       func(FlushFunc) FlushFunc
 45	CloseNotify func(CloseNotifyFunc) CloseNotifyFunc
 46	Hijack      func(HijackFunc) HijackFunc
 47	ReadFrom    func(ReadFromFunc) ReadFromFunc
 48	Push        func(PushFunc) PushFunc
 49}
 50
 51// Wrap returns a wrapped version of w that provides the exact same interface
 52// as w. Specifically if w implements any combination of:
 53//
 54// - http.Flusher
 55// - http.CloseNotifier
 56// - http.Hijacker
 57// - io.ReaderFrom
 58// - http.Pusher
 59//
 60// The wrapped version will implement the exact same combination. If no hooks
 61// are set, the wrapped version also behaves exactly as w. Hooks targeting
 62// methods not supported by w are ignored. Any other hooks will intercept the
 63// method they target and may modify the call's arguments and/or return values.
 64// The CaptureMetrics implementation serves as a working example for how the
 65// hooks can be used.
 66func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter {
 67	rw := &rw{w: w, h: hooks}
 68	_, i0 := w.(http.Flusher)
 69	_, i1 := w.(http.CloseNotifier)
 70	_, i2 := w.(http.Hijacker)
 71	_, i3 := w.(io.ReaderFrom)
 72	_, i4 := w.(http.Pusher)
 73	switch {
 74	// combination 1/32
 75	case !i0 && !i1 && !i2 && !i3 && !i4:
 76		return struct {
 77			Unwrapper
 78			http.ResponseWriter
 79		}{rw, rw}
 80	// combination 2/32
 81	case !i0 && !i1 && !i2 && !i3 && i4:
 82		return struct {
 83			Unwrapper
 84			http.ResponseWriter
 85			http.Pusher
 86		}{rw, rw, rw}
 87	// combination 3/32
 88	case !i0 && !i1 && !i2 && i3 && !i4:
 89		return struct {
 90			Unwrapper
 91			http.ResponseWriter
 92			io.ReaderFrom
 93		}{rw, rw, rw}
 94	// combination 4/32
 95	case !i0 && !i1 && !i2 && i3 && i4:
 96		return struct {
 97			Unwrapper
 98			http.ResponseWriter
 99			io.ReaderFrom
100			http.Pusher
101		}{rw, rw, rw, rw}
102	// combination 5/32
103	case !i0 && !i1 && i2 && !i3 && !i4:
104		return struct {
105			Unwrapper
106			http.ResponseWriter
107			http.Hijacker
108		}{rw, rw, rw}
109	// combination 6/32
110	case !i0 && !i1 && i2 && !i3 && i4:
111		return struct {
112			Unwrapper
113			http.ResponseWriter
114			http.Hijacker
115			http.Pusher
116		}{rw, rw, rw, rw}
117	// combination 7/32
118	case !i0 && !i1 && i2 && i3 && !i4:
119		return struct {
120			Unwrapper
121			http.ResponseWriter
122			http.Hijacker
123			io.ReaderFrom
124		}{rw, rw, rw, rw}
125	// combination 8/32
126	case !i0 && !i1 && i2 && i3 && i4:
127		return struct {
128			Unwrapper
129			http.ResponseWriter
130			http.Hijacker
131			io.ReaderFrom
132			http.Pusher
133		}{rw, rw, rw, rw, rw}
134	// combination 9/32
135	case !i0 && i1 && !i2 && !i3 && !i4:
136		return struct {
137			Unwrapper
138			http.ResponseWriter
139			http.CloseNotifier
140		}{rw, rw, rw}
141	// combination 10/32
142	case !i0 && i1 && !i2 && !i3 && i4:
143		return struct {
144			Unwrapper
145			http.ResponseWriter
146			http.CloseNotifier
147			http.Pusher
148		}{rw, rw, rw, rw}
149	// combination 11/32
150	case !i0 && i1 && !i2 && i3 && !i4:
151		return struct {
152			Unwrapper
153			http.ResponseWriter
154			http.CloseNotifier
155			io.ReaderFrom
156		}{rw, rw, rw, rw}
157	// combination 12/32
158	case !i0 && i1 && !i2 && i3 && i4:
159		return struct {
160			Unwrapper
161			http.ResponseWriter
162			http.CloseNotifier
163			io.ReaderFrom
164			http.Pusher
165		}{rw, rw, rw, rw, rw}
166	// combination 13/32
167	case !i0 && i1 && i2 && !i3 && !i4:
168		return struct {
169			Unwrapper
170			http.ResponseWriter
171			http.CloseNotifier
172			http.Hijacker
173		}{rw, rw, rw, rw}
174	// combination 14/32
175	case !i0 && i1 && i2 && !i3 && i4:
176		return struct {
177			Unwrapper
178			http.ResponseWriter
179			http.CloseNotifier
180			http.Hijacker
181			http.Pusher
182		}{rw, rw, rw, rw, rw}
183	// combination 15/32
184	case !i0 && i1 && i2 && i3 && !i4:
185		return struct {
186			Unwrapper
187			http.ResponseWriter
188			http.CloseNotifier
189			http.Hijacker
190			io.ReaderFrom
191		}{rw, rw, rw, rw, rw}
192	// combination 16/32
193	case !i0 && i1 && i2 && i3 && i4:
194		return struct {
195			Unwrapper
196			http.ResponseWriter
197			http.CloseNotifier
198			http.Hijacker
199			io.ReaderFrom
200			http.Pusher
201		}{rw, rw, rw, rw, rw, rw}
202	// combination 17/32
203	case i0 && !i1 && !i2 && !i3 && !i4:
204		return struct {
205			Unwrapper
206			http.ResponseWriter
207			http.Flusher
208		}{rw, rw, rw}
209	// combination 18/32
210	case i0 && !i1 && !i2 && !i3 && i4:
211		return struct {
212			Unwrapper
213			http.ResponseWriter
214			http.Flusher
215			http.Pusher
216		}{rw, rw, rw, rw}
217	// combination 19/32
218	case i0 && !i1 && !i2 && i3 && !i4:
219		return struct {
220			Unwrapper
221			http.ResponseWriter
222			http.Flusher
223			io.ReaderFrom
224		}{rw, rw, rw, rw}
225	// combination 20/32
226	case i0 && !i1 && !i2 && i3 && i4:
227		return struct {
228			Unwrapper
229			http.ResponseWriter
230			http.Flusher
231			io.ReaderFrom
232			http.Pusher
233		}{rw, rw, rw, rw, rw}
234	// combination 21/32
235	case i0 && !i1 && i2 && !i3 && !i4:
236		return struct {
237			Unwrapper
238			http.ResponseWriter
239			http.Flusher
240			http.Hijacker
241		}{rw, rw, rw, rw}
242	// combination 22/32
243	case i0 && !i1 && i2 && !i3 && i4:
244		return struct {
245			Unwrapper
246			http.ResponseWriter
247			http.Flusher
248			http.Hijacker
249			http.Pusher
250		}{rw, rw, rw, rw, rw}
251	// combination 23/32
252	case i0 && !i1 && i2 && i3 && !i4:
253		return struct {
254			Unwrapper
255			http.ResponseWriter
256			http.Flusher
257			http.Hijacker
258			io.ReaderFrom
259		}{rw, rw, rw, rw, rw}
260	// combination 24/32
261	case i0 && !i1 && i2 && i3 && i4:
262		return struct {
263			Unwrapper
264			http.ResponseWriter
265			http.Flusher
266			http.Hijacker
267			io.ReaderFrom
268			http.Pusher
269		}{rw, rw, rw, rw, rw, rw}
270	// combination 25/32
271	case i0 && i1 && !i2 && !i3 && !i4:
272		return struct {
273			Unwrapper
274			http.ResponseWriter
275			http.Flusher
276			http.CloseNotifier
277		}{rw, rw, rw, rw}
278	// combination 26/32
279	case i0 && i1 && !i2 && !i3 && i4:
280		return struct {
281			Unwrapper
282			http.ResponseWriter
283			http.Flusher
284			http.CloseNotifier
285			http.Pusher
286		}{rw, rw, rw, rw, rw}
287	// combination 27/32
288	case i0 && i1 && !i2 && i3 && !i4:
289		return struct {
290			Unwrapper
291			http.ResponseWriter
292			http.Flusher
293			http.CloseNotifier
294			io.ReaderFrom
295		}{rw, rw, rw, rw, rw}
296	// combination 28/32
297	case i0 && i1 && !i2 && i3 && i4:
298		return struct {
299			Unwrapper
300			http.ResponseWriter
301			http.Flusher
302			http.CloseNotifier
303			io.ReaderFrom
304			http.Pusher
305		}{rw, rw, rw, rw, rw, rw}
306	// combination 29/32
307	case i0 && i1 && i2 && !i3 && !i4:
308		return struct {
309			Unwrapper
310			http.ResponseWriter
311			http.Flusher
312			http.CloseNotifier
313			http.Hijacker
314		}{rw, rw, rw, rw, rw}
315	// combination 30/32
316	case i0 && i1 && i2 && !i3 && i4:
317		return struct {
318			Unwrapper
319			http.ResponseWriter
320			http.Flusher
321			http.CloseNotifier
322			http.Hijacker
323			http.Pusher
324		}{rw, rw, rw, rw, rw, rw}
325	// combination 31/32
326	case i0 && i1 && i2 && i3 && !i4:
327		return struct {
328			Unwrapper
329			http.ResponseWriter
330			http.Flusher
331			http.CloseNotifier
332			http.Hijacker
333			io.ReaderFrom
334		}{rw, rw, rw, rw, rw, rw}
335	// combination 32/32
336	case i0 && i1 && i2 && i3 && i4:
337		return struct {
338			Unwrapper
339			http.ResponseWriter
340			http.Flusher
341			http.CloseNotifier
342			http.Hijacker
343			io.ReaderFrom
344			http.Pusher
345		}{rw, rw, rw, rw, rw, rw, rw}
346	}
347	panic("unreachable")
348}
349
350type rw struct {
351	w http.ResponseWriter
352	h Hooks
353}
354
355func (w *rw) Unwrap() http.ResponseWriter {
356	return w.w
357}
358
359func (w *rw) Header() http.Header {
360	f := w.w.(http.ResponseWriter).Header
361	if w.h.Header != nil {
362		f = w.h.Header(f)
363	}
364	return f()
365}
366
367func (w *rw) WriteHeader(code int) {
368	f := w.w.(http.ResponseWriter).WriteHeader
369	if w.h.WriteHeader != nil {
370		f = w.h.WriteHeader(f)
371	}
372	f(code)
373}
374
375func (w *rw) Write(b []byte) (int, error) {
376	f := w.w.(http.ResponseWriter).Write
377	if w.h.Write != nil {
378		f = w.h.Write(f)
379	}
380	return f(b)
381}
382
383func (w *rw) Flush() {
384	f := w.w.(http.Flusher).Flush
385	if w.h.Flush != nil {
386		f = w.h.Flush(f)
387	}
388	f()
389}
390
391func (w *rw) CloseNotify() <-chan bool {
392	f := w.w.(http.CloseNotifier).CloseNotify
393	if w.h.CloseNotify != nil {
394		f = w.h.CloseNotify(f)
395	}
396	return f()
397}
398
399func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) {
400	f := w.w.(http.Hijacker).Hijack
401	if w.h.Hijack != nil {
402		f = w.h.Hijack(f)
403	}
404	return f()
405}
406
407func (w *rw) ReadFrom(src io.Reader) (int64, error) {
408	f := w.w.(io.ReaderFrom).ReadFrom
409	if w.h.ReadFrom != nil {
410		f = w.h.ReadFrom(f)
411	}
412	return f(src)
413}
414
415func (w *rw) Push(target string, opts *http.PushOptions) error {
416	f := w.w.(http.Pusher).Push
417	if w.h.Push != nil {
418		f = w.h.Push(f)
419	}
420	return f(target, opts)
421}
422
423type Unwrapper interface {
424	Unwrap() http.ResponseWriter
425}
426
427// Unwrap returns the underlying http.ResponseWriter from within zero or more
428// layers of httpsnoop wrappers.
429func Unwrap(w http.ResponseWriter) http.ResponseWriter {
430	if rw, ok := w.(Unwrapper); ok {
431		// recurse until rw.Unwrap() returns a non-Unwrapper
432		return Unwrap(rw.Unwrap())
433	} else {
434		return w
435	}
436}