You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-library/vendor/github.com/qiniu/go-sdk/v7/internal/clientv2/interceptor_debug.go

210 lines
5.1 KiB

package clientv2
import (
"crypto/tls"
"fmt"
clientV1 "github.com/qiniu/go-sdk/v7/client"
"github.com/qiniu/go-sdk/v7/internal/log"
"net/http"
"net/http/httptrace"
"net/http/httputil"
)
type DebugLevel int
const (
DebugLevelPrintNone DebugLevel = 0
DebugLevelPrintNormal DebugLevel = 1
DebugLevelPrintDetail DebugLevel = 2
)
var (
printRequestTrace = false
printRequestLevel *DebugLevel = nil
printResponseLevel *DebugLevel = nil
)
func PrintRequestTrace(isPrint bool) {
printRequestTrace = isPrint
}
func IsPrintRequestTrace() bool {
return printRequestTrace
}
func PrintRequest(level DebugLevel) {
printRequestLevel = &level
}
func IsPrintRequest() bool {
if printRequestLevel != nil {
return *printRequestLevel == DebugLevelPrintNormal || *printRequestLevel == DebugLevelPrintDetail
}
return clientV1.DebugMode
}
func IsPrintRequestBody() bool {
if printRequestLevel != nil {
return *printRequestLevel == DebugLevelPrintDetail
}
return clientV1.DeepDebugInfo
}
func PrintResponse(level DebugLevel) {
printResponseLevel = &level
}
func IsPrintResponse() bool {
if printResponseLevel != nil {
return *printResponseLevel == DebugLevelPrintNormal || *printResponseLevel == DebugLevelPrintDetail
}
return clientV1.DebugMode
}
func IsPrintResponseBody() bool {
if printResponseLevel != nil {
return *printResponseLevel == DebugLevelPrintDetail
}
return clientV1.DeepDebugInfo
}
type debugInterceptor struct {
}
func newDebugInterceptor() Interceptor {
return &debugInterceptor{}
}
func (interceptor *debugInterceptor) Priority() InterceptorPriority {
return InterceptorPriorityDebug
}
func (interceptor *debugInterceptor) Intercept(req *http.Request, handler Handler) (*http.Response, error) {
if interceptor == nil {
return handler(req)
}
label := interceptor.requestLabel(req)
if e := interceptor.printRequest(label, req); e != nil {
return nil, e
}
req = interceptor.printRequestTrace(label, req)
resp, err := handler(req)
if e := interceptor.printResponse(label, resp); e != nil {
return nil, e
}
return resp, err
}
func (interceptor *debugInterceptor) requestLabel(req *http.Request) string {
if req == nil || req.URL == nil {
return ""
}
return fmt.Sprintf("Url:%s", req.URL.String())
}
func (interceptor *debugInterceptor) printRequest(label string, req *http.Request) error {
if req == nil {
return nil
}
printReq := IsPrintRequest()
if !printReq {
return nil
}
info := label + " request:\n"
d, dErr := httputil.DumpRequest(req, IsPrintRequestBody())
if dErr != nil {
return dErr
}
info += string(d) + "\n"
log.Debug(info)
return nil
}
func (interceptor *debugInterceptor) printRequestTrace(label string, req *http.Request) *http.Request {
if !IsPrintRequestTrace() || req == nil {
return req
}
label += "\n"
trace := &httptrace.ClientTrace{
GetConn: func(hostPort string) {
log.Debug(label + fmt.Sprintf("GetConn, %s \n", hostPort))
},
GotConn: func(connInfo httptrace.GotConnInfo) {
remoteAddr := connInfo.Conn.RemoteAddr()
log.Debug(label + fmt.Sprintf("GotConn, Network:%s RemoteAddr:%s \n", remoteAddr.Network(), remoteAddr.String()))
},
PutIdleConn: func(err error) {
log.Debug(label + fmt.Sprintf("PutIdleConn, err:%v \n", err))
},
GotFirstResponseByte: func() {
log.Debug(label + fmt.Sprint("GotFirstResponseByte \n"))
},
Got100Continue: func() {
log.Debug(label + fmt.Sprint("Got100Continue \n"))
},
DNSStart: func(info httptrace.DNSStartInfo) {
log.Debug(label + fmt.Sprintf("DNSStart, host:%s \n", info.Host))
},
DNSDone: func(info httptrace.DNSDoneInfo) {
log.Debug(label + fmt.Sprintf("DNSDone, addr:%+v \n", info.Addrs))
},
ConnectStart: func(network, addr string) {
log.Debug(label + fmt.Sprintf("ConnectStart, network:%+v ip:%s \n", network, addr))
},
ConnectDone: func(network, addr string, err error) {
log.Debug(label + fmt.Sprintf("ConnectDone, network:%s ip:%s err:%v \n", network, addr, err))
},
TLSHandshakeStart: func() {
log.Debug(label + fmt.Sprint("TLSHandshakeStart \n"))
},
TLSHandshakeDone: func(state tls.ConnectionState, err error) {
log.Debug(label + fmt.Sprintf("TLSHandshakeDone, state:%+v err:%s \n", state, err))
},
// go1.10 不支持
//WroteHeaderField: func(key string, value []string) {
// log.Debug(label + fmt.Sprintf("WroteHeaderField, key:%s value:%s \n", key, value))
//},
WroteHeaders: func() {
log.Debug(label + fmt.Sprint("WroteHeaders \n"))
},
Wait100Continue: func() {
log.Debug(label + fmt.Sprint("Wait100Continue \n"))
},
WroteRequest: func(info httptrace.WroteRequestInfo) {
log.Debug(label + fmt.Sprintf("WroteRequest, err:%v \n", info.Err))
},
}
return req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
}
func (interceptor *debugInterceptor) printResponse(label string, resp *http.Response) error {
if resp == nil {
return nil
}
printResp := IsPrintResponse()
if !printResp {
return nil
}
info := label + " response:\n"
d, dErr := httputil.DumpResponse(resp, IsPrintResponseBody())
if dErr != nil {
return dErr
}
info += string(d) + "\n"
log.Debug(info)
return nil
}