wrap_generated_lt_1.8.go raw

   1  // +build !go1.8
   2  // Code generated by "httpsnoop/codegen"; DO NOT EDIT.
   3  
   4  package httpsnoop
   5  
   6  import (
   7  	"bufio"
   8  	"io"
   9  	"net"
  10  	"net/http"
  11  )
  12  
  13  // HeaderFunc is part of the http.ResponseWriter interface.
  14  type HeaderFunc func() http.Header
  15  
  16  // WriteHeaderFunc is part of the http.ResponseWriter interface.
  17  type WriteHeaderFunc func(code int)
  18  
  19  // WriteFunc is part of the http.ResponseWriter interface.
  20  type WriteFunc func(b []byte) (int, error)
  21  
  22  // FlushFunc is part of the http.Flusher interface.
  23  type FlushFunc func()
  24  
  25  // CloseNotifyFunc is part of the http.CloseNotifier interface.
  26  type CloseNotifyFunc func() <-chan bool
  27  
  28  // HijackFunc is part of the http.Hijacker interface.
  29  type HijackFunc func() (net.Conn, *bufio.ReadWriter, error)
  30  
  31  // ReadFromFunc is part of the io.ReaderFrom interface.
  32  type 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.
  37  type 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.
  61  func 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  
 200  type rw struct {
 201  	w http.ResponseWriter
 202  	h Hooks
 203  }
 204  
 205  func (w *rw) Unwrap() http.ResponseWriter {
 206  	return w.w
 207  }
 208  
 209  func (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  
 217  func (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  
 225  func (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  
 233  func (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  
 241  func (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  
 249  func (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  
 257  func (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  
 265  type 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.
 271  func 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  }
 279