|
|
@ -45,7 +45,7 @@ func main() {
|
|
45
|
45
|
responses = rs
|
|
46
|
46
|
}
|
|
47
|
47
|
|
|
48
|
|
requestLog := make([]Request, 0)
|
|
|
48
|
requestLog := make([]LogEntry, 0)
|
|
49
|
49
|
|
|
50
|
50
|
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
|
|
51
|
51
|
var resp *http.Response
|
|
|
@ -83,13 +83,31 @@ func main() {
|
|
83
|
83
|
buf.Write(respOut)
|
|
84
|
84
|
buf.Write([]byte("\n"))
|
|
85
|
85
|
|
|
86
|
|
requestLog = append(requestLog, buf.Bytes())
|
|
|
86
|
requestLog = append(requestLog, LogEntry{
|
|
|
87
|
Request: out,
|
|
|
88
|
Response: asResponse(req, resp),
|
|
|
89
|
})
|
|
87
|
90
|
})
|
|
88
|
91
|
|
|
89
|
92
|
http.HandleFunc("/_log", func(w http.ResponseWriter, req *http.Request) {
|
|
|
93
|
if strings.Contains(req.Header.Get("Accept"), "application/yaml") {
|
|
|
94
|
rs := make([]Response, len(requestLog))
|
|
|
95
|
for i, log := range requestLog {
|
|
|
96
|
rs[i] = log.Response
|
|
|
97
|
}
|
|
|
98
|
err := renderYAML(w, rs)
|
|
|
99
|
if err != nil {
|
|
|
100
|
log.Printf("Error: Render log: %s", err)
|
|
|
101
|
}
|
|
|
102
|
return
|
|
|
103
|
}
|
|
|
104
|
|
|
90
|
105
|
for i := len(requestLog) - 1; i >= 0; i-- {
|
|
91
|
106
|
w.Write([]byte("------------------------------------------------------\n"))
|
|
92
|
|
w.Write(requestLog[i])
|
|
|
107
|
w.Write(requestLog[i].Request)
|
|
|
108
|
w.Write([]byte("\n\n"))
|
|
|
109
|
requestLog[i].Response.AsHTTP().Write(w)
|
|
|
110
|
w.Write([]byte("\n"))
|
|
93
|
111
|
}
|
|
94
|
112
|
})
|
|
95
|
113
|
|
|
|
@ -272,6 +290,12 @@ func renderHTML(w http.ResponseWriter, responses []Response) error {
|
|
272
|
290
|
return nil
|
|
273
|
291
|
}
|
|
274
|
292
|
|
|
|
293
|
// LogEntry is a request/respond pair for logging.
|
|
|
294
|
type LogEntry struct {
|
|
|
295
|
Request Request
|
|
|
296
|
Response Response
|
|
|
297
|
}
|
|
|
298
|
|
|
275
|
299
|
// Request is a stored serialized HTTP request.
|
|
276
|
300
|
type Request []byte
|
|
277
|
301
|
|
|
|
@ -316,6 +340,24 @@ func (resp Response) AsHTTP() *http.Response {
|
|
316
|
340
|
}
|
|
317
|
341
|
}
|
|
318
|
342
|
|
|
|
343
|
func asResponse(req *http.Request, resp *http.Response) Response {
|
|
|
344
|
headers := make([]Header, 0)
|
|
|
345
|
for name, vals := range resp.Header {
|
|
|
346
|
for _, val := range vals {
|
|
|
347
|
headers = append(headers, Header{Name: name, Value: val})
|
|
|
348
|
}
|
|
|
349
|
}
|
|
|
350
|
buf := new(bytes.Buffer)
|
|
|
351
|
io.Copy(buf, resp.Body)
|
|
|
352
|
return Response{
|
|
|
353
|
Method: req.Method,
|
|
|
354
|
Path: req.URL.Path,
|
|
|
355
|
Status: resp.StatusCode,
|
|
|
356
|
Headers: headers,
|
|
|
357
|
Body: buf.String(),
|
|
|
358
|
}
|
|
|
359
|
}
|
|
|
360
|
|
|
319
|
361
|
// Header is a single-valued HTTP header name and value
|
|
320
|
362
|
type Header struct {
|
|
321
|
363
|
Name string `yaml:"name"`
|