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  }