@@ -33,6 +33,7 @@ import (
3333
3434type RecordingHTTPSProxy struct {
3535 prevRequestSHA string
36+ seenFiles map [string ]struct {}
3637 config * config.EndpointConfig
3738 recordingDir string
3839 redactor * redact.Redact
@@ -41,6 +42,7 @@ type RecordingHTTPSProxy struct {
4142func NewRecordingHTTPSProxy (cfg * config.EndpointConfig , recordingDir string , redactor * redact.Redact ) * RecordingHTTPSProxy {
4243 return & RecordingHTTPSProxy {
4344 prevRequestSHA : store .HeadSHA ,
45+ seenFiles : make (map [string ]struct {}),
4446 config : cfg ,
4547 recordingDir : recordingDir ,
4648 redactor : redactor ,
@@ -70,7 +72,7 @@ func (r *RecordingHTTPSProxy) handleRequest(w http.ResponseWriter, req *http.Req
7072 }
7173 fmt .Printf ("Recording request: %s %s\n " , req .Method , req .URL .String ())
7274
73- recReq , err := r .recordRequest (req )
75+ recReq , err := r .redactRequest (req )
7476 if err != nil {
7577 fmt .Printf ("Error recording request: %v\n " , err )
7678 http .Error (w , fmt .Sprintf ("Error recording request: %v" , err ), http .StatusInternalServerError )
@@ -82,6 +84,10 @@ func (r *RecordingHTTPSProxy) handleRequest(w http.ResponseWriter, req *http.Req
8284 http .Error (w , fmt .Sprintf ("Invalid recording file name: %v" , err ), http .StatusInternalServerError )
8385 return
8486 }
87+ if _ , ok := r .seenFiles [fileName ]; ! ok {
88+ // Reset to HeadSHA when first time seen a request from the given file.
89+ recReq .PreviousRequest = store .HeadSHA
90+ }
8591
8692 if req .Header .Get ("Upgrade" ) == "websocket" {
8793 fmt .Printf ("Upgrading connection to websocket...\n " )
@@ -95,17 +101,20 @@ func (r *RecordingHTTPSProxy) handleRequest(w http.ResponseWriter, req *http.Req
95101 http .Error (w , fmt .Sprintf ("Error proxying request: %v" , err ), http .StatusInternalServerError )
96102 return
97103 }
98-
99- err = r .recordResponse (resp , fileName , respBody )
100-
104+ shaSum := recReq .ComputeSum ()
105+ err = r .recordResponse (recReq , resp , fileName , shaSum , respBody )
101106 if err != nil {
102107 fmt .Printf ("Error recording response: %v\n " , err )
103108 http .Error (w , fmt .Sprintf ("Error recording response: %v" , err ), http .StatusInternalServerError )
104109 return
105110 }
111+ if (fileName != shaSum ) {
112+ r .prevRequestSHA = shaSum
113+ }
114+ r .seenFiles [fileName ] = struct {}{}
106115}
107116
108- func (r * RecordingHTTPSProxy ) recordRequest (req * http.Request ) (* store.RecordedRequest , error ) {
117+ func (r * RecordingHTTPSProxy ) redactRequest (req * http.Request ) (* store.RecordedRequest , error ) {
109118 recordedRequest , err := store .NewRecordedRequest (req , r .prevRequestSHA , * r .config )
110119 if err != nil {
111120 return recordedRequest , err
@@ -117,17 +126,6 @@ func (r *RecordingHTTPSProxy) recordRequest(req *http.Request) (*store.RecordedR
117126 r .redactor .Headers (recordedRequest .Header )
118127 recordedRequest .Request = r .redactor .String (recordedRequest .Request )
119128 recordedRequest .Body = r .redactor .Bytes (recordedRequest .Body )
120-
121- fileName , err := recordedRequest .GetRecordingFileName ()
122- if err != nil {
123- fmt .Printf ("Invalid recording file name: %v\n " , err )
124- return recordedRequest , err
125- }
126- recordPath := filepath .Join (r .recordingDir , fileName + ".req" )
127- err = os .WriteFile (recordPath , []byte (recordedRequest .Serialize ()), 0644 )
128- if err != nil {
129- return recordedRequest , err
130- }
131129 return recordedRequest , nil
132130}
133131
@@ -178,21 +176,47 @@ func (r *RecordingHTTPSProxy) proxyRequest(w http.ResponseWriter, req *http.Requ
178176 return resp , respBodyBytes , nil
179177}
180178
181- func (r * RecordingHTTPSProxy ) recordResponse (resp * http.Response , fileName string , body []byte ) error {
179+ func (r * RecordingHTTPSProxy ) recordResponse (recReq * store. RecordedRequest , resp * http.Response , fileName string , shaSum string , body []byte ) error {
182180 recordedResponse , err := store .NewRecordedResponse (resp , body )
183181 if err != nil {
184182 return err
185183 }
184+ recordPath := filepath .Join (r .recordingDir , fileName + ".http.log" )
186185
187- recordedResponse .Body = r .redactor .Bytes (recordedResponse .Body )
186+ // Default to overwriting the file, assuming it's a new file to record.
187+ fileMode := os .O_TRUNC
188+ // If we've seen requests with the same file name before, change the mode to append.
189+ if _ , ok := r .seenFiles [fileName ]; ok {
190+ fileMode = os .O_APPEND
191+ }
192+ file , err := os .OpenFile (recordPath , fileMode | os .O_CREATE | os .O_WRONLY , 0644 )
193+ if err != nil {
194+ return err
195+ }
196+ defer file .Close ()
188197
189- recordPath := filepath .Join (r .recordingDir , fileName + ".resp" )
190- fmt .Printf ("Writing response to: %s\n " , recordPath )
191- err = os .WriteFile (recordPath , []byte (recordedResponse .Serialize ()), 0644 )
198+ fmt .Printf ("Writing request to: %s\n " , recordPath )
199+ serializedReq := recReq .Serialize ()
200+ _ , err = file .WriteString (fmt .Sprintf ("%s.req %d\n " , shaSum , len (serializedReq )))
201+ if err != nil {
202+ return err
203+ }
204+ _ , err = file .WriteString (serializedReq )
192205 if err != nil {
193206 return err
194207 }
195208
209+ fmt .Printf ("Writing response to: %s\n " , recordPath )
210+ recordedResponse .Body = r .redactor .Bytes (recordedResponse .Body )
211+ serializedResp := recordedResponse .Serialize ()
212+ _ , err = file .WriteString (fmt .Sprintf ("\n %s.resp %d\n " , shaSum , len (serializedResp )))
213+ if err != nil {
214+ return err
215+ }
216+ _ , err = file .WriteString (serializedResp )
217+ if err != nil {
218+ return err
219+ }
196220 return nil
197221}
198222
@@ -230,7 +254,7 @@ func (r *RecordingHTTPSProxy) proxyWebsocket(w http.ResponseWriter, req *http.Re
230254 go pumpWebsocket (clientConn , conn , c , quit , ">" )
231255 go pumpWebsocket (conn , clientConn , c , quit , "<" )
232256
233- recordPath := filepath .Join (r .recordingDir , fileName + ".websocket" )
257+ recordPath := filepath .Join (r .recordingDir , fileName + ".websocket.log " )
234258 f , err := os .Create (recordPath )
235259 if err != nil {
236260 fmt .Printf ("Error creating websocket recording file: %v\n " , err )
0 commit comments