Skip to content

Instantly share code, notes, and snippets.

@kulti
Last active June 1, 2022 06:52
Show Gist options
  • Save kulti/79ad30738aa2e6f5f1bfb13cb4522c5a to your computer and use it in GitHub Desktop.
Save kulti/79ad30738aa2e6f5f1bfb13cb4522c5a to your computer and use it in GitHub Desktop.
Wrap http.ResponseWriter with proxying another interfaces
func wrapResponseWriter(w http.ResponseWriter, codeHook func(int)) http.ResponseWriter {
rw := &rw{w: w, codeHook: codeHook}
hj, hasHijack := w.(http.Hijacker)
fl, hasFlusher := w.(http.Flusher)
rf, hasReadFrom := w.(io.ReaderFrom)
switch {
case hasHijack && hasFlusher && hasReadFrom:
return struct {
http.ResponseWriter
http.Hijacker
http.Flusher
io.ReaderFrom
}{rw, hj, fl, rf}
case hasHijack && hasFlusher:
return struct {
http.ResponseWriter
http.Hijacker
http.Flusher
}{rw, hj, fl}
case hasHijack && hasReadFrom:
return struct {
http.ResponseWriter
http.Hijacker
io.ReaderFrom
}{rw, hj, rf}
case hasFlusher && hasReadFrom:
return struct {
http.ResponseWriter
http.Flusher
io.ReaderFrom
}{rw, fl, rf}
case hasHijack:
return struct {
http.ResponseWriter
http.Hijacker
}{rw, hj}
case hasFlusher:
return struct {
http.ResponseWriter
http.Flusher
}{rw, fl}
case hasReadFrom:
return struct {
http.ResponseWriter
io.ReaderFrom
}{rw, rf}
default:
return struct {
http.ResponseWriter
}{rw}
}
}
type rw struct {
w http.ResponseWriter
codeHook func(int)
}
func (w *rw) Header() http.Header {
return w.w.Header()
}
func (w *rw) WriteHeader(code int) {
w.codeHook(code)
w.w.WriteHeader(code)
}
func (w *rw) Write(b []byte) (int, error) {
return w.w.Write(b)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment