66	"io" 
77	"net" 
88	"net/http" 
9+ 
10+ 	"github.com/signalsciences/sigsci-module-golang/schema" 
911)
1012
1113// ResponseWriter is a http.ResponseWriter allowing extraction of data needed for inspection 
@@ -24,12 +26,17 @@ type ResponseWriterFlusher interface {
2426
2527// NewResponseWriter returns a ResponseWriter or ResponseWriterFlusher depending on the base http.ResponseWriter. 
2628func  NewResponseWriter (base  http.ResponseWriter ) ResponseWriter  {
29+ 	return  newResponseWriter (base , nil )
30+ }
31+ 
32+ func  newResponseWriter (base  http.ResponseWriter , actions  []schema.Action ) ResponseWriter  {
2733	// NOTE: according to net/http docs, if WriteHeader is not called explicitly, 
2834	// the first call to Write will trigger an implicit WriteHeader(http.StatusOK). 
2935	// this is why the default code is 200 and it only changes if WriteHeader is called. 
3036	w  :=  & responseRecorder {
31- 		base : base ,
32- 		code : 200 ,
37+ 		base :    base ,
38+ 		code :    200 ,
39+ 		actions : actions ,
3340	}
3441	if  _ , ok  :=  w .base .(http.Flusher ); ok  {
3542		return  & responseRecorderFlusher {w }
@@ -39,9 +46,10 @@ func NewResponseWriter(base http.ResponseWriter) ResponseWriter {
3946
4047// responseRecorder wraps a base http.ResponseWriter allowing extraction of additional inspection data 
4148type  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 
4553}
4654
4755// BaseResponseWriter returns the base http.ResponseWriter allowing access if needed 
@@ -66,12 +74,37 @@ func (w *responseRecorder) Header() http.Header {
6674
6775// WriteHeader writes the header, recording the status code for inspection 
6876func  (w  * responseRecorder ) WriteHeader (status  int ) {
77+ 	if  w .actions  !=  nil  {
78+ 		w .mergeHeader ()
79+ 	}
6980	w .code  =  status 
7081	w .base .WriteHeader (status )
7182}
7283
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+ 
73103// Write writes data, tracking the length written for inspection 
74104func  (w  * responseRecorder ) Write (b  []byte ) (int , error ) {
105+ 	if  w .actions  !=  nil  {
106+ 		w .mergeHeader ()
107+ 	}
75108	w .size  +=  int64 (len (b ))
76109	return  w .base .Write (b )
77110}
0 commit comments