6
6
"io"
7
7
"net"
8
8
"net/http"
9
+
10
+ "github.com/signalsciences/sigsci-module-golang/schema"
9
11
)
10
12
11
13
// ResponseWriter is a http.ResponseWriter allowing extraction of data needed for inspection
@@ -24,12 +26,17 @@ type ResponseWriterFlusher interface {
24
26
25
27
// NewResponseWriter returns a ResponseWriter or ResponseWriterFlusher depending on the base http.ResponseWriter.
26
28
func NewResponseWriter (base http.ResponseWriter ) ResponseWriter {
29
+ return newResponseWriter (base , nil )
30
+ }
31
+
32
+ func newResponseWriter (base http.ResponseWriter , actions []schema.Action ) ResponseWriter {
27
33
// NOTE: according to net/http docs, if WriteHeader is not called explicitly,
28
34
// the first call to Write will trigger an implicit WriteHeader(http.StatusOK).
29
35
// this is why the default code is 200 and it only changes if WriteHeader is called.
30
36
w := & responseRecorder {
31
- base : base ,
32
- code : 200 ,
37
+ base : base ,
38
+ code : 200 ,
39
+ actions : actions ,
33
40
}
34
41
if _ , ok := w .base .(http.Flusher ); ok {
35
42
return & responseRecorderFlusher {w }
@@ -39,9 +46,10 @@ func NewResponseWriter(base http.ResponseWriter) ResponseWriter {
39
46
40
47
// responseRecorder wraps a base http.ResponseWriter allowing extraction of additional inspection data
41
48
type responseRecorder struct {
42
- base http.ResponseWriter
43
- code int
44
- size int64
49
+ base http.ResponseWriter
50
+ code int
51
+ size int64
52
+ actions []schema.Action
45
53
}
46
54
47
55
// BaseResponseWriter returns the base http.ResponseWriter allowing access if needed
@@ -66,12 +74,37 @@ func (w *responseRecorder) Header() http.Header {
66
74
67
75
// WriteHeader writes the header, recording the status code for inspection
68
76
func (w * responseRecorder ) WriteHeader (status int ) {
77
+ if w .actions != nil {
78
+ w .mergeHeader ()
79
+ }
69
80
w .code = status
70
81
w .base .WriteHeader (status )
71
82
}
72
83
84
+ func (w * responseRecorder ) mergeHeader () {
85
+ hdr := w .base .Header ()
86
+ for _ , a := range w .actions {
87
+ switch a .Code {
88
+ case schema .AddHdr :
89
+ hdr .Add (a .Args [0 ], a .Args [1 ])
90
+ case schema .SetHdr :
91
+ hdr .Set (a .Args [0 ], a .Args [1 ])
92
+ case schema .SetNEHdr :
93
+ if len (hdr .Get (a .Args [0 ])) == 0 {
94
+ hdr .Set (a .Args [0 ], a .Args [1 ])
95
+ }
96
+ case schema .DelHdr :
97
+ hdr .Del (a .Args [0 ])
98
+ }
99
+ }
100
+ w .actions = nil
101
+ }
102
+
73
103
// Write writes data, tracking the length written for inspection
74
104
func (w * responseRecorder ) Write (b []byte ) (int , error ) {
105
+ if w .actions != nil {
106
+ w .mergeHeader ()
107
+ }
75
108
w .size += int64 (len (b ))
76
109
return w .base .Write (b )
77
110
}
0 commit comments