-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(http): make interceptingWriter reimplement common interfaces fro…
- Loading branch information
Showing
3 changed files
with
1,297 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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} | ||
} | ||
} |
Oops, something went wrong.