in sdk/client.go [557:719]
func (client *Client) DoActionWithSigner(request requests.AcsRequest, response responses.AcsResponse, signer auth.Signer) (err error) {
if client.Network != "" {
match, _ := regexp.MatchString("^[a-zA-Z0-9_-]+$", client.Network)
if !match {
return fmt.Errorf("netWork contains invalid characters")
}
}
fieldMap := make(map[string]string)
initLogMsg(fieldMap)
defer func() {
client.printLog(fieldMap, err)
}()
httpRequest, err := client.buildRequestWithSigner(request)
if err != nil {
return
}
client.setTimeout(request)
proxy, err := client.getHttpProxy(httpRequest.URL.Scheme)
if err != nil {
return err
}
noProxy := client.getNoProxy()
var flag bool
for _, value := range noProxy {
if strings.HasPrefix(value, "*") {
value = fmt.Sprintf(".%s", value)
}
noProxyReg, err := regexp.Compile(value)
if err != nil {
return err
}
if noProxyReg.MatchString(httpRequest.Host) {
flag = true
break
}
}
// Set whether to ignore certificate validation.
// Default InsecureSkipVerify is false.
if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil {
if trans.TLSClientConfig != nil {
trans.TLSClientConfig.InsecureSkipVerify = client.getHTTPSInsecure(request)
} else {
trans.TLSClientConfig = &tls.Config{
InsecureSkipVerify: client.getHTTPSInsecure(request),
}
}
if proxy != nil && !flag {
trans.Proxy = http.ProxyURL(proxy)
}
client.httpClient.Transport = trans
}
// Set tracer
var span opentracing.Span
if ok := opentracing.IsGlobalTracerRegistered(); ok && !client.isCloseTrace {
tracer := opentracing.GlobalTracer()
var rootCtx opentracing.SpanContext
var rootSpan opentracing.Span
if rootSpan = client.rootSpan; rootSpan != nil {
rootCtx = rootSpan.Context()
} else if rootSpan = request.GetTracerSpan(); rootSpan != nil {
rootCtx = rootSpan.Context()
}
span = tracer.StartSpan(
httpRequest.URL.RequestURI(),
opentracing.ChildOf(rootCtx),
opentracing.Tag{Key: string(ext.Component), Value: "aliyunApi"},
opentracing.Tag{Key: "actionName", Value: request.GetActionName()})
defer span.Finish()
tracer.Inject(
span.Context(),
opentracing.HTTPHeaders,
opentracing.HTTPHeadersCarrier(httpRequest.Header))
}
var httpResponse *http.Response
for retryTimes := 0; retryTimes <= client.config.MaxRetryTime; retryTimes++ {
if retryTimes > 0 {
client.printLog(fieldMap, err)
initLogMsg(fieldMap)
}
putMsgToMap(fieldMap, httpRequest)
debug("> %s %s %s", httpRequest.Method, httpRequest.URL.RequestURI(), httpRequest.Proto)
debug("> Host: %s", httpRequest.Host)
for key, value := range httpRequest.Header {
debug("> %s: %v", key, strings.Join(value, ""))
}
debug(">")
debug(" Retry Times: %d.", retryTimes)
startTime := time.Now()
fieldMap["{start_time}"] = startTime.Format("2006-01-02 15:04:05")
httpResponse, err = hookDo(client.httpClient.Do)(httpRequest)
fieldMap["{cost}"] = time.Since(startTime).String()
if err == nil {
fieldMap["{code}"] = strconv.Itoa(httpResponse.StatusCode)
fieldMap["{res_headers}"] = TransToString(httpResponse.Header)
debug("< %s %s", httpResponse.Proto, httpResponse.Status)
for key, value := range httpResponse.Header {
debug("< %s: %v", key, strings.Join(value, ""))
}
}
debug("<")
// receive error
if err != nil {
debug(" Error: %s.", err.Error())
if span != nil {
ext.LogError(span, err)
}
if !client.config.AutoRetry {
return
} else if retryTimes >= client.config.MaxRetryTime {
// timeout but reached the max retry times, return
times := strconv.Itoa(retryTimes + 1)
timeoutErrorMsg := fmt.Sprintf(errors.TimeoutErrorMessage, times, times)
if strings.Contains(err.Error(), "Client.Timeout") {
timeoutErrorMsg += " Read timeout. Please set a valid ReadTimeout."
} else {
timeoutErrorMsg += " Connect timeout. Please set a valid ConnectTimeout."
}
err = errors.NewClientError(errors.TimeoutErrorCode, timeoutErrorMsg, err)
return
}
}
if isCertificateError(err) {
return
}
// if status code >= 500 or timeout, will trigger retry
if client.config.AutoRetry && (err != nil || isServerError(httpResponse)) {
client.setTimeout(request)
// rewrite signatureNonce and signature
httpRequest, err = client.buildRequestWithSigner(request)
if err != nil {
return
}
continue
}
break
}
if span != nil {
ext.HTTPStatusCode.Set(span, uint16(httpResponse.StatusCode))
}
err = responses.Unmarshal(response, httpResponse, request.GetAcceptFormat())
fieldMap["{res_body}"] = response.GetHttpContentString()
debug("%s", response.GetHttpContentString())
// wrap server errors
if serverErr, ok := err.(*errors.ServerError); ok {
var wrapInfo = map[string]string{}
serverErr.RespHeaders = response.GetHttpHeaders()
wrapInfo["StringToSign"] = request.GetStringToSign()
err = errors.WrapServerError(serverErr, wrapInfo)
}
return
}