@@ -0,0 +1,11 @@ | |||
package credentials | |||
type BaseCredential struct { | |||
AccessKeyId string | |||
AccessKeySecret string | |||
} | |||
type AccessKeyCredential struct { | |||
AccessKeyId string | |||
AccessKeySecret string | |||
} |
@@ -1,6 +1,4 @@ | |||
package auth | |||
type Creditial struct { | |||
AccessKeyId string | |||
AccessKeySecret string | |||
type Credential interface { | |||
} |
@@ -0,0 +1,28 @@ | |||
package auth | |||
import ( | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils" | |||
"net/url" | |||
"strings" | |||
) | |||
func buildRpcStringToSign(request requests.AcsRequest) (stringToSign string) { | |||
signParams := make(map[string]string) | |||
for key, value := range request.GetQueryParams() { | |||
signParams[key] = value | |||
} | |||
for key, value := range request.GetFormParams() { | |||
signParams[key] = value | |||
} | |||
stringToSign = utils.GetUrlFormedMap(signParams) | |||
stringToSign = strings.Replace(stringToSign, "+", "%20", -1) | |||
stringToSign = strings.Replace(stringToSign, "*", "%2A", -1) | |||
stringToSign = strings.Replace(stringToSign, "%7E", "~", -1) | |||
stringToSign = url.QueryEscape(stringToSign) | |||
stringToSign = request.GetMethod() + "&%2F&" + stringToSign | |||
return | |||
} | |||
@@ -0,0 +1,32 @@ | |||
package auth | |||
import ( | |||
"errors" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/signers" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses" | |||
) | |||
type Signer interface { | |||
GetName() string | |||
Sign(stringToSign, secretSuffix string) string | |||
} | |||
func NewSignerWithCredential(credential Credential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer Signer, err error) { | |||
switch instance := credential.(type) { | |||
case *credentials.AccessKeyCredential: | |||
signer = signers.NewAccessKeySigner(instance) | |||
default: | |||
err = errors.New("UnsupportedCredentialErrorCode = SDK.UnsupportedCredential") | |||
} | |||
return | |||
} | |||
func Sign(request requests.AcsRequest, signer Signer, regionId string) (err error) { | |||
} |
@@ -0,0 +1,41 @@ | |||
package signers | |||
import ( | |||
"crypto/hmac" | |||
"crypto/sha1" | |||
"encoding/base64" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials" | |||
) | |||
type AccessKeySigner struct { | |||
credential *credentials.AccessKeyCredential | |||
} | |||
func NewAccessKeySigner(credential *credentials.AccessKeyCredential) *AccessKeySigner { | |||
return &AccessKeySigner{ | |||
credential: credential, | |||
} | |||
} | |||
func (*AccessKeySigner) GetName() string { | |||
return "HMAC-SHA1" | |||
} | |||
func (signer *AccessKeySigner) Sign(stringToSign, secretSuffix string) string { | |||
secret := signer.credential.AccessKeySecret + secretSuffix | |||
return ShaHmac1(stringToSign, secret) | |||
} | |||
func ShaHmac1(source, secret string) string { | |||
key := []byte(secret) | |||
hmac := hmac.New(sha1.New, key) | |||
hmac.Write([]byte(source)) | |||
signedBytes := hmac.Sum(nil) | |||
signedString := base64.StdEncoding.EncodeToString(signedBytes) | |||
return signedString | |||
} | |||
@@ -4,8 +4,8 @@ import ( | |||
"context" | |||
"fmt" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/request" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/response" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses" | |||
"net" | |||
"net/http" | |||
"runtime" | |||
@@ -22,13 +22,13 @@ type Client struct { | |||
Host string | |||
httpClient *http.Client | |||
isInsecure bool | |||
signer *auth.Creditial | |||
signer auth.Signer | |||
readTimeout time.Duration | |||
connectTimeout time.Duration | |||
config *Config | |||
} | |||
func (client *Client) InitWithOptions(host string, config *Config, creditial auth.Creditial) (err error) { | |||
func (client *Client) InitWithOptions(host string, config *Config, creditial auth.Credential) (err error) { | |||
client.httpClient = &http.Client{} | |||
if config.Transport != nil { | |||
@@ -41,6 +41,9 @@ func (client *Client) InitWithOptions(host string, config *Config, creditial aut | |||
client.httpClient.Timeout = config.Timeout | |||
} | |||
client.signer, err = auth.NewSignerWithCredential(credential, client.ProcessCommonRequestWithSigner) | |||
return nil | |||
} | |||
@@ -52,6 +55,16 @@ func (client *Client) InitWithConfig() (config *Config) { | |||
} | |||
} | |||
func (client *Client) ProcessCommonRequestWithSigner(request *requests.CommonRequest, signerInterface interface{}) (response *responses.CommonResponse, err error) { | |||
if signer, isSigner := signerInterface.(auth.Signer); isSigner { | |||
response = responses.NewCommonResponse() | |||
err = client.DoActionWithSigner(request, response, signer) | |||
return | |||
} | |||
panic("should not be here") | |||
} | |||
func Timeout(connectTimeout time.Duration) func(ctx context.Context, net, addr string) (c net.Conn, err error) { | |||
return func(ctx context.Context, network, address string) (c net.Conn, err error) { | |||
return (&net.Dialer{ | |||
@@ -61,7 +74,7 @@ func Timeout(connectTimeout time.Duration) func(ctx context.Context, net, addr s | |||
} | |||
} | |||
func (client *Client) setTimeOut(request request.AcsRequest) { | |||
func (client *Client) setTimeOut(request requests.AcsRequest) { | |||
readTimeout, connectTimeout := client.getTimeOut(request) | |||
client.httpClient.Timeout = readTimeout | |||
if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil { | |||
@@ -74,7 +87,7 @@ func (client *Client) setTimeOut(request request.AcsRequest) { | |||
} | |||
} | |||
func (client *Client) getTimeOut(request request.AcsRequest) (time.Duration, time.Duration) { | |||
func (client *Client) getTimeOut(request requests.AcsRequest) (time.Duration, time.Duration) { | |||
readTimeOut := defaultReadTimeout | |||
connectTimeOut := defaultConnectTimeout | |||
@@ -96,6 +109,10 @@ func (client *Client) getTimeOut(request request.AcsRequest) (time.Duration, tim | |||
return readTimeOut, connectTimeOut | |||
} | |||
func (client *Client) DoAction(request request.AcsRequest, response response.AcsResponse) (err error) { | |||
func (client *Client) DoAction(request requests.AcsRequest, response responses.AcsResponse) (err error) { | |||
return client.DoActionWithSigner(request, response, nil) | |||
} | |||
func (client *Client) DoActionWithSigner(request requests.AcsRequest, response responses.AcsResponse, signer auth.Signer) (err error) { | |||
return nil | |||
} |
@@ -1,17 +0,0 @@ | |||
package request | |||
import "time" | |||
type AcsRequest interface { | |||
GetReadTimeout() time.Duration | |||
GetConnectTimeout() time.Duration | |||
SetReadTimeout(readTimeOut time.Duration) | |||
SetConnectTimeout(connectTimeOut time.Duration) | |||
} | |||
type baseRequest struct { | |||
Scheme string | |||
Method string | |||
Host string | |||
Domain string | |||
} |
@@ -1,5 +0,0 @@ | |||
package request | |||
type RpcRequest struct { | |||
*baseRequest | |||
} |
@@ -0,0 +1,5 @@ | |||
package requests | |||
type CommonRequest struct { | |||
*baseRequest | |||
} |
@@ -0,0 +1,5 @@ | |||
package requests | |||
type HttpRequest struct { | |||
*baseRequest | |||
} |
@@ -0,0 +1,129 @@ | |||
package requests | |||
import ( | |||
"time" | |||
) | |||
const ( | |||
RPC = "RPC" | |||
ROA = "ROA" | |||
HTTP = "HTTP" | |||
HTTPS = "HTTPS" | |||
DefaultHttpPort = "80" | |||
GET = "GET" | |||
PUT = "PUT" | |||
POST = "POST" | |||
DELETE = "DELETE" | |||
PATCH = "PATCH" | |||
HEAD = "HEAD" | |||
OPTIONS = "OPTIONS" | |||
Json = "application/json" | |||
Xml = "application/xml" | |||
Raw = "application/octet-stream" | |||
Form = "application/x-www-form-urlencoded" | |||
Header = "Header" | |||
Query = "Query" | |||
Body = "Body" | |||
Path = "Path" | |||
HeaderSeparator = "\n" | |||
) | |||
type AcsRequest interface { | |||
GetReadTimeout() time.Duration | |||
GetConnectTimeout() time.Duration | |||
SetReadTimeout(readTimeOut time.Duration) | |||
SetConnectTimeout(connectTimeOut time.Duration) | |||
SetHTTPSInsecure(isInsecure bool) | |||
GetHTTPSInsecure() *bool | |||
GetQueryParams() map[string]string | |||
GetFormParams() map[string]string | |||
GetMethod() string | |||
SetStringToSign(stringToSign string) | |||
} | |||
type baseRequest struct { | |||
Scheme string | |||
Method string | |||
Host string | |||
Domain string | |||
From string | |||
ReadTimeout time.Duration | |||
ConnectTimeout time.Duration | |||
isInsecure *bool | |||
AcceptFormat string | |||
userAgent map[string]string | |||
product string | |||
version string | |||
QueryParams map[string]string | |||
Headers map[string]string | |||
FormParams map[string]string | |||
Content []byte | |||
queries string | |||
stringToSign string | |||
} | |||
func (request *baseRequest) GetMethod() string { | |||
return request.Method | |||
} | |||
func (request *baseRequest) GetFormParams() map[string]string { | |||
return request.FormParams | |||
} | |||
func (request *baseRequest) GetQueryParams() map[string]string { | |||
return request.QueryParams | |||
} | |||
func (request *baseRequest) SetHTTPSInsecure(isInsecure bool) { | |||
request.isInsecure = &isInsecure | |||
} | |||
func (request *baseRequest) GetHTTPSInsecure() *bool { | |||
return request.isInsecure | |||
} | |||
func (request *baseRequest) GetReadTimeout() time.Duration { | |||
return request.ReadTimeout | |||
} | |||
func (request *baseRequest) GetConnectTimeout() time.Duration { | |||
return request.ConnectTimeout | |||
} | |||
func (request *baseRequest) SetReadTimeout(readTimeOut time.Duration) { | |||
request.ReadTimeout = readTimeOut | |||
} | |||
func (request *baseRequest) SetConnectTimeout(connectTimeOut time.Duration) { | |||
request.ConnectTimeout = connectTimeOut | |||
} | |||
func (request *baseRequest) SetStringToSign(stringToSign string) { | |||
request.stringToSign = stringToSign | |||
} | |||
func defaultBaseRequest() (request *baseRequest) { | |||
request = &baseRequest{ | |||
Scheme: "", | |||
AcceptFormat: "JSON", | |||
Method: GET, | |||
QueryParams: make(map[string]string), | |||
Headers: map[string]string{ | |||
"x-sdk-client": "golang/1.0.0", | |||
"x-sdk-invoke-type": "normal", | |||
"Accept-Encoding": "identity", | |||
}, | |||
FormParams: make(map[string]string), | |||
} | |||
return | |||
} |
@@ -1,4 +0,0 @@ | |||
package response | |||
type AcsResponse interface { | |||
} |
@@ -0,0 +1,75 @@ | |||
package responses | |||
import ( | |||
"io/ioutil" | |||
"net/http" | |||
) | |||
type AcsResponse interface { | |||
IsSuccess() bool | |||
GetHttpStatus() int | |||
GetHttpHeaders() map[string][]string | |||
GetHttpContentString() string | |||
GetHttpContentBytes() []byte | |||
GetOriginHttpResponse() *http.Response | |||
parseFromHttpResponse(httpResponse *http.Response) error | |||
} | |||
type BaseResponse struct { | |||
httpStatus int | |||
httpHeaders map[string][]string | |||
httpContentString string | |||
httpContentBytes []byte | |||
originHttpResponse *http.Response | |||
} | |||
func (baseResponse *BaseResponse) GetHttpStatus() int { | |||
return baseResponse.httpStatus | |||
} | |||
func (baseResponse *BaseResponse) GetHttpHeaders() map[string][]string { | |||
return baseResponse.httpHeaders | |||
} | |||
func (baseResponse *BaseResponse) GetHttpContentString() string { | |||
return baseResponse.httpContentString | |||
} | |||
func (baseResponse *BaseResponse) GetHttpContentBytes() []byte { | |||
return baseResponse.httpContentBytes | |||
} | |||
func (baseResponse *BaseResponse) GetOriginHttpResponse() *http.Response { | |||
return baseResponse.originHttpResponse | |||
} | |||
func (baseResponse *BaseResponse) IsSuccess() bool { | |||
if baseResponse.GetHttpStatus() >= 200 && baseResponse.GetHttpStatus() < 300 { | |||
return true | |||
} | |||
return false | |||
} | |||
func (baseResponse *BaseResponse) parseFromHttpResponse(httpResponse *http.Response) (err error) { | |||
defer httpResponse.Body.Close() | |||
body, err := ioutil.ReadAll(httpResponse.Body) | |||
if err != nil { | |||
return | |||
} | |||
baseResponse.httpStatus = httpResponse.StatusCode | |||
baseResponse.httpHeaders = httpResponse.Header | |||
baseResponse.httpContentBytes = body | |||
baseResponse.httpContentString = string(body) | |||
baseResponse.originHttpResponse = httpResponse | |||
return | |||
} | |||
type CommonResponse struct { | |||
*BaseResponse | |||
} | |||
func NewCommonResponse() (response *CommonResponse) { | |||
return &CommonResponse{ | |||
BaseResponse: &BaseResponse{}, | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
package utils | |||
import "net/url" | |||
func GetUrlFormedMap(source map[string]string) (urlEncoded string) { | |||
urlEncoder := url.Values{} | |||
for key, value := range source { | |||
urlEncoder.Add(key, value) | |||
} | |||
urlEncoded = urlEncoder.Encode() | |||
return | |||
} |