wrap_generated_gteq_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  // PushFunc is part of the http.Pusher interface.
  35  type 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.
  40  type 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.
  66  func 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  
 350  type rw struct {
 351  	w http.ResponseWriter
 352  	h Hooks
 353  }
 354  
 355  func (w *rw) Unwrap() http.ResponseWriter {
 356  	return w.w
 357  }
 358  
 359  func (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  
 367  func (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  
 375  func (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  
 383  func (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  
 391  func (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  
 399  func (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  
 407  func (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  
 415  func (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  
 423  type 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.
 429  func 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  }
 437