wrap_generated_lt_1.8.go 6.2 KB

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