harbor/src/chartserver/client.go
陈德 0582db9a82 Apply consistent format for comments
Signed-off-by: 陈德 <chende@caicloud.io>
2018-09-05 16:16:31 +08:00

118 lines
2.6 KiB
Go

package chartserver
import (
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
)
const (
clientTimeout = 10 * time.Second
maxIdleConnections = 10
idleConnectionTimeout = 30 * time.Second
)
// ChartClient is a http client to get the content from the external http server
type ChartClient struct {
// HTTP client
httpClient *http.Client
// Auth info
credentail *Credential
}
// NewChartClient is constructor of ChartClient
// credentail can be nil
func NewChartClient(credentail *Credential) *ChartClient { // Create http client with customized timeouts
client := &http.Client{
Timeout: clientTimeout,
Transport: &http.Transport{
MaxIdleConns: maxIdleConnections,
IdleConnTimeout: idleConnectionTimeout,
},
}
return &ChartClient{
httpClient: client,
credentail: credentail,
}
}
// GetContent get the bytes from the specified url
func (cc *ChartClient) GetContent(addr string) ([]byte, error) {
response, err := cc.sendRequest(addr, http.MethodGet, nil, []int{http.StatusOK})
if err != nil {
return nil, err
}
content, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, err
}
defer response.Body.Close()
return content, nil
}
// DeleteContent sends deleting request to the addr to delete content
func (cc *ChartClient) DeleteContent(addr string) error {
_, err := cc.sendRequest(addr, http.MethodDelete, nil, []int{http.StatusOK})
return err
}
// sendRequest sends requests to the addr with the specified spec
func (cc *ChartClient) sendRequest(addr string, method string, body io.Reader, expectedCodes []int) (*http.Response, error) {
if len(strings.TrimSpace(addr)) == 0 {
return nil, errors.New("empty url is not allowed")
}
fullURI, err := url.Parse(addr)
if err != nil {
return nil, fmt.Errorf("invalid url: %s", err.Error())
}
request, err := http.NewRequest(method, addr, body)
if err != nil {
return nil, err
}
// Set basic auth
if cc.credentail != nil {
request.SetBasicAuth(cc.credentail.Username, cc.credentail.Password)
}
response, err := cc.httpClient.Do(request)
if err != nil {
return nil, err
}
isExpectedStatusCode := false
for _, eCode := range expectedCodes {
if eCode == response.StatusCode {
isExpectedStatusCode = true
break
}
}
if !isExpectedStatusCode {
content, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, err
}
defer response.Body.Close()
if err := extractError(content); err != nil {
return nil, err
}
return nil, fmt.Errorf("%s '%s' failed with error: %s", method, fullURI.Path, content)
}
return response, nil
}