client_request.go (125 lines of code) (raw):

package sls // request sends a request to SLS. import ( "bytes" "fmt" "io/ioutil" "net/http" "net/http/httputil" "strings" "github.com/go-kit/kit/log/level" ) // request sends a request to alibaba cloud Log Service. // @note if error is nil, you must call http.Response.Body.Close() to finalize reader func (c *Client) request(project, 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, fmt.Errorf("Can't find 'x-log-bodyrawsize' header") } var endpoint string var usingHTTPS bool if strings.HasPrefix(c.Endpoint, "https://") { endpoint = c.Endpoint[8:] usingHTTPS = true } else if strings.HasPrefix(c.Endpoint, "http://") { endpoint = c.Endpoint[7:] } else { endpoint = c.Endpoint } // SLS public request headers var hostStr string if len(project) == 0 { hostStr = endpoint } else { hostStr = project + "." + endpoint } headers[HTTPHeaderHost] = hostStr headers[HTTPHeaderAPIVersion] = version if len(c.UserAgent) > 0 { headers[HTTPHeaderUserAgent] = c.UserAgent } else { headers[HTTPHeaderUserAgent] = DefaultLogUserAgent } c.accessKeyLock.RLock() stsToken := c.SecurityToken accessKeyID := c.AccessKeyID accessKeySecret := c.AccessKeySecret region := c.Region authVersion := c.AuthVersion c.accessKeyLock.RUnlock() if c.credentialsProvider != nil { res, err := c.credentialsProvider.GetCredentials() if err != nil { return nil, fmt.Errorf("fail to fetch credentials: %w", err) } accessKeyID = res.AccessKeyID accessKeySecret = res.AccessKeySecret stsToken = res.SecurityToken } // Access with token if stsToken != "" { headers[HTTPHeaderAcsSecurityToken] = stsToken } if body != nil { if _, ok := headers[HTTPHeaderContentType]; !ok { return nil, fmt.Errorf("Can't find 'Content-Type' header") } } for k, v := range c.InnerHeaders { headers[k] = v } var signer Signer if authVersion == AuthV4 { headers[HTTPHeaderLogDate] = dateTimeISO8601() signer = NewSignerV4(accessKeyID, accessKeySecret, region) } else if 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(c.CommonHeaders, headers) // Initialize http request reader := bytes.NewReader(body) var urlStr string // using http as default if !GlobalForceUsingHTTP && usingHTTPS { urlStr = "https://" } else { urlStr = "http://" } urlStr += hostStr + uri req, err := http.NewRequest(method, urlStr, reader) if err != nil { return nil, 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 httpClient := c.HTTPClient if httpClient == nil { httpClient = defaultHttpClient } resp, err := httpClient.Do(req) if err != nil { return nil, err } // Parse the sls error from body. if resp.StatusCode != http.StatusOK { defer resp.Body.Close() buf, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, readResponseError(err) } return nil, httpStatusNotOkError(buf, resp.Header, resp.StatusCode) } 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 }