Skip to content

Commit

Permalink
fix http.Flusher and io.ReaderFrom implementation (#923)
Browse files Browse the repository at this point in the history

Co-authored-by: José Carlos Chávez <jcchavezs@gmail.com>
  • Loading branch information
romainmenke and jcchavezs authored Nov 21, 2023
1 parent 48cf923 commit a95ea5f
Show file tree
Hide file tree
Showing 2 changed files with 306 additions and 90 deletions.
114 changes: 24 additions & 90 deletions http/interceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,23 @@ func (i *rwInterceptor) Header() http.Header {
return i.w.Header()
}

var _ http.ResponseWriter = (*rwInterceptor)(nil)
func (i *rwInterceptor) ReadFrom(r io.Reader) (n int64, err error) {
return io.Copy(i, r)
}

func (i *rwInterceptor) Flush() {
if !i.wroteHeader {
i.WriteHeader(http.StatusOK)
}
}

type responseWriter interface {
http.ResponseWriter
io.ReaderFrom
http.Flusher
}

var _ responseWriter = (*rwInterceptor)(nil)

// wrap wraps the interceptor into a response writer that also preserves
// the http interfaces implemented by the original response writer to avoid
Expand Down Expand Up @@ -168,110 +184,28 @@ func wrap(w http.ResponseWriter, r *http.Request, tx types.Transaction) (
var (
hijacker, isHijacker = i.w.(http.Hijacker)
pusher, isPusher = i.w.(http.Pusher)
flusher, isFlusher = i.w.(http.Flusher)
reader, isReader = i.w.(io.ReaderFrom)
)

switch {
case !isHijacker && !isPusher && !isFlusher && !isReader:
case !isHijacker && isPusher:
return struct {
http.ResponseWriter
}{i}, responseProcessor
case !isHijacker && !isPusher && !isFlusher && isReader:
return struct {
http.ResponseWriter
io.ReaderFrom
}{i, reader}, responseProcessor
case !isHijacker && !isPusher && isFlusher && !isReader:
return struct {
http.ResponseWriter
http.Flusher
}{i, flusher}, responseProcessor
case !isHijacker && !isPusher && isFlusher && isReader:
return struct {
http.ResponseWriter
http.Flusher
io.ReaderFrom
}{i, flusher, reader}, responseProcessor
case !isHijacker && isPusher && !isFlusher && !isReader:
return struct {
http.ResponseWriter
responseWriter
http.Pusher
}{i, pusher}, responseProcessor
case !isHijacker && isPusher && !isFlusher && isReader:
return struct {
http.ResponseWriter
http.Pusher
io.ReaderFrom
}{i, pusher, reader}, responseProcessor
case !isHijacker && isPusher && isFlusher && !isReader:
return struct {
http.ResponseWriter
http.Pusher
http.Flusher
}{i, pusher, flusher}, responseProcessor
case !isHijacker && isPusher && isFlusher && isReader:
case isHijacker && !isPusher:
return struct {
http.ResponseWriter
http.Pusher
http.Flusher
io.ReaderFrom
}{i, pusher, flusher, reader}, responseProcessor
case isHijacker && !isPusher && !isFlusher && !isReader:
return struct {
http.ResponseWriter
responseWriter
http.Hijacker
}{i, hijacker}, responseProcessor
case isHijacker && !isPusher && !isFlusher && isReader:
case isHijacker && isPusher:
return struct {
http.ResponseWriter
http.Hijacker
io.ReaderFrom
}{i, hijacker, reader}, responseProcessor
case isHijacker && !isPusher && isFlusher && !isReader:
return struct {
http.ResponseWriter
http.Hijacker
http.Flusher
}{i, hijacker, flusher}, responseProcessor
case isHijacker && !isPusher && isFlusher && isReader:
return struct {
http.ResponseWriter
http.Hijacker
http.Flusher
io.ReaderFrom
}{i, hijacker, flusher, reader}, responseProcessor
case isHijacker && isPusher && !isFlusher && !isReader:
return struct {
http.ResponseWriter
responseWriter
http.Hijacker
http.Pusher
}{i, hijacker, pusher}, responseProcessor
case isHijacker && isPusher && !isFlusher && isReader:
return struct {
http.ResponseWriter
http.Hijacker
http.Pusher
io.ReaderFrom
}{i, hijacker, pusher, reader}, responseProcessor
case isHijacker && isPusher && isFlusher && !isReader:
return struct {
http.ResponseWriter
http.Hijacker
http.Pusher
http.Flusher
}{i, hijacker, pusher, flusher}, responseProcessor
case isHijacker && isPusher && isFlusher && isReader:
return struct {
http.ResponseWriter
http.Hijacker
http.Pusher
http.Flusher
io.ReaderFrom
}{i, hijacker, pusher, flusher, reader}, responseProcessor
default:
return struct {
http.ResponseWriter
responseWriter
}{i}, responseProcessor
}
}
Loading

0 comments on commit a95ea5f

Please sign in to comment.