Merge pull request #242 from github/debug-api

Dump HTTP request/response bodies when `DEBUG=api`
This commit is contained in:
Nate Smith 2020-01-22 14:05:29 -06:00 committed by GitHub
commit 340f747944
2 changed files with 24 additions and 3 deletions

View file

@ -7,6 +7,8 @@ import (
"io"
"io/ioutil"
"net/http"
"regexp"
"strings"
)
// ClientOption represents an argument to NewClient
@ -34,13 +36,26 @@ func AddHeader(name, value string) ClientOption {
}
// VerboseLog enables request/response logging within a RoundTripper
func VerboseLog(out io.Writer) ClientOption {
func VerboseLog(out io.Writer, logBodies bool) ClientOption {
return func(tr http.RoundTripper) http.RoundTripper {
return &funcTripper{roundTrip: func(req *http.Request) (*http.Response, error) {
fmt.Fprintf(out, "> %s %s\n", req.Method, req.URL.RequestURI())
if logBodies && req.Body != nil && inspectableMIMEType(req.Header.Get("Content-type")) {
newBody := &bytes.Buffer{}
io.Copy(out, io.TeeReader(req.Body, newBody))
fmt.Fprintln(out)
req.Body = ioutil.NopCloser(newBody)
}
res, err := tr.RoundTrip(req)
if err == nil {
fmt.Fprintf(out, "< HTTP %s\n", res.Status)
if logBodies && res.Body != nil && inspectableMIMEType(res.Header.Get("Content-type")) {
newBody := &bytes.Buffer{}
// TODO: pretty-print response JSON
io.Copy(out, io.TeeReader(res.Body, newBody))
fmt.Fprintln(out)
res.Body = ioutil.NopCloser(newBody)
}
}
return res, err
}}
@ -179,3 +194,9 @@ func handleHTTPError(resp *http.Response) error {
return fmt.Errorf("http error, '%s' failed (%d): '%s'", resp.Request.URL, resp.StatusCode, message)
}
var jsonTypeRE = regexp.MustCompile(`[/+]json($|;)`)
func inspectableMIMEType(t string) bool {
return strings.HasPrefix(t, "text/") || jsonTypeRE.MatchString(t)
}

View file

@ -84,7 +84,7 @@ func BasicClient() (*api.Client, error) {
opts = append(opts, api.AddHeader("Authorization", fmt.Sprintf("token %s", c.Token)))
}
if verbose := os.Getenv("DEBUG"); verbose != "" {
opts = append(opts, api.VerboseLog(os.Stderr))
opts = append(opts, api.VerboseLog(os.Stderr, false))
}
return api.NewClient(opts...), nil
}
@ -113,7 +113,7 @@ var apiClientForContext = func(ctx context.Context) (*api.Client, error) {
api.AddHeader("GraphQL-Features", "pe_mobile"),
}
if verbose := os.Getenv("DEBUG"); verbose != "" {
opts = append(opts, api.VerboseLog(os.Stderr))
opts = append(opts, api.VerboseLog(os.Stderr, strings.Contains(verbose, "api")))
}
return api.NewClient(opts...), nil
}