@@ -3,16 +3,19 @@ package credentials | |||
type BaseCredential struct { | |||
AccessKeyId string | |||
AccessKeySecret string | |||
AccessKeyFrom string | |||
} | |||
type AccessKeyCredential struct { | |||
AccessKeyId string | |||
AccessKeySecret string | |||
AccessKeyFrom string | |||
} | |||
func (baseCred *BaseCredential) ToAccessKeyCredential() *AccessKeyCredential { | |||
return &AccessKeyCredential{ | |||
AccessKeyId: baseCred.AccessKeyId, | |||
AccessKeySecret: baseCred.AccessKeySecret, | |||
AccessKeyFrom: baseCred.AccessKeyFrom, | |||
} | |||
} |
@@ -10,8 +10,8 @@ import ( | |||
"time" | |||
) | |||
func signHttpRequest(request requests.AcsRequest, signer Signer) (err error) { | |||
err = completeHttpSignParams(request, signer) | |||
func signRpcRequest(request requests.AcsRequest, signer Signer) (err error) { | |||
err = completeRpcSignParams(request, signer) | |||
if err != nil { | |||
return | |||
} | |||
@@ -19,25 +19,37 @@ func signHttpRequest(request requests.AcsRequest, signer Signer) (err error) { | |||
delete(request.GetQueryParams(), "sign") | |||
} | |||
stringToSign := buildHttpStringToSign(request) | |||
stringToSign := buildRpcStringToSign(request) | |||
request.SetStringToSign(stringToSign) | |||
signature := signer.Sign(stringToSign, "&") | |||
request.GetQueryParams()["sign"] = signature | |||
return | |||
} | |||
func completeHttpSignParams(request requests.AcsRequest, signer Signer) (err error) { | |||
func completeRpcSignParams(request requests.AcsRequest, signer Signer) (err error) { | |||
var accessKeyFrom string | |||
if accessKeyFrom, err = signer.GetAccessKeyFrom(); err != nil { | |||
return | |||
} | |||
queryParams := request.GetQueryParams() | |||
queryParams["timestamp"] = fmt.Sprintf("%d", time.Now().Unix()) | |||
queryParams["access_time"] = fmt.Sprintf("%d", time.Now().Unix()) | |||
queryParams["access_key"], err = signer.GetAccessKeyId() | |||
queryParams["access_from"] = accessKeyFrom | |||
if err != nil { | |||
return | |||
} | |||
request.GetHeaders()["Content-type"] = requests.Form | |||
request.GetHeaders()["Gr-Sdk-From"] = accessKeyFrom | |||
formString := utils.GetUrlFormedMap(request.GetFormParams()) | |||
request.SetContent(bytes.NewBufferString(formString).Bytes()) | |||
return | |||
} | |||
func buildHttpStringToSign(request requests.AcsRequest) (stringToSign string) { | |||
func buildRpcStringToSign(request requests.AcsRequest) (stringToSign string) { | |||
signParams := make(map[string]string) | |||
for key, value := range request.GetQueryParams() { | |||
signParams[key] = value |
@@ -11,6 +11,7 @@ import ( | |||
type Signer interface { | |||
GetName() string | |||
GetAccessKeyId() (string, error) | |||
GetAccessKeyFrom() (string, error) | |||
Sign(stringToSign, secretSuffix string) string | |||
} | |||
@@ -28,6 +29,6 @@ func NewSignerWithCredential(credential Credential, commonApi func(request *requ | |||
func Sign(request requests.AcsRequest, signer Signer) (err error) { | |||
//TODO 根据rpc和roa两种风格签名,自行选择 | |||
err = signHttpRequest(request, signer) | |||
err = signRpcRequest(request, signer) | |||
return | |||
} |
@@ -15,6 +15,10 @@ func (signer *AccessKeySigner) GetAccessKeyId() (string, error) { | |||
return signer.credential.AccessKeyId, nil | |||
} | |||
func (signer *AccessKeySigner) GetAccessKeyFrom() (string, error) { | |||
return signer.credential.AccessKeyFrom, nil | |||
} | |||
func (*AccessKeySigner) GetName() string { | |||
return "HMAC-SHA1" | |||
} | |||
@@ -8,6 +8,7 @@ import ( | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses" | |||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils" | |||
"net" | |||
"net/http" | |||
"net/url" | |||
@@ -35,7 +36,7 @@ type Client struct { | |||
httpProxy string | |||
httpsProxy string | |||
noProxy string | |||
sourceFrom string | |||
debug utils.Debug | |||
} | |||
func (client *Client) GetNoProxy() string { | |||
@@ -75,20 +76,20 @@ func (client *Client) InitClientConfig() (config *Config) { | |||
} | |||
func (client *Client) InitWithAccessKey(accessKeyId, accessKeySecret, source string) (err error) { | |||
func (client *Client) InitWithAccessKey(accessKeyId, accessKeySecret, accessKeyFrom string) (err error) { | |||
config := client.InitWithConfig() | |||
credential := &credentials.BaseCredential{ | |||
AccessKeyId: accessKeyId, | |||
AccessKeySecret: accessKeySecret, | |||
AccessKeyFrom: accessKeyFrom, | |||
} | |||
return client.InitWithOptions(source, config, credential) | |||
return client.InitWithOptions(config, credential) | |||
} | |||
func (client *Client) InitWithOptions(source string, config *Config, credential auth.Credential) (err error) { | |||
func (client *Client) InitWithOptions(config *Config, credential auth.Credential) (err error) { | |||
client.httpClient = &http.Client{} | |||
client.config = config | |||
client.sourceFrom = source | |||
client.debug = utils.Init("sdk", true) | |||
if config.Transport != nil { | |||
client.httpClient.Transport = config.Transport | |||
@@ -279,7 +280,8 @@ func (client *Client) buildRequestWithSigner(request requests.AcsRequest, signer | |||
} | |||
userAgent := DefaultUserAgent | |||
httpRequest.Header.Set("User-Agent", userAgent) | |||
httpRequest.Header.Set("Gr-Sdk-From", client.sourceFrom) | |||
client.debug("%s", request.GetStringToSign()) | |||
return | |||
} | |||
@@ -9,7 +9,7 @@ type CommonRequest struct { | |||
} | |||
func (request *CommonRequest) TransToAscRequest() { | |||
httpReqeust := &HttpRequest{} | |||
httpReqeust := &RpcRequest{} | |||
httpReqeust.baseRequest = request.baseRequest | |||
httpReqeust.product = request.Product | |||
request.Ontology = httpReqeust | |||
@@ -4,8 +4,9 @@ import ( | |||
"errors" | |||
"fmt" | |||
"io" | |||
"log" | |||
"math/cmplx" | |||
"reflect" | |||
"strconv" | |||
"time" | |||
) | |||
@@ -65,6 +66,7 @@ type AcsRequest interface { | |||
SetContent(content []byte) | |||
SetDomain(host string) | |||
SetStringToSign(stringToSign string) | |||
GetStringToSign() string | |||
GetBodyReader() io.Reader | |||
addHeaderParam(key, value string) | |||
@@ -98,6 +100,10 @@ type baseRequest struct { | |||
stringToSign string | |||
} | |||
func (request *baseRequest) GetStringToSign() string { | |||
return request.stringToSign | |||
} | |||
func (request *baseRequest) SetContent(content []byte) { | |||
request.Content = content | |||
} | |||
@@ -200,17 +206,48 @@ func defaultBaseRequest() (request *baseRequest) { | |||
func InitParam(request AcsRequest) (err error) { | |||
reflectValue := reflect.ValueOf(request).Elem() | |||
err = flatRepeatedList(reflectValue, request, "") | |||
return nil | |||
} | |||
func flatRepeatedList(reflectValue reflect.Value, request AcsRequest, position string) (err error) { | |||
reflectType := reflectValue.Type() | |||
for i := 0; i < reflectType.NumField(); i++ { | |||
field := reflectType.Field(i) | |||
name, isContiansNameTag := field.Tag.Lookup("field") | |||
fieldPosition, _ := field.Tag.Lookup("position") | |||
log.Println(name, field) | |||
fieldPosition := position | |||
if fieldPosition == "" { | |||
fieldPosition, _ = field.Tag.Lookup("position") | |||
} | |||
fieldDefault, _ := field.Tag.Lookup("default") | |||
if isContiansNameTag { | |||
err = addParam(request, fieldPosition, name, reflectValue.Field(i).String()) | |||
var value string | |||
switch field.Type.Kind() { | |||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | |||
value = strconv.FormatInt(reflectValue.Field(i).Int(), 10) | |||
case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | |||
value = strconv.FormatUint(reflectValue.Field(i).Uint(), 10) | |||
case reflect.Float32, reflect.Float64: | |||
value = strconv.FormatFloat(reflectValue.Field(i).Float(), 'E', -1, 64) | |||
case reflect.Bool: | |||
value = strconv.FormatBool(reflectValue.Field(i).Bool()) | |||
case reflect.Complex64, reflect.Complex128: | |||
value = fmt.Sprint(cmplx.Sqrt(reflectValue.Field(i).Complex())) | |||
default: | |||
value = reflectValue.Field(i).String() | |||
} | |||
if len(value) == 0 { | |||
value = fieldDefault | |||
} | |||
err = addParam(request, fieldPosition, name, value) | |||
} | |||
} | |||
return nil | |||
return | |||
} | |||
func addParam(request AcsRequest, position, key, value string) (err error) { | |||
@@ -7,16 +7,16 @@ import ( | |||
"strings" | |||
) | |||
type HttpRequest struct { | |||
type RpcRequest struct { | |||
*baseRequest | |||
} | |||
func (request *HttpRequest) init() { | |||
func (request *RpcRequest) init() { | |||
request.baseRequest = defaultBaseRequest() | |||
request.Method = POST | |||
} | |||
func (request *HttpRequest) BuildUrl() string { | |||
func (request *RpcRequest) BuildUrl() string { | |||
url := fmt.Sprintf("%s://%s", strings.ToLower(request.Scheme), request.Domain) | |||
if len(request.Port) > 0 { | |||
url = fmt.Sprintf("%s:%s", url, request.Port) | |||
@@ -24,24 +24,25 @@ func (request *HttpRequest) BuildUrl() string { | |||
return url + request.BuildQueries() | |||
} | |||
func (request *HttpRequest) BuildQueries() string { | |||
func (request *RpcRequest) BuildQueries() string { | |||
path := strings.TrimLeft(strings.TrimSpace(request.GetActionName()), "/") | |||
request.queries = "/" + path + "?" + utils.GetUrlFormedMap(request.QueryParams) | |||
return request.queries | |||
} | |||
func (request *HttpRequest) GetActionName() string { | |||
func (request *RpcRequest) GetActionName() string { | |||
return request.actionName | |||
} | |||
func (request *HttpRequest) InitWithApiInfo(domain, version, urlPath string) { | |||
func (request *RpcRequest) InitWithApiInfo(domain, version, urlPath string) *RpcRequest { | |||
request.init() | |||
request.SetDomain(domain) | |||
request.version = version | |||
request.actionName = urlPath | |||
return request | |||
} | |||
func (request *HttpRequest) GetBodyReader() io.Reader { | |||
func (request *RpcRequest) GetBodyReader() io.Reader { | |||
if request.FormParams != nil && len(request.FormParams) > 0 { | |||
formString := utils.GetUrlFormedMap(request.FormParams) | |||
return strings.NewReader(formString) |
@@ -0,0 +1,10 @@ | |||
package requests | |||
import "strconv" | |||
type Interger string | |||
func (i Interger) ToInt() int { | |||
a, _ := strconv.ParseInt(string(i), 10, 64) | |||
return int(a) | |||
} |
@@ -0,0 +1,18 @@ | |||
package utils | |||
import "fmt" | |||
type Debug func(format string, v ...interface{}) | |||
var hookPrint = func(input string) { | |||
fmt.Println(input) | |||
} | |||
func Init(flag string, enable bool) Debug { | |||
return func(format string, v ...interface{}) { | |||
if enable { | |||
hookPrint(fmt.Sprintf(format, v...)) | |||
} | |||
} | |||
} |
@@ -6,11 +6,10 @@ import ( | |||
) | |||
type SendSmsRequest struct { | |||
*requests.HttpRequest | |||
User string `position:"Query" field:"user" default:"-" ` | |||
Code string `position:"Query" field:"code" default:"-" ` | |||
Params string `position:"Query" field:"params" default:"-" ` | |||
Test string `position:"Body" field:"test" default:"-" ` | |||
*requests.RpcRequest | |||
User string `position:"Query" field:"user" default:"" ` | |||
Code string `position:"Query" field:"code" default:"" ` | |||
Params string `position:"Query" field:"params" default:"" ` | |||
} | |||
type SendSmsResponseData struct { | |||
@@ -25,12 +24,10 @@ type SendSmsResponse struct { | |||
func CreateSendSmsRequest() (req *SendSmsRequest) { | |||
req = &SendSmsRequest{ | |||
HttpRequest: &requests.HttpRequest{}, | |||
RpcRequest: &requests.RpcRequest{}, | |||
} | |||
req.InitWithApiInfo(HOST, VERSION, "/api/sms/send") | |||
req.Method = requests.POST | |||
req.Scheme = requests.HTTP | |||
req.Method = requests.GET | |||
return | |||
} | |||