diff --git a/request.go b/request.go index 9b9e7b2..89a6e5c 100644 --- a/request.go +++ b/request.go @@ -36,6 +36,7 @@ type Request interface { DisableRedirect() Request ForceMultipart() Request Do() (*Response, error) + String() string } type request struct { diff --git a/response.go b/response.go index e3e5f96..ebbf210 100644 --- a/response.go +++ b/response.go @@ -2,11 +2,19 @@ package client import ( + "bytes" "encoding/json" "fmt" "io" "io/ioutil" + "log" + "mime" "net/http" + "os" + "os/exec" + "runtime" + "strings" + "time" ) // Response is a request response wrapping the original *http.Request. @@ -14,10 +22,6 @@ type Response struct { *http.Response } -func (r *Response) String() string { - return fmt.Sprint(r.Response) -} - // Close closes the response body. // It must be called after body is no longer used. func (r *Response) Close() error { @@ -59,3 +63,70 @@ func (r *Response) JSON(v interface{}) error { func (r *Response) Path() string { return r.Request.URL.Path } + +// Dump is for debug purpose. +// It prints the request info, writes the body in a file and opens it in the browser. +// It panics on error. +func (r *Response) Dump() { + log.Println("-", r) + + var ext string + exts, _ := mime.ExtensionsByType(r.Header.Get("Content-Type")) + if len(exts) > 0 { + ext = exts[0] + } + name := fmt.Sprintf("response-dump-%d%s", time.Now().Unix(), ext) + f, err := os.Create(name) + if err != nil { + panic(err) + } + defer f.Close() + + if strings.HasPrefix(r.Header.Get("Content-Type"), "text/html") { + buf := bytes.NewBufferString("
\n\n")
+		log.New(buf, "", log.LstdFlags).Println("-", r)
+		buf.WriteString("
") + if _, err = io.Copy(f, buf); err != nil { + panic(err) + } + } + + if _, err = io.Copy(f, r.Body); err != nil { + panic(err) + } + + openFile(name) +} + +func openFile(url string) error { + var cmd string + var args []string + switch runtime.GOOS { + case "windows": + cmd = "cmd" + args = []string{"/c", "start"} + case "darwin": + cmd = "open" + default: + cmd = "xdg-open" + } + args = append(args, url) + return exec.Command(cmd, args...).Start() +} + +func (r *Response) String() string { + s := r.Status + " - " + r.Proto + " " + r.Request.Method + " " + r.Request.URL.String() + "\n" + if len(r.Header) > 0 { + s += "\tHeader:\n" + for k, v := range r.Header { + s += "\t\t" + k + ": " + strings.Join(v, ", ") + "\n" + } + } + if len(r.Cookies()) > 0 { + s += "\tCookies:\n" + for _, v := range r.Cookies() { + s += "\t\t" + fmt.Sprint(v) + } + } + return s +} diff --git a/response_test.go b/response_test.go new file mode 100644 index 0000000..6eeac34 --- /dev/null +++ b/response_test.go @@ -0,0 +1,13 @@ +package client + +import ( + "testing" +) + +func TestResponseDump(t *testing.T) { + // res, err := Get("http://example.com").Do() + // if err != nil { + // panic(err) + // } + // res.Dump() +}