Repository: go-kit/kit (go)

Issue:
Support for WebSockets in Server interface
net/http added support for websockets in v1.12 ([discussion](https://github.com/golang/go/issues/26937)). The change however requires applications to use an additional interface ([Hijacker](https://github.com/golang/go/blob/go1.12/src/net/http/server.go#L179)) to 'hijack' the connection and access the I/O channels. When applications use go-kit, the http.ResponseWriter is replaced by an interceptingWriter here: https://github.com/go-kit/kit/blob/v0.10.0/transport/http/server.go#L99. This only [embeds](https://github.com/go-kit/kit/blob/v0.10.0/transport/http/server.go#L228) the original `http.ResponseWriter`. To open up support for websockets, we needs to embed the Hijacker interface as well. 

Pull request:
feat(http): make interceptingWriter reimplement common interfaces
successor to #1093 and closes #1092.

Patch:
diff --git a/transport/http/intercepting_writer.go b/transport/http/intercepting_writer.go
new file mode 100644
index 0000000..3737b6e
--- /dev/null
+++ b/transport/http/intercepting_writer.go
@@ -0,0 +1,257 @@
+package http
+
+import (
+	"io"
+	"net/http"
+)
+
+type interceptingWriter struct {
+	http.ResponseWriter
+	code    int
+	written int64
+}
+
+// WriteHeader may not be explicitly called, so care must be taken to
+// initialize w.code to its default value of http.StatusOK.
+func (w *interceptingWriter) WriteHeader(code int) {
+	w.code = code
+	w.ResponseWriter.WriteHeader(code)
+}
+
+func (w *interceptingWriter) Write(p []byte) (int, error) {
+	n, err := w.ResponseWriter.Write(p)
+	w.written += int64(n)
+	return n, err
+}
+
+// reimplementInterfaces returns a wrapped version of the embedded ResponseWriter
+// and selectively implements the same combination of additional interfaces as
+// the wrapped one. The interfaces it may implement are: http.Hijacker,
+// http.CloseNotifier, http.Pusher, http.Flusher and io.ReaderFrom. The standard
+// library is known to assert the existence of these interfaces and behaves
+// differently. This implementation is derived from
+// https://github.com/felixge/httpsnoop.
+func (w *interceptingWriter) reimplementInterfaces() 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}
+	}
+}
diff --git a/transport/http/server.go b/transport/http/server.go
index dfd1ff3..ab87d4a 100644
--- a/transport/http/server.go
+++ b/transport/http/server.go
@@ -104,7 +104,7 @@ func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 				f(ctx, iw.code, r)
 			}
 		}()
-		w = iw
+		w = iw.reimplementInterfaces()
 	}
 
 	for _, f := range s.before {
@@ -223,22 +223,3 @@ type StatusCoder interface {
 type Headerer interface {
 	Headers() http.Header
 }
-
-type interceptingWriter struct {
-	http.ResponseWriter
-	code    int
-	written int64
-}
-
-// WriteHeader may not be explicitly called, so care must be taken to
-// initialize w.code to its default value of http.StatusOK.
-func (w *interceptingWriter) WriteHeader(code int) {
-	w.code = code
-	w.ResponseWriter.WriteHeader(code)
-}
-
-func (w *interceptingWriter) Write(p []byte) (int, error) {
-	n, err := w.ResponseWriter.Write(p)
-	w.written += int64(n)
-	return n, err
-}


Test patch:
diff --git a/transport/http/intercepting_writer_test.go b/transport/http/intercepting_writer_test.go
new file mode 100644
index 0000000..ad4a070
--- /dev/null
+++ b/transport/http/intercepting_writer_test.go
@@ -0,0 +1,1039 @@
+package http
+
+import (
+	"bufio"
+	"io"
+	"net"
+	"net/http"
+	"testing"
+)
+
+type versatileWriter struct {
+	http.ResponseWriter
+	closeNotifyCalled bool
+	hijackCalled      bool
+	readFromCalled    bool
+	pushCalled        bool
+	flushCalled       bool
+}
+
+func (v *versatileWriter) Flush() { v.flushCalled = true }
+func (v *versatileWriter) Push(target string, opts *http.PushOptions) error {
+	v.pushCalled = true
+	return nil
+}
+func (v *versatileWriter) ReadFrom(r io.Reader) (n int64, err error) {
+	v.readFromCalled = true
+	return 0, nil
+}
+func (v *versatileWriter) CloseNotify() <-chan bool { v.closeNotifyCalled = true; return nil }
+func (v *versatileWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
+	v.hijackCalled = true
+	return nil, nil, nil
+}
+
+func TestInterceptingWriter_passthroughs(t *testing.T) {
+	w := &versatileWriter{}
+	iw := (&interceptingWriter{ResponseWriter: w}).reimplementInterfaces()
+	iw.(http.Flusher).Flush()
+	iw.(http.Pusher).Push("", nil)
+	iw.(http.CloseNotifier).CloseNotify()
+	iw.(http.Hijacker).Hijack()
+	iw.(io.ReaderFrom).ReadFrom(nil)
+
+	if !w.flushCalled {
+		t.Error("Flush not called")
+	}
+	if !w.pushCalled {
+		t.Error("Push not called")
+	}
+	if !w.closeNotifyCalled {
+		t.Error("CloseNotify not called")
+	}
+	if !w.hijackCalled {
+		t.Error("Hijack not called")
+	}
+	if !w.readFromCalled {
+		t.Error("ReadFrom not called")
+	}
+}
+
+// TestInterceptingWriter_reimplementInterfaces is also derived from
+// https://github.com/felixge/httpsnoop, like interceptingWriter.
+func TestInterceptingWriter_reimplementInterfaces(t *testing.T) {
+	// combination 1/32
+	{
+		t.Log("http.ResponseWriter")
+		inner := struct {
+			http.ResponseWriter
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 2/32
+	{
+		t.Log("http.ResponseWriter, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 3/32
+	{
+		t.Log("http.ResponseWriter, io.ReaderFrom")
+		inner := struct {
+			http.ResponseWriter
+			io.ReaderFrom
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 4/32
+	{
+		t.Log("http.ResponseWriter, io.ReaderFrom, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			io.ReaderFrom
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 5/32
+	{
+		t.Log("http.ResponseWriter, http.Hijacker")
+		inner := struct {
+			http.ResponseWriter
+			http.Hijacker
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 6/32
+	{
+		t.Log("http.ResponseWriter, http.Hijacker, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Hijacker
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 7/32
+	{
+		t.Log("http.ResponseWriter, http.Hijacker, io.ReaderFrom")
+		inner := struct {
+			http.ResponseWriter
+			http.Hijacker
+			io.ReaderFrom
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 8/32
+	{
+		t.Log("http.ResponseWriter, http.Hijacker, io.ReaderFrom, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Hijacker
+			io.ReaderFrom
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 9/32
+	{
+		t.Log("http.ResponseWriter, http.CloseNotifier")
+		inner := struct {
+			http.ResponseWriter
+			http.CloseNotifier
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 10/32
+	{
+		t.Log("http.ResponseWriter, http.CloseNotifier, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.CloseNotifier
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 11/32
+	{
+		t.Log("http.ResponseWriter, http.CloseNotifier, io.ReaderFrom")
+		inner := struct {
+			http.ResponseWriter
+			http.CloseNotifier
+			io.ReaderFrom
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 12/32
+	{
+		t.Log("http.ResponseWriter, http.CloseNotifier, io.ReaderFrom, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.CloseNotifier
+			io.ReaderFrom
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 13/32
+	{
+		t.Log("http.ResponseWriter, http.CloseNotifier, http.Hijacker")
+		inner := struct {
+			http.ResponseWriter
+			http.CloseNotifier
+			http.Hijacker
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 14/32
+	{
+		t.Log("http.ResponseWriter, http.CloseNotifier, http.Hijacker, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.CloseNotifier
+			http.Hijacker
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 15/32
+	{
+		t.Log("http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom")
+		inner := struct {
+			http.ResponseWriter
+			http.CloseNotifier
+			http.Hijacker
+			io.ReaderFrom
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 16/32
+	{
+		t.Log("http.ResponseWriter, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.CloseNotifier
+			http.Hijacker
+			io.ReaderFrom
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 17/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 18/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 19/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, io.ReaderFrom")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			io.ReaderFrom
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 20/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, io.ReaderFrom, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			io.ReaderFrom
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 21/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.Hijacker")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.Hijacker
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 22/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.Hijacker, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.Hijacker
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 23/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.Hijacker
+			io.ReaderFrom
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 24/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.Hijacker, io.ReaderFrom, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.Hijacker
+			io.ReaderFrom
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 25/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.CloseNotifier")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.CloseNotifier
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 26/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.CloseNotifier
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 27/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.CloseNotifier
+			io.ReaderFrom
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 28/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.CloseNotifier, io.ReaderFrom, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.CloseNotifier
+			io.ReaderFrom
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 29/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.CloseNotifier
+			http.Hijacker
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 30/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.CloseNotifier
+			http.Hijacker
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != false {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 31/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.CloseNotifier
+			http.Hijacker
+			io.ReaderFrom
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != false {
+			t.Error("unexpected interface")
+		}
+
+	}
+
+	// combination 32/32
+	{
+		t.Log("http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker, io.ReaderFrom, http.Pusher")
+		inner := struct {
+			http.ResponseWriter
+			http.Flusher
+			http.CloseNotifier
+			http.Hijacker
+			io.ReaderFrom
+			http.Pusher
+		}{}
+		w := (&interceptingWriter{ResponseWriter: inner}).reimplementInterfaces()
+		if _, ok := w.(http.ResponseWriter); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Flusher); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.CloseNotifier); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Hijacker); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(io.ReaderFrom); ok != true {
+			t.Error("unexpected interface")
+		}
+		if _, ok := w.(http.Pusher); ok != true {
+			t.Error("unexpected interface")
+		}
+
+	}
+}