-
Notifications
You must be signed in to change notification settings - Fork 1
/
tee.go
79 lines (68 loc) · 2.46 KB
/
tee.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package main
// This file is stolen from:
// https://github.com/rcrowley/go-tigertonic/blob/master/tee.go
import (
"bytes"
"net/http"
)
// TeeHeaderResponseWriter is an http.ResponseWriter that both writes and
// records the response status and headers for post-processing.
type TeeHeaderResponseWriter struct {
http.Flusher
http.ResponseWriter
StatusCode int
}
// NewTeeHeaderResponseWriter constructs a new TeeHeaderResponseWriter that
// writes responses through another http.ResponseWriter and records the
// response status and headers for post-processing.
func NewTeeHeaderResponseWriter(w http.ResponseWriter) *TeeHeaderResponseWriter {
return &TeeHeaderResponseWriter{ResponseWriter: w}
}
// Flush implements the http.Flusher interface, if possible, to support streaming
// responses to clients.
func (w *TeeHeaderResponseWriter) Flush() {
if f, ok := w.ResponseWriter.(http.Flusher); ok {
f.Flush()
}
}
// WriteHeader writes the response line and headers to the client via the
// underlying http.ResponseWriter and records the status for post-processing.
func (w *TeeHeaderResponseWriter) WriteHeader(code int) {
w.ResponseWriter.WriteHeader(code)
w.StatusCode = code
}
// TeeResponseWriter is an http.ResponseWriter that both writes and records the
// response status, headers, and body for post-processing.
type TeeResponseWriter struct {
http.Flusher
http.ResponseWriter
Body bytes.Buffer
StatusCode int
}
// NewTeeResponseWriter constructs a new TeeResponseWriter that writes
// responses through another http.ResponseWriter and records the response
// status, headers, and body for post-processing.
func NewTeeResponseWriter(w http.ResponseWriter) *TeeResponseWriter {
return &TeeResponseWriter{ResponseWriter: w}
}
// Flush implements the http.Flusher interface, if possible, to support streaming
// responses to clients.
func (w *TeeResponseWriter) Flush() {
if f, ok := w.ResponseWriter.(http.Flusher); ok {
f.Flush()
}
}
// Write writes the byte slice to the client via the underlying
// http.ResponseWriter and records it for post-processing.
func (w *TeeResponseWriter) Write(p []byte) (int, error) {
if n, err := w.ResponseWriter.Write(p); nil != err {
return n, err
}
return w.Body.Write(p)
}
// WriteHeader writes the response line and headers to the client via the
// underlying http.ResponseWriter and records the status for post-processing.
func (w *TeeResponseWriter) WriteHeader(code int) {
w.ResponseWriter.WriteHeader(code)
w.StatusCode = code
}