...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package transport
16
17 import (
18 "fmt"
19 "net/http"
20 "net/http/httputil"
21 "time"
22
23 "github.com/google/go-containerregistry/internal/redact"
24 "github.com/google/go-containerregistry/pkg/logs"
25 )
26
27 type logTransport struct {
28 inner http.RoundTripper
29 }
30
31
32
33 func NewLogger(inner http.RoundTripper) http.RoundTripper {
34 return &logTransport{inner}
35 }
36
37 func (t *logTransport) RoundTrip(in *http.Request) (out *http.Response, err error) {
38
39
40
41 omitBody, reason := redact.FromContext(in.Context())
42 if omitBody {
43 logs.Debug.Printf("--> %s %s [body redacted: %s]", in.Method, in.URL, reason)
44 } else {
45 logs.Debug.Printf("--> %s %s", in.Method, in.URL)
46 }
47
48
49 savedHeaders := in.Header.Clone()
50 if in.Header != nil && in.Header.Get("authorization") != "" {
51 in.Header.Set("authorization", "<redacted>")
52 }
53
54 b, err := httputil.DumpRequestOut(in, !omitBody)
55 if err == nil {
56 logs.Debug.Println(string(b))
57 } else {
58 logs.Debug.Printf("Failed to dump request %s %s: %v", in.Method, in.URL, err)
59 }
60
61
62 in.Header = savedHeaders
63
64 start := time.Now()
65 out, err = t.inner.RoundTrip(in)
66 duration := time.Since(start)
67 if err != nil {
68 logs.Debug.Printf("<-- %v %s %s (%s)", err, in.Method, in.URL, duration)
69 }
70 if out != nil {
71 msg := fmt.Sprintf("<-- %d", out.StatusCode)
72 if out.Request != nil {
73 msg = fmt.Sprintf("%s %s", msg, out.Request.URL)
74 }
75 msg = fmt.Sprintf("%s (%s)", msg, duration)
76
77 if omitBody {
78 msg = fmt.Sprintf("%s [body redacted: %s]", msg, reason)
79 }
80
81 logs.Debug.Print(msg)
82
83 b, err := httputil.DumpResponse(out, !omitBody)
84 if err == nil {
85 logs.Debug.Println(string(b))
86 } else {
87 logs.Debug.Printf("Failed to dump response %s %s: %v", in.Method, in.URL, err)
88 }
89 }
90 return
91 }
92
View as plain text