func realRequest()

in request.go [151:261]


func realRequest(ctx context.Context, project *LogProject, method, uri string, headers map[string]string,
	body []byte) (*http.Response, error) {

	// The caller should provide 'x-log-bodyrawsize' header
	if _, ok := headers[HTTPHeaderBodyRawSize]; !ok {
		return nil, NewClientError(fmt.Errorf("Can't find 'x-log-bodyrawsize' header"))
	}

	// SLS public request headers
	baseURL := project.getBaseURL()
	headers[HTTPHeaderHost] = baseURL
	headers[HTTPHeaderAPIVersion] = version
	if len(project.UserAgent) > 0 {
		headers[HTTPHeaderUserAgent] = project.UserAgent
	} else {
		headers[HTTPHeaderUserAgent] = DefaultLogUserAgent
	}

	stsToken := project.SecurityToken
	accessKeyID := project.AccessKeyID
	accessKeySecret := project.AccessKeySecret

	if project.credentialProvider != nil {
		c, err := project.credentialProvider.GetCredentials()
		if err != nil {
			return nil, NewClientError(fmt.Errorf("fail to get credentials: %w", err))
		}
		stsToken = c.SecurityToken
		accessKeyID = c.AccessKeyID
		accessKeySecret = c.AccessKeySecret
	}

	// Access with token
	if stsToken != "" {
		headers[HTTPHeaderAcsSecurityToken] = stsToken
	}

	if body != nil {
		if _, ok := headers[HTTPHeaderContentType]; !ok {
			return nil, NewClientError(fmt.Errorf("Can't find 'Content-Type' header"))
		}
	}

	for k, v := range project.innerHeaders {
		headers[k] = v
	}
	var signer Signer
	if project.AuthVersion == AuthV4 {
		headers[HTTPHeaderLogDate] = dateTimeISO8601()
		signer = NewSignerV4(accessKeyID, accessKeySecret, project.Region)
	} else if project.AuthVersion == AuthV0 {
		signer = NewSignerV0()
	} else {
		headers[HTTPHeaderDate] = nowRFC1123()
		signer = NewSignerV1(accessKeyID, accessKeySecret)
	}
	if err := signer.Sign(method, uri, headers, body); err != nil {
		return nil, err
	}

	addHeadersAfterSign(project.commonHeaders, headers)

	// Initialize http request
	reader := bytes.NewReader(body)

	// Handle the endpoint
	urlStr := fmt.Sprintf("%s%s", baseURL, uri)
	req, err := http.NewRequest(method, urlStr, reader)
	if err != nil {
		return nil, NewClientError(err)
	}
	for k, v := range headers {
		req.Header.Add(k, v)
	}
	if IsDebugLevelMatched(5) {
		dump, e := httputil.DumpRequest(req, true)
		if e != nil {
			level.Info(Logger).Log("msg", e)
		}
		level.Info(Logger).Log("msg", "HTTP Request:\n%v", string(dump))
	}
	// Get ready to do request
	resp, err := project.httpClient.Do(req)
	if err != nil {
		return nil, err
	}

	// Parse the sls error from body.
	if resp.StatusCode != http.StatusOK {
		err := &Error{}
		err.HTTPCode = (int32)(resp.StatusCode)
		defer resp.Body.Close()
		buf, ioErr := ioutil.ReadAll(resp.Body)
		if ioErr != nil {
			return nil, NewBadResponseError(ioErr.Error(), resp.Header, resp.StatusCode)
		}
		if jErr := json.Unmarshal(buf, err); jErr != nil {
			return nil, NewBadResponseError(string(buf), resp.Header, resp.StatusCode)
		}
		err.RequestID = resp.Header.Get(RequestIDHeader)
		return nil, err
	}
	if IsDebugLevelMatched(5) {
		dump, e := httputil.DumpResponse(resp, true)
		if e != nil {
			level.Info(Logger).Log("msg", e)
		}
		level.Info(Logger).Log("msg", "HTTP Response:\n%v", string(dump))
	}
	return resp, nil
}