// +build go1.8 package nethttp import ( "io" "net/http" ) type statusCodeTracker struct { http.ResponseWriter status int wroteheader bool } func (w *statusCodeTracker) WriteHeader(status int) { w.status = status w.wroteheader = true w.ResponseWriter.WriteHeader(status) } func (w *statusCodeTracker) Write(b []byte) (int, error) { if !w.wroteheader { w.wroteheader = true w.status = 200 } return w.ResponseWriter.Write(b) } // wrappedResponseWriter returns a wrapped version of the original // ResponseWriter and only implements the same combination of additional // interfaces as the original. This implementation is based on // https://github.com/felixge/httpsnoop. func (w *statusCodeTracker) wrappedResponseWriter() http.ResponseWriter { var ( hj, i0 = w.ResponseWriter.(http.Hijacker) cn, i1 = w.ResponseWriter.(http.CloseNotifier) pu, i2 = w.ResponseWriter.(http.Pusher) fl, i3 = w.ResponseWriter.(http.Flusher) rf, i4 = w.ResponseWriter.(io.ReaderFrom) ) switch { case !i0 && !i1 && !i2 && !i3 && !i4: return struct { http.ResponseWriter }{w} case !i0 && !i1 && !i2 && !i3 && i4: return struct { http.ResponseWriter io.ReaderFrom }{w, rf} case !i0 && !i1 && !i2 && i3 && !i4: return struct { http.ResponseWriter http.Flusher }{w, fl} case !i0 && !i1 && !i2 && i3 && i4: return struct { http.ResponseWriter http.Flusher io.ReaderFrom }{w, fl, rf} case !i0 && !i1 && i2 && !i3 && !i4: return struct { http.ResponseWriter http.Pusher }{w, pu} case !i0 && !i1 && i2 && !i3 && i4: return struct { http.ResponseWriter http.Pusher io.ReaderFrom }{w, pu, rf} case !i0 && !i1 && i2 && i3 && !i4: return struct { http.ResponseWriter http.Pusher http.Flusher }{w, pu, fl} case !i0 && !i1 && i2 && i3 && i4: return struct { http.ResponseWriter http.Pusher http.Flusher io.ReaderFrom }{w, pu, fl, rf} case !i0 && i1 && !i2 && !i3 && !i4: return struct { http.ResponseWriter http.CloseNotifier }{w, cn} case !i0 && i1 && !i2 && !i3 && i4: return struct { http.ResponseWriter http.CloseNotifier io.ReaderFrom }{w, cn, rf} case !i0 && i1 && !i2 && i3 && !i4: return struct { http.ResponseWriter http.CloseNotifier http.Flusher }{w, cn, fl} case !i0 && i1 && !i2 && i3 && i4: return struct { http.ResponseWriter http.CloseNotifier http.Flusher io.ReaderFrom }{w, cn, fl, rf} case !i0 && i1 && i2 && !i3 && !i4: return struct { http.ResponseWriter http.CloseNotifier http.Pusher }{w, cn, pu} case !i0 && i1 && i2 && !i3 && i4: return struct { http.ResponseWriter http.CloseNotifier http.Pusher io.ReaderFrom }{w, cn, pu, rf} case !i0 && i1 && i2 && i3 && !i4: return struct { http.ResponseWriter http.CloseNotifier http.Pusher http.Flusher }{w, cn, pu, fl} case !i0 && i1 && i2 && i3 && i4: return struct { http.ResponseWriter http.CloseNotifier http.Pusher http.Flusher io.ReaderFrom }{w, cn, pu, fl, rf} case i0 && !i1 && !i2 && !i3 && !i4: return struct { http.ResponseWriter http.Hijacker }{w, hj} case i0 && !i1 && !i2 && !i3 && i4: return struct { http.ResponseWriter http.Hijacker io.ReaderFrom }{w, hj, rf} case i0 && !i1 && !i2 && i3 && !i4: return struct { http.ResponseWriter http.Hijacker http.Flusher }{w, hj, fl} case i0 && !i1 && !i2 && i3 && i4: return struct { http.ResponseWriter http.Hijacker http.Flusher io.ReaderFrom }{w, hj, fl, rf} case i0 && !i1 && i2 && !i3 && !i4: return struct { http.ResponseWriter http.Hijacker http.Pusher }{w, hj, pu} case i0 && !i1 && i2 && !i3 && i4: return struct { http.ResponseWriter http.Hijacker http.Pusher io.ReaderFrom }{w, hj, pu, rf} case i0 && !i1 && i2 && i3 && !i4: return struct { http.ResponseWriter http.Hijacker http.Pusher http.Flusher }{w, hj, pu, fl} case i0 && !i1 && i2 && i3 && i4: return struct { http.ResponseWriter http.Hijacker http.Pusher http.Flusher io.ReaderFrom }{w, hj, pu, fl, rf} case i0 && i1 && !i2 && !i3 && !i4: return struct { http.ResponseWriter http.Hijacker http.CloseNotifier }{w, hj, cn} case i0 && i1 && !i2 && !i3 && i4: return struct { http.ResponseWriter http.Hijacker http.CloseNotifier io.ReaderFrom }{w, hj, cn, rf} case i0 && i1 && !i2 && i3 && !i4: return struct { http.ResponseWriter http.Hijacker http.CloseNotifier http.Flusher }{w, hj, cn, fl} case i0 && i1 && !i2 && i3 && i4: return struct { http.ResponseWriter http.Hijacker http.CloseNotifier http.Flusher io.ReaderFrom }{w, hj, cn, fl, rf} case i0 && i1 && i2 && !i3 && !i4: return struct { http.ResponseWriter http.Hijacker http.CloseNotifier http.Pusher }{w, hj, cn, pu} case i0 && i1 && i2 && !i3 && i4: return struct { http.ResponseWriter http.Hijacker http.CloseNotifier http.Pusher io.ReaderFrom }{w, hj, cn, pu, rf} case i0 && i1 && i2 && i3 && !i4: return struct { http.ResponseWriter http.Hijacker http.CloseNotifier http.Pusher http.Flusher }{w, hj, cn, pu, fl} case i0 && i1 && i2 && i3 && i4: return struct { http.ResponseWriter http.Hijacker http.CloseNotifier http.Pusher http.Flusher io.ReaderFrom }{w, hj, cn, pu, fl, rf} default: return struct { http.ResponseWriter }{w} } }