github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v7/shared/log_cache_client.go (about) 1 package shared 2 3 import ( 4 "fmt" 5 "net" 6 "net/http" 7 "strings" 8 "time" 9 10 "code.cloudfoundry.org/cli/command" 11 "code.cloudfoundry.org/cli/util" 12 logcache "code.cloudfoundry.org/log-cache/pkg/client" 13 ) 14 15 type DebugPrinter struct { 16 outputs []RequestLoggerOutput 17 } 18 19 func (p DebugPrinter) Print(title, dump string) { 20 for _, output := range p.outputs { 21 _ = output.Start() //nolint 22 _ = output.DisplayType(title, time.Now()) //nolint 23 _ = output.DisplayDump(dump) //nolint 24 _ = output.Stop() //nolint 25 } 26 } 27 28 func (p *DebugPrinter) addOutput(output RequestLoggerOutput) { 29 p.outputs = append(p.outputs, output) 30 } 31 32 type tokenHTTPClient struct { 33 c logcache.HTTPClient 34 accessToken func() string 35 } 36 37 func (c *tokenHTTPClient) Do(req *http.Request) (*http.Response, error) { 38 req.Header.Set("Authorization", c.accessToken()) 39 return c.c.Do(req) 40 } 41 42 type httpDebugClient struct { 43 printer DebugPrinter 44 c logcache.HTTPClient 45 } 46 47 func (c *httpDebugClient) Do(req *http.Request) (*http.Response, error) { 48 c.printer.Print("HTTP REQUEST", 49 fmt.Sprintf("GET %s HTTP/1.1\nHOST: %s://%s\nQUERY: %s\n%s", 50 req.URL.Path, 51 req.URL.Scheme, 52 req.URL.Host, 53 req.URL.RawQuery, 54 headersString(req.Header)), 55 ) 56 57 resp, err := c.c.Do(req) 58 if err != nil { 59 c.printer.Print("HTTP ERROR", err.Error()) 60 return nil, err 61 } 62 63 c.printer.Print("HTTP RESPONSE", 64 fmt.Sprintf("%s\n%s", 65 resp.Status, 66 headersString(resp.Header)), 67 ) 68 69 return resp, err 70 } 71 72 // NewLogCacheClient returns back a configured Log Cache Client. 73 func NewLogCacheClient(logCacheEndpoint string, config command.Config, ui command.UI) *logcache.Client { 74 tr := &http.Transport{ 75 Proxy: http.ProxyFromEnvironment, 76 TLSClientConfig: util.NewTLSConfig(nil, config.SkipSSLValidation()), 77 DialContext: (&net.Dialer{ 78 KeepAlive: 30 * time.Second, 79 Timeout: config.DialTimeout(), 80 }).DialContext, 81 } 82 83 var client logcache.HTTPClient //nolint 84 client = &http.Client{Transport: tr} 85 86 verbose, location := config.Verbose() 87 if verbose { 88 printer := DebugPrinter{} 89 printer.addOutput(ui.RequestLoggerTerminalDisplay()) 90 if location != nil { 91 printer.addOutput(ui.RequestLoggerFileWriter(location)) 92 } 93 94 client = &httpDebugClient{printer: printer, c: client} 95 } 96 97 return logcache.NewClient( 98 logCacheEndpoint, 99 logcache.WithHTTPClient(&tokenHTTPClient{ 100 c: client, 101 accessToken: config.AccessToken, 102 }), 103 ) 104 } 105 func headersString(header http.Header) string { 106 var result string 107 for name, values := range header { 108 result += name + ": " + strings.Join(values, ", ") + "\n" 109 } 110 return result 111 }