debug.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package main
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "net/http"
  8. "os"
  9. )
  10. type logTransport struct {
  11. rt http.RoundTripper
  12. }
  13. func (t *logTransport) RoundTrip(req *http.Request) (*http.Response, error) {
  14. var buf bytes.Buffer
  15. os.Stdout.Write([]byte("\n[request]\n"))
  16. if req.Body != nil {
  17. req.Body = ioutil.NopCloser(&readButCopy{req.Body, &buf})
  18. }
  19. req.Write(os.Stdout)
  20. if req.Body != nil {
  21. req.Body = ioutil.NopCloser(&buf)
  22. }
  23. os.Stdout.Write([]byte("\n[/request]\n"))
  24. res, err := t.rt.RoundTrip(req)
  25. fmt.Printf("[response]\n")
  26. if err != nil {
  27. fmt.Printf("ERROR: %v", err)
  28. } else {
  29. body := res.Body
  30. res.Body = nil
  31. res.Write(os.Stdout)
  32. if body != nil {
  33. res.Body = ioutil.NopCloser(&echoAsRead{body})
  34. }
  35. }
  36. return res, err
  37. }
  38. type echoAsRead struct {
  39. src io.Reader
  40. }
  41. func (r *echoAsRead) Read(p []byte) (int, error) {
  42. n, err := r.src.Read(p)
  43. if n > 0 {
  44. os.Stdout.Write(p[:n])
  45. }
  46. if err == io.EOF {
  47. fmt.Printf("\n[/response]\n")
  48. }
  49. return n, err
  50. }
  51. type readButCopy struct {
  52. src io.Reader
  53. dst io.Writer
  54. }
  55. func (r *readButCopy) Read(p []byte) (int, error) {
  56. n, err := r.src.Read(p)
  57. if n > 0 {
  58. r.dst.Write(p[:n])
  59. }
  60. return n, err
  61. }