wrap_generated_lt_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// Hooks defines a set of method interceptors for methods included in
 35// http.ResponseWriter as well as some others. You can think of them as
 36// middleware for the function calls they target. See Wrap for more details.
 37type Hooks struct {
 38	Header      func(HeaderFunc) HeaderFunc
 39	WriteHeader func(WriteHeaderFunc) WriteHeaderFunc
 40	Write       func(WriteFunc) WriteFunc
 41	Flush       func(FlushFunc) FlushFunc
 42	CloseNotify func(CloseNotifyFunc) CloseNotifyFunc
 43	Hijack      func(HijackFunc) HijackFunc
 44	ReadFrom    func(ReadFromFunc) ReadFromFunc
 45}
 46
 47// Wrap returns a wrapped version of w that provides the exact same interface
 48// as w. Specifically if w implements any combination of:
 49//
 50// - http.Flusher
 51// - http.CloseNotifier
 52// - http.Hijacker
 53// - io.ReaderFrom
 54//
 55// The wrapped version will implement the exact same combination. If no hooks
 56// are set, the wrapped version also behaves exactly as w. Hooks targeting
 57// methods not supported by w are ignored. Any other hooks will intercept the
 58// method they target and may modify the call's arguments and/or return values.
 59// The CaptureMetrics implementation serves as a working example for how the
 60// hooks can be used.
 61func Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter {
 62	rw := &rw{w: w, h: hooks}
 63	_, i0 := w.(http.Flusher)
 64	_, i1 := w.(http.CloseNotifier)
 65	_, i2 := w.(http.Hijacker)
 66	_, i3 := w.(io.ReaderFrom)
 67	switch {
 68	// combination 1/16
 69	case !i0 && !i1 && !i2 && !i3:
 70		return struct {
 71			Unwrapper
 72			http.ResponseWriter
 73		}{rw, rw}
 74	// combination 2/16
 75	case !i0 && !i1 && !i2 && i3:
 76		return struct {
 77			Unwrapper
 78			http.ResponseWriter
 79			io.ReaderFrom
 80		}{rw, rw, rw}
 81	// combination 3/16
 82	case !i0 && !i1 && i2 && !i3:
 83		return struct {
 84			Unwrapper
 85			http.ResponseWriter
 86			http.Hijacker
 87		}{rw, rw, rw}
 88	// combination 4/16
 89	case !i0 && !i1 && i2 && i3:
 90		return struct {
 91			Unwrapper
 92			http.ResponseWriter
 93			http.Hijacker
 94			io.ReaderFrom
 95		}{rw, rw, rw, rw}
 96	// combination 5/16
 97	case !i0 && i1 && !i2 && !i3:
 98		return struct {
 99			Unwrapper
100			http.ResponseWriter
101			http.CloseNotifier
102		}{rw, rw, rw}
103	// combination 6/16
104	case !i0 && i1 && !i2 && i3:
105		return struct {
106			Unwrapper
107			http.ResponseWriter
108			http.CloseNotifier
109			io.ReaderFrom
110		}{rw, rw, rw, rw}
111	// combination 7/16
112	case !i0 && i1 && i2 && !i3:
113		return struct {
114			Unwrapper
115			http.ResponseWriter
116			http.CloseNotifier
117			http.Hijacker
118		}{rw, rw, rw, rw}
119	// combination 8/16
120	case !i0 && i1 && i2 && i3:
121		return struct {
122			Unwrapper
123			http.ResponseWriter
124			http.CloseNotifier
125			http.Hijacker
126			io.ReaderFrom
127		}{rw, rw, rw, rw, rw}
128	// combination 9/16
129	case i0 && !i1 && !i2 && !i3:
130		return struct {
131			Unwrapper
132			http.ResponseWriter
133			http.Flusher
134		}{rw, rw, rw}
135	// combination 10/16
136	case i0 && !i1 && !i2 && i3:
137		return struct {
138			Unwrapper
139			http.ResponseWriter
140			http.Flusher
141			io.ReaderFrom
142		}{rw, rw, rw, rw}
143	// combination 11/16
144	case i0 && !i1 && i2 && !i3:
145		return struct {
146			Unwrapper
147			http.ResponseWriter
148			http.Flusher
149			http.Hijacker
150		}{rw, rw, rw, rw}
151	// combination 12/16
152	case i0 && !i1 && i2 && i3:
153		return struct {
154			Unwrapper
155			http.ResponseWriter
156			http.Flusher
157			http.Hijacker
158			io.ReaderFrom
159		}{rw, rw, rw, rw, rw}
160	// combination 13/16
161	case i0 && i1 && !i2 && !i3:
162		return struct {
163			Unwrapper
164			http.ResponseWriter
165			http.Flusher
166			http.CloseNotifier
167		}{rw, rw, rw, rw}
168	// combination 14/16
169	case i0 && i1 && !i2 && i3:
170		return struct {
171			Unwrapper
172			http.ResponseWriter
173			http.Flusher
174			http.CloseNotifier
175			io.ReaderFrom
176		}{rw, rw, rw, rw, rw}
177	// combination 15/16
178	case i0 && i1 && i2 && !i3:
179		return struct {
180			Unwrapper
181			http.ResponseWriter
182			http.Flusher
183			http.CloseNotifier
184			http.Hijacker
185		}{rw, rw, rw, rw, rw}
186	// combination 16/16
187	case i0 && i1 && i2 && i3:
188		return struct {
189			Unwrapper
190			http.ResponseWriter
191			http.Flusher
192			http.CloseNotifier
193			http.Hijacker
194			io.ReaderFrom
195		}{rw, rw, rw, rw, rw, rw}
196	}
197	panic("unreachable")
198}
199
200type rw struct {
201	w http.ResponseWriter
202	h Hooks
203}
204
205func (w *rw) Unwrap() http.ResponseWriter {
206	return w.w
207}
208
209func (w *rw) Header() http.Header {
210	f := w.w.(http.ResponseWriter).Header
211	if w.h.Header != nil {
212		f = w.h.Header(f)
213	}
214	return f()
215}
216
217func (w *rw) WriteHeader(code int) {
218	f := w.w.(http.ResponseWriter).WriteHeader
219	if w.h.WriteHeader != nil {
220		f = w.h.WriteHeader(f)
221	}
222	f(code)
223}
224
225func (w *rw) Write(b []byte) (int, error) {
226	f := w.w.(http.ResponseWriter).Write
227	if w.h.Write != nil {
228		f = w.h.Write(f)
229	}
230	return f(b)
231}
232
233func (w *rw) Flush() {
234	f := w.w.(http.Flusher).Flush
235	if w.h.Flush != nil {
236		f = w.h.Flush(f)
237	}
238	f()
239}
240
241func (w *rw) CloseNotify() <-chan bool {
242	f := w.w.(http.CloseNotifier).CloseNotify
243	if w.h.CloseNotify != nil {
244		f = w.h.CloseNotify(f)
245	}
246	return f()
247}
248
249func (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) {
250	f := w.w.(http.Hijacker).Hijack
251	if w.h.Hijack != nil {
252		f = w.h.Hijack(f)
253	}
254	return f()
255}
256
257func (w *rw) ReadFrom(src io.Reader) (int64, error) {
258	f := w.w.(io.ReaderFrom).ReadFrom
259	if w.h.ReadFrom != nil {
260		f = w.h.ReadFrom(f)
261	}
262	return f(src)
263}
264
265type Unwrapper interface {
266	Unwrap() http.ResponseWriter
267}
268
269// Unwrap returns the underlying http.ResponseWriter from within zero or more
270// layers of httpsnoop wrappers.
271func Unwrap(w http.ResponseWriter) http.ResponseWriter {
272	if rw, ok := w.(Unwrapper); ok {
273		// recurse until rw.Unwrap() returns a non-Unwrapper
274		return Unwrap(rw.Unwrap())
275	} else {
276		return w
277	}
278}