123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- package common
- import (
- "bytes"
- "encoding/json"
- "io/ioutil"
- "log"
- "net/http"
- "net/url"
- "time"
- "github.com/denverdino/aliyungo/util"
- )
- // A Client represents a client of ECS services
- type Client struct {
- AccessKeyId string //Access Key Id
- AccessKeySecret string //Access Key Secret
- debug bool
- httpClient *http.Client
- endpoint string
- version string
- }
- // NewClient creates a new instance of ECS client
- func (client *Client) Init(endpoint, version, accessKeyId, accessKeySecret string) {
- client.AccessKeyId = accessKeyId
- client.AccessKeySecret = accessKeySecret + "&"
- client.debug = false
- client.httpClient = &http.Client{}
- client.endpoint = endpoint
- client.version = version
- }
- // SetEndpoint sets custom endpoint
- func (client *Client) SetEndpoint(endpoint string) {
- client.endpoint = endpoint
- }
- // SetEndpoint sets custom version
- func (client *Client) SetVersion(version string) {
- client.version = version
- }
- // SetAccessKeyId sets new AccessKeyId
- func (client *Client) SetAccessKeyId(id string) {
- client.AccessKeyId = id
- }
- // SetAccessKeySecret sets new AccessKeySecret
- func (client *Client) SetAccessKeySecret(secret string) {
- client.AccessKeySecret = secret + "&"
- }
- // SetDebug sets debug mode to log the request/response message
- func (client *Client) SetDebug(debug bool) {
- client.debug = debug
- }
- // Invoke sends the raw HTTP request for ECS services
- func (client *Client) Invoke(action string, args interface{}, response interface{}) error {
- request := Request{}
- request.init(client.version, action, client.AccessKeyId)
- query := util.ConvertToQueryValues(request)
- util.SetQueryValues(args, &query)
- // Sign request
- signature := util.CreateSignatureForRequest(ECSRequestMethod, &query, client.AccessKeySecret)
- // Generate the request URL
- requestURL := client.endpoint + "?" + query.Encode() + "&Signature=" + url.QueryEscape(signature)
- httpReq, err := http.NewRequest(ECSRequestMethod, requestURL, nil)
- // TODO move to util and add build val flag
- httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version)
- if err != nil {
- return GetClientError(err)
- }
- t0 := time.Now()
- httpResp, err := client.httpClient.Do(httpReq)
- t1 := time.Now()
- if err != nil {
- return GetClientError(err)
- }
- statusCode := httpResp.StatusCode
- if client.debug {
- log.Printf("Invoke %s %s %d (%v)", ECSRequestMethod, requestURL, statusCode, t1.Sub(t0))
- }
- defer httpResp.Body.Close()
- body, err := ioutil.ReadAll(httpResp.Body)
- if err != nil {
- return GetClientError(err)
- }
- if client.debug {
- var prettyJSON bytes.Buffer
- err = json.Indent(&prettyJSON, body, "", " ")
- log.Println(string(prettyJSON.Bytes()))
- }
- if statusCode >= 400 && statusCode <= 599 {
- errorResponse := ErrorResponse{}
- err = json.Unmarshal(body, &errorResponse)
- ecsError := &Error{
- ErrorResponse: errorResponse,
- StatusCode: statusCode,
- }
- return ecsError
- }
- err = json.Unmarshal(body, response)
- //log.Printf("%++v", response)
- if err != nil {
- return GetClientError(err)
- }
- return nil
- }
- // GenerateClientToken generates the Client Token with random string
- func (client *Client) GenerateClientToken() string {
- return util.CreateRandomString()
- }
- func GetClientErrorFromString(str string) error {
- return &Error{
- ErrorResponse: ErrorResponse{
- Code: "AliyunGoClientFailure",
- Message: str,
- },
- StatusCode: -1,
- }
- }
- func GetClientError(err error) error {
- return GetClientErrorFromString(err.Error())
- }
|