/** Author: Mark George <mark.george@otago.ac.nz> License: Zero-Clause BSD License */ package main import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/http" "net/http/httputil" "strings" "time" "github.com/fatih/color" ) func showRequest(req *http.Request) { showTimestamp() if !globalOptions.NoColour { color.Set(color.FgBlue) } if globalOptions.HeadersOnly { showRequestHeaders(req) } else if globalOptions.BodiesOnly { showRequestBody(req) } else { showRequestHeaders(req) fmt.Println() showRequestBody(req) } color.Unset() } func showFilteredRequest(req *http.Request) { showTimestamp() if !globalOptions.NoColour { color.Set(color.FgBlue) } if !globalOptions.BodiesOnly { showRequestHeaders(req) } color.Unset() fmt.Println("\n[Request body filtered]") } func showResponse(rsp *http.Response) { showTimestamp() if !globalOptions.NoColour { color.Set(color.FgRed) } if globalOptions.HeadersOnly { showResponseHeaders(rsp) } else if globalOptions.BodiesOnly { showResponseBody(rsp) } else { showResponseHeaders(rsp) fmt.Println() showResponseBody(rsp) } color.Unset() } func showFilteredResponse(req *http.Response) { showTimestamp() if !globalOptions.NoColour { color.Set(color.FgRed) } if !globalOptions.BodiesOnly { showResponseHeaders(req) } color.Unset() fmt.Println("\n[Response body filtered]") } func showRequestBody(req *http.Request) { // is there a body? if req.Body == nil || req.Body == http.NoBody { // nope, nothing to do return } originalBody, _ := ioutil.ReadAll(req.Body) // clone body since reading from request it will consume it copy1 := ioutil.NopCloser(bytes.NewBuffer(originalBody)) copy2 := ioutil.NopCloser(bytes.NewBuffer(originalBody)) // put one copy back into original request req.Body = copy1 // read body from other copy body, _ := ioutil.ReadAll(copy2) defer copy2.Close() if !globalOptions.NoIndent { if strings.Contains(req.Header.Get("Content-Type"), "application/json") { // if req.Header.Get("Content-Type") == "application/json" { var indentedJson bytes.Buffer err := json.Indent(&indentedJson, body, "", " ") if err == nil { // display indented version fmt.Println(&indentedJson) return } } } fmt.Println(string(body[:])) } func showResponseBody(rsp *http.Response) { // is there a body? if rsp.Body == nil || rsp.Body == http.NoBody { // nope, nothing to do return } originalBody, _ := ioutil.ReadAll(rsp.Body) // clone body since reading from request it will consume it copy1 := ioutil.NopCloser(bytes.NewBuffer(originalBody)) copy2 := ioutil.NopCloser(bytes.NewBuffer(originalBody)) // put one copy back into original request rsp.Body = copy1 // read body from other copy body, _ := ioutil.ReadAll(copy2) defer copy2.Close() if !globalOptions.NoIndent { if strings.Contains(rsp.Header.Get("Content-Type"), "application/json") { var indentedJson bytes.Buffer err := json.Indent(&indentedJson, body, "", " ") if err == nil { // display indented version fmt.Println(&indentedJson) return } } } fmt.Println(string(body[:])) } func showRequestHeaders(req *http.Request) { dumpBody := false dump, _ := httputil.DumpRequest(req, dumpBody) fmt.Println(strings.TrimSpace(string(dump[:]))) } func showResponseHeaders(rsp *http.Response) { dumpBody := false dumpRsp, _ := httputil.DumpResponse(rsp, dumpBody) fmt.Println(strings.TrimSpace(string(dumpRsp[:]))) } func showTimestamp() { if !globalOptions.NoTimestamps { fmt.Println(time.Now().Format(time.StampMilli)) } }