func (r roundTripper) RoundTrip(req *http.Request) (resp *http.Response, err error) {
	tripper := r.rt
	if tripper == nil {
		tripper = http.RoundTripper(http.DefaultTransport)
	}
	l := r.logger
	p := newPrinter(l)
	defer p.flush()
	if hide := req.Context().Value(contextHide{}); hide != nil || p.checkFilter(req) {
		return tripper.RoundTrip(req)
	}
	var tlsClientConfig *tls.Config
	if l.Time {
		defer p.printTimeRequest()()
	}
	if !l.SkipRequestInfo {
		p.printRequestInfo(req)
	}
	if transport, ok := tripper.(*http.Transport); ok && transport.TLSClientConfig != nil {
		tlsClientConfig = transport.TLSClientConfig
		if tlsClientConfig.InsecureSkipVerify {
			p.printf("* Skipping TLS verification: %s\n",
				p.format(color.FgRed, "connection is susceptible to man-in-the-middle attacks."))
		}
	}
	if l.TLS && tlsClientConfig != nil {
		p.printOutgoingClientTLS(tlsClientConfig)
	}
	p.printRequest(req)
	defer func() {
		if err != nil {
			p.printf("* %s\n", p.format(color.FgRed, err.Error()))
			if resp == nil {
				return
			}
		}
		if l.TLS {
			p.printTLSInfo(resp.TLS, false)
			p.printTLSServer(req.Host, resp.TLS)
		}
		p.printResponse(resp)
	}()
	return tripper.RoundTrip(req)
}
RoundTrip implements the http.RoundTrip interface.
package httpretty
import (
	"bytes"
	"context"
	"crypto/tls"
	"encoding/json"
	"errors"
	"io"
	"net/http"
	"net/textproto"
	"os"
	"sync"
	"github.com/henvic/httpretty/internal/color"
)
type Formatter interface {
	Match(mediatype string) bool
	Format(w io.Writer, src []byte) error
}
func WithHide(ctx context.Context) context.Context {
	return context.WithValue(ctx, contextHide{}, struct{}{})
}
type Logger struct {
	SkipRequestInfo bool
	Time bool
	TLS bool
	RequestHeader bool
	RequestBody bool
	ResponseHeader bool
	ResponseBody bool
	SkipSanitize bool
	Colors bool
	Formatters []Formatter
	MaxRequestBody int64
	MaxResponseBody int64
	mu         sync.Mutex  
	w          io.Writer
	filter     Filter
	skipHeader map[string]struct{}
	bodyFilter BodyFilter
	flusher    Flusher
}
type Filter func(req *http.Request) (skip bool, err error)
type BodyFilter func(h http.Header) (skip bool, err error)
type Flusher int
const (
	NoBuffer Flusher = iota
	OnReady
	OnEnd
)
func (l *Logger) SetFilter(f Filter) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.filter = f
}
func (l *Logger) SkipHeader(headers []string) {
	l.mu.Lock()
	defer l.mu.Unlock()
	m := map[string]struct{}{}
	for _, h := range headers {
		m[textproto.CanonicalMIMEHeaderKey(h)] = struct{}{}
	}
	l.skipHeader = m
}
func (l *Logger) SetBodyFilter(f BodyFilter) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.bodyFilter = f
}
func (l *Logger) SetOutput(w io.Writer) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.w = w
}
func (l *Logger) SetFlusher(f Flusher) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.flusher = f
}
func (l *Logger) getWriter() io.Writer {
	if l.w == nil {
		return os.Stdout
	}
	return l.w
}
func (l *Logger) getFilter() Filter {
	l.mu.Lock()
	f := l.filter
	defer l.mu.Unlock()
	return f
}
func (l *Logger) getBodyFilter() BodyFilter {
	l.mu.Lock()
	f := l.bodyFilter
	defer l.mu.Unlock()
	return f
}
func (l *Logger) cloneSkipHeader() map[string]struct{} {
	l.mu.Lock()
	skipped := l.skipHeader
	l.mu.Unlock()
	m := map[string]struct{}{}
	for h := range skipped {
		m[h] = struct{}{}
	}
	return m
}
type contextHide struct{}
type roundTripper struct {
	logger *Logger
	rt     http.RoundTripper
}
func (l *Logger) RoundTripper(rt http.RoundTripper) http.RoundTripper {
	return roundTripper{
		logger: l,
		rt:     rt,
	}
}