fork from gaore-common-sdk-go
This commit is contained in:
commit
1bd1a66cfe
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### Example user template template
|
||||
### Example user template
|
||||
|
||||
# IntelliJ project files
|
||||
.idea
|
||||
*.iml
|
||||
out
|
||||
gen
|
179
README.md
Normal file
179
README.md
Normal file
@ -0,0 +1,179 @@
|
||||
# gaore-common-sdk-go
|
||||
|
||||
### 1.目录架构
|
||||
```
|
||||
├── README.md
|
||||
├── sdk
|
||||
│ ├── auth `认证类`
|
||||
│ ├── client.go `客户端主入口类`
|
||||
│ ├── config.go
|
||||
│ ├── requests `请求类`
|
||||
│ ├── responses `响应类`
|
||||
│ └── utils `工具类`
|
||||
└── services
|
||||
└── jedi
|
||||
```
|
||||
### 2.引入
|
||||
```go
|
||||
go get -u golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk
|
||||
```
|
||||
或 Go Module
|
||||
```go
|
||||
import "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
|
||||
```
|
||||
|
||||
### 3.服务端认证及返回处理
|
||||
|
||||
调用 `auth.UnSign` 方法,提供`*http.Request`请求实例,以及`signer.Signer` 签名器(签名器需要包括凭据)
|
||||
即可完成整个验签过程
|
||||
|
||||
这里以`beego`为例 :
|
||||
```go
|
||||
package applications
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/context"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth"
|
||||
"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/grlogs"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 过滤器
|
||||
beego.InsertFilter("/api/*", beego.BeforeRouter, func(context *context.Context) {
|
||||
httpRequest := context.Request
|
||||
err := auth.UnSign(httpRequest, signers.NewAccessKeySigner(&credentials.AccessKeyCredential{
|
||||
AccessKeyId: "aaaaaa",
|
||||
AccessKeySecret: "bbbbbb",
|
||||
AccessKeyFrom: context.Input.Param("access_from"),
|
||||
}))
|
||||
|
||||
if err != nil {
|
||||
resp := response.NewJsonByDefaultFailed()
|
||||
resp.Msg = err.Error()
|
||||
resp.Code = 10086
|
||||
|
||||
var (
|
||||
hasIndent = beego.BConfig.RunMode != beego.PROD
|
||||
)
|
||||
context.Output.Status = 500
|
||||
context.Output.JSON(resp, hasIndent, false)
|
||||
}
|
||||
})
|
||||
}
|
||||
```
|
||||
服务端返回的响应体为以下结构的json字符流, `code`,`status`,`msg` 这三个字段*最好*要包含且数据类型要一致 , `data` 部分为业务内容,自行定义
|
||||
```json
|
||||
{
|
||||
"code": 1001,
|
||||
"msg": "不能为空",
|
||||
"status": false,
|
||||
"data": {
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.sdk编写
|
||||
|
||||
在`services`目录下以服务归类新建文件夹, 如`jedi`为短信服务,以 `RpcRequest` 和 `BaseResponse` 以基类写好请求子类和响应子类。一个请求接口对应一对请求和响应类。
|
||||
|
||||
```go
|
||||
import "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
|
||||
|
||||
const (
|
||||
HOST = "jedi" // 如果非全域名会自动补全.gaore.com , 如jedi 会自动补全jedi.goare.com, 也可以打全域名 test.uu89.com
|
||||
VERSION = "2020-08-04"
|
||||
)
|
||||
|
||||
|
||||
type Client struct {
|
||||
sdk.Client
|
||||
}
|
||||
|
||||
func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
|
||||
client = &Client{}
|
||||
err = client.InitWithAccessKey(accesskey, secrect, source)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) Test(req *DemoTestRequest) (response *DemoTestResponse, err error) {
|
||||
response = CreateDemoTestResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
||||
```
|
||||
|
||||
请求类,对参数用标签解释, 如 `position:"Query" field:"param_1" default:""` , 有三个字段 `position` , `field`, `default`
|
||||
|
||||
- `position` 为标志该参数为请求体对应的位置, `Query` query参数, `Body` post请求体参数, `Head`请求头参数
|
||||
|
||||
- `field` 解释成参数实际名称
|
||||
|
||||
- `default` 默认值
|
||||
|
||||
```go
|
||||
type DemoTestRequest struct {
|
||||
*requests.RpcRequest
|
||||
Param1 string `position:"Query" field:"param_1" default:"" `
|
||||
Param2 int `position:"Query" field:"param_2" default:"10086" `
|
||||
Param3 bool `position:"Query" field:"param_3" default:"false" `
|
||||
}
|
||||
```
|
||||
对应解释成http请求为:
|
||||
```go
|
||||
GET param_1=111¶m_2=10086¶m_3=false
|
||||
```
|
||||
|
||||
完整示例:
|
||||
```go
|
||||
package jedi
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
// 定义请求体
|
||||
type DemoTestRequest struct {
|
||||
*requests.RpcRequest
|
||||
Param1 string `position:"Query" field:"param_1" default:"" `
|
||||
Param2 int `position:"Query" field:"param_2" default:"10086" `
|
||||
Param3 bool `position:"Query" field:"param_3" default:"false" `
|
||||
}
|
||||
|
||||
func CreateDemoTestRequest() (req *DemoTestRequest) {
|
||||
req = &DemoTestRequest{RpcRequest: &requests.RpcRequest{}}
|
||||
// InitWithApiInfo 初始化请求,有三个参数,域名,版本,和路径
|
||||
// 域名参数如果非全域名会自动补全.gaore.com , 如jedi 会自动补全jedi.goare.com, 也可以打全域名 test.uu89.com
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/sms/Index")
|
||||
// 定义 请求方法 POST 或 GET
|
||||
req.Method = requests.GET
|
||||
return
|
||||
}
|
||||
|
||||
// 定义响应体
|
||||
type DemoTestResponse struct {
|
||||
*responses.BaseResponse
|
||||
Data DemoTestResponseData `json:"data"`
|
||||
}
|
||||
|
||||
type DemoTestResponseData struct {
|
||||
Account string `json:"account"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
func CreateDemoTestResponse() *DemoTestResponse {
|
||||
return &DemoTestResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
终端调试打开方式, 需要在系统环境变量上加入(三选一):
|
||||
```
|
||||
DEBUG=sdk,signer,request
|
||||
```
|
21
sdk/auth/credentials/access_key_credential.go
Normal file
21
sdk/auth/credentials/access_key_credential.go
Normal file
@ -0,0 +1,21 @@
|
||||
package credentials
|
||||
|
||||
type BaseCredential struct {
|
||||
AccessKeyId string `json:"access_key_id" yaml:"access_key_id"`
|
||||
AccessKeySecret string `json:"access_key_secret" yaml:"access_key_secret"`
|
||||
AccessKeyFrom string `json:"access_key_from" yaml:"access_key_from"`
|
||||
}
|
||||
|
||||
type AccessKeyCredential struct {
|
||||
AccessKeyId string `json:"access_key_id" yaml:"access_key_id"`
|
||||
AccessKeySecret string `json:"access_key_secret" yaml:"access_key_secret"`
|
||||
AccessKeyFrom string `json:"access_key_from" yaml:"access_key_from"`
|
||||
}
|
||||
|
||||
func (baseCred *BaseCredential) ToAccessKeyCredential() *AccessKeyCredential {
|
||||
return &AccessKeyCredential{
|
||||
AccessKeyId: baseCred.AccessKeyId,
|
||||
AccessKeySecret: baseCred.AccessKeySecret,
|
||||
AccessKeyFrom: baseCred.AccessKeyFrom,
|
||||
}
|
||||
}
|
13
sdk/auth/credentials/ali_appcode_credential.go
Normal file
13
sdk/auth/credentials/ali_appcode_credential.go
Normal file
@ -0,0 +1,13 @@
|
||||
package credentials
|
||||
|
||||
type AliAppcodeCredential struct {
|
||||
AccessKeyId string `json:"access_key_id" yaml:"access_key_id"`
|
||||
AccessKeySecret string `json:"access_key_secret" yaml:"access_key_secret"`
|
||||
}
|
||||
|
||||
func NewAliAppcodeCredential(accessKeyId, accessKeySecret string) *AliAppcodeCredential {
|
||||
return &AliAppcodeCredential{
|
||||
AccessKeyId: accessKeyId,
|
||||
AccessKeySecret: accessKeySecret,
|
||||
}
|
||||
}
|
15
sdk/auth/credentials/sts_token_credential.go
Normal file
15
sdk/auth/credentials/sts_token_credential.go
Normal file
@ -0,0 +1,15 @@
|
||||
package credentials
|
||||
|
||||
type StdTokenCredential struct {
|
||||
AccessKeyId string `json:"access_key_id" yaml:"access_key_id"`
|
||||
AccessKeySecret string `json:"access_key_secret" yaml:"access_key_secret"`
|
||||
AccessKeyFrom string `json:"access_key_from" yaml:"access_key_from"`
|
||||
}
|
||||
|
||||
func NewStsTokenCredential(accessKeyId, accessKeySecret, accessFrom string) *StdTokenCredential {
|
||||
return &StdTokenCredential{
|
||||
AccessKeyId: accessKeyId,
|
||||
AccessKeySecret: accessKeySecret,
|
||||
AccessKeyFrom: accessFrom,
|
||||
}
|
||||
}
|
12
sdk/auth/crediantial.go
Normal file
12
sdk/auth/crediantial.go
Normal file
@ -0,0 +1,12 @@
|
||||
package auth
|
||||
|
||||
import "golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
|
||||
|
||||
var debug utils.Debug
|
||||
|
||||
func init() {
|
||||
debug = utils.Init("signer")
|
||||
}
|
||||
|
||||
type Credential interface {
|
||||
}
|
160
sdk/auth/rali_signature_composer.go
Normal file
160
sdk/auth/rali_signature_composer.go
Normal file
@ -0,0 +1,160 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func signRaliRequest(request requests.AcsRequest, signer Signer) (err error) {
|
||||
err = completeRaliSignParams(request, signer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
stringToSign := buildRaliStringToSign(request)
|
||||
request.SetStringToSign(stringToSign)
|
||||
signature := signer.Sign(stringToSign, "")
|
||||
request.GetHeaders()["X-Ca-Signature"] = signature
|
||||
|
||||
debug("GrSdk sign: %s", signature)
|
||||
debug("GrSdk sign string: %s", strings.ReplaceAll(stringToSign, "\n", "#"))
|
||||
debug("GrSdk sign: \r\n")
|
||||
return
|
||||
}
|
||||
|
||||
func completeRaliSignParams(request requests.AcsRequest, signer Signer) (err error) {
|
||||
|
||||
request.GetHeaders()["X-Ca-Timestamp"] = fmt.Sprintf("%d", time.Now().Unix()*1000)
|
||||
request.GetHeaders()["X-Ca-Signature-Method"] = signer.GetName()
|
||||
request.GetHeaders()["X-Ca-Nonce"] = utils.GetUUID()
|
||||
request.GetHeaders()["X-Ca-Key"], err = signer.GetAccessKeyId()
|
||||
|
||||
if request.GetEnv() != "" {
|
||||
request.GetHeaders()["X-Ca-Stage"] = request.GetEnv()
|
||||
}
|
||||
|
||||
if request.GetMethod() == requests.POST {
|
||||
request.GetHeaders()["Content-type"] = requests.Form
|
||||
}
|
||||
|
||||
formString := utils.GetUrlFormedMap(request.GetFormParams())
|
||||
request.SetContent(bytes.NewBufferString(formString).Bytes())
|
||||
return
|
||||
}
|
||||
|
||||
func buildRaliSignHeader(request requests.AcsRequest) (str1, str2 string) {
|
||||
|
||||
headParams := make(map[string]string)
|
||||
signatureHeaders := make([]string, 0)
|
||||
|
||||
for key, val := range request.GetHeaders() {
|
||||
headParams[key] = val
|
||||
}
|
||||
|
||||
delete(headParams, "X-Ca-Signature")
|
||||
delete(headParams, "X-Ca-Signature-Headers")
|
||||
delete(headParams, "Accept")
|
||||
delete(headParams, "Content-MD5")
|
||||
delete(headParams, "Content-Type")
|
||||
delete(headParams, "Date")
|
||||
|
||||
for key, _ := range headParams {
|
||||
signatureHeaders = append(signatureHeaders, key)
|
||||
}
|
||||
|
||||
sort.Strings(signatureHeaders)
|
||||
|
||||
for _, key := range signatureHeaders {
|
||||
str1 += fmt.Sprintf("%s:%s\n", key, headParams[key])
|
||||
}
|
||||
|
||||
return strings.TrimRight(str1, "\n"), strings.Join(signatureHeaders, ",")
|
||||
}
|
||||
|
||||
func buildRaliStringToSign(request requests.AcsRequest) (stringToSign string) {
|
||||
signParams := make(map[string]string)
|
||||
for key, value := range request.GetQueryParams() {
|
||||
signParams[key] = value
|
||||
}
|
||||
|
||||
if strings.ToUpper(request.GetMethod()) == requests.POST {
|
||||
for key, value := range request.GetFormParams() {
|
||||
signParams[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
str1, str2 := buildRaliSignHeader(request)
|
||||
|
||||
stringToSign = request.GetMethod() + "\n"
|
||||
stringToSign += request.GetHeaders()["Accept"] + "\n\n"
|
||||
stringToSign += request.GetHeaders()["Content-type"] + "\n\n"
|
||||
stringToSign += str1 + "\n"
|
||||
stringToSign += request.GetActionName() + "?" + utils.GetUrlByKeySort(signParams)
|
||||
request.GetHeaders()["X-Ca-Signature-Headers"] = str2
|
||||
|
||||
//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
|
||||
}
|
||||
|
||||
func unsignRaliRequest(request *http.Request, signer Signer) (err error) {
|
||||
signParams := make(map[string]string)
|
||||
for key, value := range request.URL.Query() {
|
||||
signParams[key] = value[0]
|
||||
}
|
||||
|
||||
if strings.ToUpper(request.Method) == requests.POST {
|
||||
for key, value := range request.Form {
|
||||
signParams[key] = value[0]
|
||||
}
|
||||
}
|
||||
|
||||
if accessKey, err := signer.GetAccessKeyId(); err != nil {
|
||||
return err
|
||||
} else if accessKey == "" {
|
||||
return errors.New("access key is not allow empty")
|
||||
} else if accessKey != signParams["access_key"] {
|
||||
return errors.New("illegal access key")
|
||||
}
|
||||
|
||||
signValue, ok := signParams["sign"]
|
||||
if !ok {
|
||||
return errors.New("sign value is not exists")
|
||||
} else {
|
||||
delete(signParams, "sign")
|
||||
}
|
||||
|
||||
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.Method + "&%2F&" + stringToSign
|
||||
debug("GrSdk sign: %s", stringToSign)
|
||||
|
||||
if timestamp, err := strconv.ParseInt(signParams["access_time"], 10, 64); err != nil {
|
||||
return err
|
||||
} else {
|
||||
if time.Unix(timestamp, 0).Before(time.Now().Add(-5 * time.Minute)) {
|
||||
err = errors.New("sign timeout 5 minute")
|
||||
}
|
||||
}
|
||||
|
||||
if signer.Sign(stringToSign, "&") != signValue {
|
||||
return errors.New("sign string is not correct")
|
||||
}
|
||||
return
|
||||
}
|
128
sdk/auth/roa_signature_composer.go
Normal file
128
sdk/auth/roa_signature_composer.go
Normal file
@ -0,0 +1,128 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func signRoaRequest(request requests.AcsRequest, signer Signer) (err error) {
|
||||
err = completeRoaSignParams(request, signer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if _, isContainsSign := request.GetQueryParams()["sign"]; isContainsSign {
|
||||
delete(request.GetQueryParams(), "sign")
|
||||
}
|
||||
|
||||
stringToSign := buildRoaStringToSign(request)
|
||||
request.SetStringToSign(stringToSign)
|
||||
signature := signer.Sign(stringToSign, "&")
|
||||
request.GetQueryParams()["sign"] = signature
|
||||
debug("GrSdk sign: %s", signature)
|
||||
debug("GrSdk sign string: %s", stringToSign)
|
||||
debug("GrSdk sign: \r\n")
|
||||
return
|
||||
}
|
||||
|
||||
func completeRoaSignParams(request requests.AcsRequest, signer Signer) (err error) {
|
||||
|
||||
var accessKeyFrom string
|
||||
if accessKeyFrom, err = signer.GetAccessKeyFrom(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
queryParams := request.GetQueryParams()
|
||||
queryParams["access_time"] = fmt.Sprintf("%d", time.Now().Unix())
|
||||
queryParams["access_key"], err = signer.GetAccessKeyId()
|
||||
queryParams["access_from"] = accessKeyFrom
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if request.GetMethod() == requests.POST {
|
||||
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 buildRoaStringToSign(request requests.AcsRequest) (stringToSign string) {
|
||||
signParams := make(map[string]string)
|
||||
for key, value := range request.GetQueryParams() {
|
||||
signParams[key] = value
|
||||
}
|
||||
|
||||
if strings.ToUpper(request.GetMethod()) == requests.POST {
|
||||
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
|
||||
}
|
||||
|
||||
func unsignRoaRequest(request *http.Request, signer Signer) (err error) {
|
||||
signParams := make(map[string]string)
|
||||
for key, value := range request.URL.Query() {
|
||||
signParams[key] = value[0]
|
||||
}
|
||||
|
||||
if strings.ToUpper(request.Method) == requests.POST {
|
||||
for key, value := range request.Form {
|
||||
signParams[key] = value[0]
|
||||
}
|
||||
}
|
||||
|
||||
if accessKey, err := signer.GetAccessKeyId(); err != nil {
|
||||
return err
|
||||
} else if accessKey == "" {
|
||||
return errors.New("access key is not allow empty")
|
||||
} else if accessKey != signParams["access_key"] {
|
||||
return errors.New("illegal access key")
|
||||
}
|
||||
|
||||
signValue, ok := signParams["sign"]
|
||||
if !ok {
|
||||
return errors.New("sign value is not exists")
|
||||
} else {
|
||||
delete(signParams, "sign")
|
||||
}
|
||||
|
||||
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.Method + "&%2F&" + stringToSign
|
||||
debug("GrSdk sign: %s", stringToSign)
|
||||
|
||||
if timestamp, err := strconv.ParseInt(signParams["access_time"], 10, 64); err != nil {
|
||||
return err
|
||||
} else {
|
||||
if time.Unix(timestamp, 0).Before(time.Now().Add(-5 * time.Minute)) {
|
||||
err = errors.New("sign timeout 5 minute")
|
||||
}
|
||||
}
|
||||
|
||||
if signer.Sign(stringToSign, "&") != signValue {
|
||||
return errors.New("sign string is not correct")
|
||||
}
|
||||
return
|
||||
}
|
126
sdk/auth/rpc_signature_composer.go
Normal file
126
sdk/auth/rpc_signature_composer.go
Normal file
@ -0,0 +1,126 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func signRpcRequest(request requests.AcsRequest, signer Signer) (err error) {
|
||||
err = completeRpcSignParams(request, signer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if _, isContainsSign := request.GetQueryParams()["sign"]; isContainsSign {
|
||||
delete(request.GetQueryParams(), "sign")
|
||||
}
|
||||
|
||||
stringToSign := buildRpcStringToSign(request)
|
||||
request.SetStringToSign(stringToSign)
|
||||
signature := signer.Sign(stringToSign, "&")
|
||||
request.GetQueryParams()["sign"] = signature
|
||||
debug("GrSdk sign: %s", signature)
|
||||
debug("GrSdk sign string: %s", stringToSign)
|
||||
debug("GrSdk sign: \r\n")
|
||||
return
|
||||
}
|
||||
|
||||
func completeRpcSignParams(request requests.AcsRequest, signer Signer) (err error) {
|
||||
|
||||
var accessKeyFrom string
|
||||
if accessKeyFrom, err = signer.GetAccessKeyFrom(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
queryParams := request.GetQueryParams()
|
||||
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 buildRpcStringToSign(request requests.AcsRequest) (stringToSign string) {
|
||||
signParams := make(map[string]string)
|
||||
for key, value := range request.GetQueryParams() {
|
||||
signParams[key] = value
|
||||
}
|
||||
|
||||
if strings.ToUpper(request.GetMethod()) == requests.POST {
|
||||
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
|
||||
}
|
||||
|
||||
func unsignRpcRequest(request *http.Request, signer Signer) (err error) {
|
||||
signParams := make(map[string]string)
|
||||
for key, value := range request.URL.Query() {
|
||||
signParams[key] = value[0]
|
||||
}
|
||||
|
||||
if strings.ToUpper(request.Method) == requests.POST {
|
||||
for key, value := range request.Form {
|
||||
signParams[key] = value[0]
|
||||
}
|
||||
}
|
||||
|
||||
if accessKey, err := signer.GetAccessKeyId(); err != nil {
|
||||
return err
|
||||
} else if accessKey == "" {
|
||||
return errors.New("access key is not allow empty")
|
||||
} else if accessKey != signParams["access_key"] {
|
||||
return errors.New("illegal access key")
|
||||
}
|
||||
|
||||
signValue, ok := signParams["sign"]
|
||||
if !ok {
|
||||
return errors.New("sign value is not exists")
|
||||
} else {
|
||||
delete(signParams, "sign")
|
||||
}
|
||||
|
||||
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.Method + "&%2F&" + stringToSign
|
||||
debug("GrSdk sign: %s", stringToSign)
|
||||
|
||||
if timestamp, err := strconv.ParseInt(signParams["access_time"], 10, 64); err != nil {
|
||||
return err
|
||||
} else {
|
||||
if time.Unix(timestamp, 0).Before(time.Now().Add(-5 * time.Minute)) {
|
||||
err = errors.New("sign timeout 5 minute")
|
||||
}
|
||||
}
|
||||
|
||||
if signer.Sign(stringToSign, "&") != signValue {
|
||||
return errors.New("sign string is not correct")
|
||||
}
|
||||
return
|
||||
}
|
56
sdk/auth/signer.go
Normal file
56
sdk/auth/signer.go
Normal file
@ -0,0 +1,56 @@
|
||||
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"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Signer interface {
|
||||
GetName() string
|
||||
GetAccessKeyId() (string, error)
|
||||
GetAccessKeyFrom() (string, error)
|
||||
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)
|
||||
case *credentials.BaseCredential:
|
||||
signer = signers.NewAccessKeySigner(instance.ToAccessKeyCredential())
|
||||
case *credentials.StdTokenCredential:
|
||||
signer = signers.NewStsTokenSigner(instance)
|
||||
case *credentials.AliAppcodeCredential:
|
||||
signer = signers.NewAliAppcodeSigner(instance)
|
||||
default:
|
||||
err = errors.New("UnsupportedCredentialErrorCode = SDK.UnsupportedCredential")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Sign(request requests.AcsRequest, signer Signer) (err error) {
|
||||
switch signer.(type) {
|
||||
case *signers.AliAppcodeSigner:
|
||||
err = signRaliRequest(request, signer)
|
||||
return
|
||||
}
|
||||
|
||||
//TODO 根据rpc和roa两种风格签名,自行选择
|
||||
switch request.GetStyle() {
|
||||
case requests.RPC:
|
||||
err = signRpcRequest(request, signer)
|
||||
case requests.ROA:
|
||||
err = signRoaRequest(request, signer)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func UnSign(request *http.Request, signer Signer) (err error) {
|
||||
//TODO 根据rpc和roa两种风格签名,自行选择
|
||||
err = unsignRpcRequest(request, signer)
|
||||
return
|
||||
}
|
44
sdk/auth/signers/access_key_siginer.go
Normal file
44
sdk/auth/signers/access_key_siginer.go
Normal file
@ -0,0 +1,44 @@
|
||||
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 (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"
|
||||
}
|
||||
|
||||
func (signer *AccessKeySigner) Sign(stringToSign, secretSuffix string) string {
|
||||
secret := signer.credential.AccessKeySecret + secretSuffix
|
||||
return ShaHmac1(stringToSign, secret)
|
||||
}
|
||||
|
||||
func NewAccessKeySigner(credential *credentials.AccessKeyCredential) *AccessKeySigner {
|
||||
return &AccessKeySigner{
|
||||
credential: credential,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
43
sdk/auth/signers/ali_appcode_signer.go
Normal file
43
sdk/auth/signers/ali_appcode_signer.go
Normal file
@ -0,0 +1,43 @@
|
||||
package signers
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials"
|
||||
)
|
||||
|
||||
type AliAppcodeSigner struct {
|
||||
credential *credentials.AliAppcodeCredential
|
||||
}
|
||||
|
||||
func (signer *AliAppcodeSigner) GetName() string {
|
||||
return "HmacSHA256"
|
||||
}
|
||||
|
||||
func (signer *AliAppcodeSigner) GetAccessKeyId() (string, error) {
|
||||
return signer.credential.AccessKeyId, nil
|
||||
}
|
||||
|
||||
func (signer *AliAppcodeSigner) GetAccessKeyFrom() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (signer *AliAppcodeSigner) Sign(stringToSign, secretSuffix string) string {
|
||||
secret := signer.credential.AccessKeySecret + secretSuffix
|
||||
return ShaHmac256(stringToSign, secret)
|
||||
}
|
||||
|
||||
func NewAliAppcodeSigner(credential *credentials.AliAppcodeCredential) *AliAppcodeSigner {
|
||||
return &AliAppcodeSigner{
|
||||
credential: credential,
|
||||
}
|
||||
}
|
||||
|
||||
func ShaHmac256(source, secret string) string {
|
||||
key := []byte(secret)
|
||||
hmac1 := hmac.New(sha256.New, key)
|
||||
hmac1.Write([]byte(source))
|
||||
signedString := base64.StdEncoding.EncodeToString(hmac1.Sum(nil))
|
||||
return signedString
|
||||
}
|
41
sdk/auth/signers/sts_token_signer.go
Normal file
41
sdk/auth/signers/sts_token_signer.go
Normal file
@ -0,0 +1,41 @@
|
||||
package signers
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth/credentials"
|
||||
)
|
||||
|
||||
type StsTokenSigner struct {
|
||||
credential *credentials.StdTokenCredential
|
||||
}
|
||||
|
||||
func (signer *StsTokenSigner) GetAccessKeyId() (string, error) {
|
||||
return signer.credential.AccessKeyId, nil
|
||||
}
|
||||
|
||||
func (signer *StsTokenSigner) GetAccessKeyFrom() (string, error) {
|
||||
return signer.credential.AccessKeyFrom, nil
|
||||
}
|
||||
|
||||
func (*StsTokenSigner) GetName() string {
|
||||
return "MD5"
|
||||
}
|
||||
|
||||
func (signer *StsTokenSigner) Sign(stringToSign, secretSuffix string) string {
|
||||
secret := signer.credential.AccessKeySecret + secretSuffix
|
||||
return Md5(stringToSign, secret)
|
||||
}
|
||||
|
||||
func NewStsTokenSigner(credential *credentials.StdTokenCredential) *StsTokenSigner {
|
||||
return &StsTokenSigner{
|
||||
credential: credential,
|
||||
}
|
||||
}
|
||||
|
||||
func Md5(source, secret string) string {
|
||||
data := []byte(fmt.Sprintf("%s##%s", secret, source))
|
||||
has := md5.Sum(data)
|
||||
md5str := fmt.Sprintf("%x", has)
|
||||
return md5str
|
||||
}
|
357
sdk/client.go
Normal file
357
sdk/client.go
Normal file
@ -0,0 +1,357 @@
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/auth"
|
||||
"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/http/httputil"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var Version = "0.0.1"
|
||||
var defaultConnectTimeout = 5 * time.Second
|
||||
var defaultReadTimeout = 10 * time.Second
|
||||
var defaultDomain = ".gaore.com"
|
||||
var DefaultUserAgent = fmt.Sprintf("GaoreGoSdk (%s;%s) Golang/%s Core/%s", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), Version)
|
||||
|
||||
var debug utils.Debug
|
||||
|
||||
func init() {
|
||||
debug = utils.Init("sdk")
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
Host string
|
||||
httpClient *http.Client
|
||||
isInsecure bool
|
||||
signer auth.Signer
|
||||
readTimeout time.Duration
|
||||
connectTimeout time.Duration
|
||||
config *Config
|
||||
httpProxy string
|
||||
httpsProxy string
|
||||
noProxy string
|
||||
}
|
||||
|
||||
func (client *Client) GetNoProxy() string {
|
||||
return client.noProxy
|
||||
}
|
||||
|
||||
func (client *Client) SetNoProxy(noProxy string) {
|
||||
client.noProxy = noProxy
|
||||
}
|
||||
|
||||
func (client *Client) GetHttpsProxy() string {
|
||||
return client.httpsProxy
|
||||
}
|
||||
|
||||
func (client *Client) SetHttpsProxy(httpsProxy string) {
|
||||
client.httpsProxy = httpsProxy
|
||||
}
|
||||
|
||||
func (client *Client) SetHttpProxy(httpProxy string) {
|
||||
client.httpProxy = httpProxy
|
||||
}
|
||||
|
||||
func (client *Client) GetHttpProxy() string {
|
||||
return client.httpProxy
|
||||
}
|
||||
|
||||
func (client *Client) GetHTTPSInsecure() bool {
|
||||
return client.isInsecure
|
||||
}
|
||||
|
||||
func (client *Client) InitClientConfig() (config *Config) {
|
||||
if client.config != nil {
|
||||
return client.config
|
||||
} else {
|
||||
return NewConfig()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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(config, credential)
|
||||
}
|
||||
|
||||
func (client *Client) InitWithAliAppcode(accessKeyId, accessKeySecret string, env ...string) (err error) {
|
||||
config := client.InitWithConfig()
|
||||
credential := credentials.NewAliAppcodeCredential(accessKeyId, accessKeySecret)
|
||||
|
||||
if len(env) > 0 {
|
||||
config.Env = env[0]
|
||||
}
|
||||
|
||||
return client.InitWithOptions(config, credential)
|
||||
}
|
||||
|
||||
func (client *Client) InitWithStsToken(accessKeyId, accessKeySecret, accessKeyFrom string) (err error) {
|
||||
config := client.InitWithConfig()
|
||||
credential := &credentials.StdTokenCredential{
|
||||
AccessKeyId: accessKeyId,
|
||||
AccessKeySecret: accessKeySecret,
|
||||
AccessKeyFrom: accessKeyFrom,
|
||||
}
|
||||
return client.InitWithOptions(config, credential)
|
||||
}
|
||||
|
||||
func (client *Client) InitWithOptions(config *Config, credential auth.Credential) (err error) {
|
||||
client.httpClient = &http.Client{}
|
||||
client.config = config
|
||||
|
||||
if config.Transport != nil {
|
||||
client.httpClient.Transport = config.Transport
|
||||
} else if config.HttpTransport != nil {
|
||||
client.httpClient.Transport = config.HttpTransport
|
||||
}
|
||||
|
||||
if config.Timeout > 0 {
|
||||
client.httpClient.Timeout = config.Timeout
|
||||
}
|
||||
|
||||
client.signer, err = auth.NewSignerWithCredential(credential, client.ProcessCommonRequestWithSigner)
|
||||
return
|
||||
}
|
||||
|
||||
func (client *Client) InitWithConfig() (config *Config) {
|
||||
if client.config != nil {
|
||||
return client.config
|
||||
} else {
|
||||
return NewConfig()
|
||||
}
|
||||
}
|
||||
|
||||
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{
|
||||
Timeout: connectTimeout,
|
||||
DualStack: true,
|
||||
}).DialContext(ctx, network, address)
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
trans.DialContext = Timeout(connectTimeout)
|
||||
client.httpClient.Transport = trans
|
||||
} else if client.httpClient.Transport == nil {
|
||||
client.httpClient.Transport = &http.Transport{
|
||||
DialContext: Timeout(connectTimeout),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (client *Client) getTimeOut(request requests.AcsRequest) (time.Duration, time.Duration) {
|
||||
readTimeOut := defaultReadTimeout
|
||||
connectTimeOut := defaultConnectTimeout
|
||||
|
||||
reqReadTimeout := request.GetReadTimeout()
|
||||
reqConnectTimeout := request.GetConnectTimeout()
|
||||
if reqReadTimeout != 0*time.Millisecond {
|
||||
readTimeOut = reqReadTimeout
|
||||
} else if client.readTimeout != 0*time.Microsecond {
|
||||
readTimeOut = client.readTimeout
|
||||
} else if client.httpClient.Timeout != 0 {
|
||||
readTimeOut = client.httpClient.Timeout
|
||||
}
|
||||
|
||||
if reqConnectTimeout != 0*time.Microsecond {
|
||||
connectTimeOut = reqConnectTimeout
|
||||
} else if client.connectTimeout != 0*time.Millisecond {
|
||||
connectTimeOut = client.connectTimeout
|
||||
}
|
||||
return readTimeOut, connectTimeOut
|
||||
}
|
||||
|
||||
func (client *Client) getHTTPSInsecure(request requests.AcsRequest) (insecure bool) {
|
||||
if request.GetHTTPSInsecure() != nil {
|
||||
insecure = *request.GetHTTPSInsecure()
|
||||
} else {
|
||||
insecure = client.GetHTTPSInsecure()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
httpRequest, err := client.buildRequestWithSigner(request, signer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client.setTimeOut(request)
|
||||
proxy, err := client.getHttpProxy(httpRequest.URL.Scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
noProxy := client.getNoProxy(httpRequest.URL.Scheme)
|
||||
var flag bool
|
||||
for _, value := range noProxy {
|
||||
if strings.HasPrefix(value, "*") {
|
||||
value = fmt.Sprint(".%s", value)
|
||||
}
|
||||
noProxyReg, err := regexp.Compile(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if noProxyReg.MatchString(httpRequest.Host) {
|
||||
flag = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil {
|
||||
if trans.TLSClientConfig != nil {
|
||||
trans.TLSClientConfig.InsecureSkipVerify = client.getHTTPSInsecure(request)
|
||||
} else {
|
||||
trans.TLSClientConfig = &tls.Config{
|
||||
InsecureSkipVerify: client.getHTTPSInsecure(request),
|
||||
}
|
||||
}
|
||||
|
||||
if proxy != nil && !flag {
|
||||
trans.Proxy = http.ProxyURL(proxy)
|
||||
}
|
||||
|
||||
client.httpClient.Transport = trans
|
||||
}
|
||||
|
||||
dump, err := httputil.DumpRequest(httpRequest, true)
|
||||
debug("client %s", bytes.NewBuffer(dump).String())
|
||||
|
||||
var httpResponse *http.Response
|
||||
httpResponse, err = hookDo(client.httpClient.Do)(httpRequest)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = responses.Unmarshal(response, httpResponse, request.GetAcceptFormat())
|
||||
return
|
||||
}
|
||||
|
||||
func (client *Client) buildRequestWithSigner(request requests.AcsRequest, signer auth.Signer) (httpRequest *http.Request, err error) {
|
||||
// init param
|
||||
domain := request.GetDomain()
|
||||
if strings.Index(domain.Default, ".") < 0 {
|
||||
domain.Default += defaultDomain
|
||||
request.SetDomain(domain)
|
||||
}
|
||||
|
||||
if request.GetScheme() == "" {
|
||||
request.SetScheme(client.config.Scheme)
|
||||
}
|
||||
|
||||
if request.GetEnv() == "" && client.config.Env != "" {
|
||||
request.SetEnv(client.config.Env)
|
||||
}
|
||||
|
||||
err = requests.InitParam(request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// build signature
|
||||
var finalSigner auth.Signer
|
||||
if signer != nil {
|
||||
finalSigner = signer
|
||||
} else {
|
||||
finalSigner = client.signer
|
||||
}
|
||||
err = auth.Sign(request, finalSigner)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// build request
|
||||
requestMethod := request.GetMethod()
|
||||
requestUrl := request.BuildUrl()
|
||||
body := request.GetBodyReader()
|
||||
httpRequest, err = http.NewRequest(requestMethod, requestUrl, body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for key, val := range request.GetHeaders() {
|
||||
httpRequest.Header[key] = []string{val}
|
||||
}
|
||||
|
||||
if host, isContainsHost := request.GetHeaders()["host"]; isContainsHost {
|
||||
httpRequest.Host = host
|
||||
}
|
||||
|
||||
userAgent := DefaultUserAgent
|
||||
httpRequest.Header.Set("User-Agent", userAgent)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (client *Client) getHttpProxy(scheme string) (proxy *url.URL, err error) {
|
||||
switch scheme {
|
||||
case "https":
|
||||
if client.GetHttpsProxy() != "" {
|
||||
proxy, err = url.Parse(client.httpsProxy)
|
||||
} else if rawurl := os.Getenv("HTTPS_PROXY"); rawurl != "" {
|
||||
proxy, err = url.Parse(rawurl)
|
||||
} else if rawurl := os.Getenv("https_proxy"); rawurl != "" {
|
||||
proxy, err = url.Parse(rawurl)
|
||||
}
|
||||
default:
|
||||
if client.GetHttpProxy() != "" {
|
||||
proxy, err = url.Parse(client.httpProxy)
|
||||
} else if rawurl := os.Getenv("HTTP_PROXY"); rawurl != "" {
|
||||
proxy, err = url.Parse(rawurl)
|
||||
} else if rawurl := os.Getenv("http_proxy"); rawurl != "" {
|
||||
proxy, err = url.Parse(rawurl)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (client *Client) getNoProxy(scheme string) []string {
|
||||
var urls []string
|
||||
if client.GetNoProxy() != "" {
|
||||
urls = strings.Split(client.noProxy, ",")
|
||||
} else if rawurl := os.Getenv("NO_PROXY"); rawurl != "" {
|
||||
urls = strings.Split(rawurl, ",")
|
||||
} else if rawurl := os.Getenv("no_proxy"); rawurl != "" {
|
||||
urls = strings.Split(rawurl, ",")
|
||||
}
|
||||
return urls
|
||||
}
|
||||
|
||||
func hookDo(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
|
||||
return fn
|
||||
}
|
24
sdk/config.go
Normal file
24
sdk/config.go
Normal file
@ -0,0 +1,24 @@
|
||||
package sdk
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Debug bool `default:"false"`
|
||||
HttpTransport *http.Transport `default:""`
|
||||
Transport http.RoundTripper `default:""`
|
||||
GoRoutinePoolSize int `default:"0"`
|
||||
UserAgent string `default:""`
|
||||
Scheme string `default:"HTTP"`
|
||||
Timeout time.Duration `default:"5"`
|
||||
Env string `default:""`
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
config := &Config{}
|
||||
utils.InitStructWithDefaultTag(config)
|
||||
return config
|
||||
}
|
36
sdk/requests/common_request.go
Normal file
36
sdk/requests/common_request.go
Normal file
@ -0,0 +1,36 @@
|
||||
package requests
|
||||
|
||||
import "io"
|
||||
|
||||
type CommonRequest struct {
|
||||
*baseRequest
|
||||
Product string
|
||||
Ontology AcsRequest
|
||||
}
|
||||
|
||||
func (request *CommonRequest) TransToAscRequest() {
|
||||
rpcRequest := &RpcRequest{}
|
||||
rpcRequest.baseRequest = request.baseRequest
|
||||
rpcRequest.product = request.Product
|
||||
request.Ontology = rpcRequest
|
||||
}
|
||||
|
||||
func (request *CommonRequest) BuildUrl() string {
|
||||
return request.Ontology.BuildUrl()
|
||||
}
|
||||
|
||||
func (request *CommonRequest) BuildQueries() string {
|
||||
return request.Ontology.BuildQueries()
|
||||
}
|
||||
|
||||
func (request *CommonRequest) GetBodyReader() io.Reader {
|
||||
return request.Ontology.GetBodyReader()
|
||||
}
|
||||
|
||||
func (request *CommonRequest) GetStyle() string {
|
||||
return request.Ontology.GetStyle()
|
||||
}
|
||||
|
||||
func (request *CommonRequest) InitWithApiInfo(domain Host, version, urlPath string) {
|
||||
request.Ontology.InitWithApiInfo(domain, version, urlPath)
|
||||
}
|
314
sdk/requests/request.go
Normal file
314
sdk/requests/request.go
Normal file
@ -0,0 +1,314 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
|
||||
"io"
|
||||
"math/cmplx"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
RPC = "RPC"
|
||||
ROA = "ROA"
|
||||
|
||||
HTTP = "HTTP"
|
||||
HTTPS = "HTTPS"
|
||||
|
||||
JSON = "JSON"
|
||||
XML = "XML"
|
||||
|
||||
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"
|
||||
|
||||
TEST = "TEST"
|
||||
PRE = "PRE"
|
||||
RELEASE = "RELEASE"
|
||||
|
||||
HeaderSeparator = "\n"
|
||||
)
|
||||
|
||||
type Host struct {
|
||||
Default string
|
||||
Func func(string) string
|
||||
}
|
||||
|
||||
var debug utils.Debug
|
||||
|
||||
func init() {
|
||||
debug = utils.Init("request")
|
||||
}
|
||||
|
||||
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
|
||||
GetScheme() string
|
||||
GetDomain() Host
|
||||
SetDomain(host Host)
|
||||
GetActionName() string
|
||||
GetAcceptFormat() string
|
||||
GetAccept() string
|
||||
GetHeaders() map[string]string
|
||||
GetStyle() string
|
||||
InitWithApiInfo(domain Host, version, urlPath string)
|
||||
GetEnv() string
|
||||
SetEnv(string)
|
||||
|
||||
BuildUrl() string
|
||||
BuildQueries() string
|
||||
|
||||
SetScheme(scheme string)
|
||||
SetContent(content []byte)
|
||||
|
||||
SetStringToSign(stringToSign string)
|
||||
GetStringToSign() string
|
||||
GetBodyReader() io.Reader
|
||||
|
||||
AddHeaderParam(key, value string)
|
||||
addQueryParam(key, value string)
|
||||
addFormParam(key, value string)
|
||||
}
|
||||
|
||||
type baseRequest struct {
|
||||
Scheme string
|
||||
Method string
|
||||
Port string
|
||||
Domain Host
|
||||
From string
|
||||
ReadTimeout time.Duration
|
||||
ConnectTimeout time.Duration
|
||||
isInsecure *bool
|
||||
Env string
|
||||
|
||||
AcceptFormat string
|
||||
actionName 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) GetEnv() string {
|
||||
return request.Env
|
||||
}
|
||||
|
||||
func (request *baseRequest) SetEnv(e string) {
|
||||
request.Env = e
|
||||
}
|
||||
|
||||
func (request *baseRequest) GetStringToSign() string {
|
||||
return request.stringToSign
|
||||
}
|
||||
|
||||
func (request *baseRequest) SetContent(content []byte) {
|
||||
request.Content = content
|
||||
}
|
||||
|
||||
func (request *baseRequest) GetAcceptFormat() string {
|
||||
return request.AcceptFormat
|
||||
}
|
||||
|
||||
func (request *baseRequest) GetAccept() string {
|
||||
switch request.GetAcceptFormat() {
|
||||
case JSON:
|
||||
return Json
|
||||
case XML:
|
||||
return Xml
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (request *baseRequest) GetHeaders() map[string]string {
|
||||
return request.Headers
|
||||
}
|
||||
|
||||
func (request *baseRequest) GetActionName() string {
|
||||
return request.actionName
|
||||
}
|
||||
|
||||
func (request *baseRequest) SetScheme(scheme string) {
|
||||
request.Scheme = scheme
|
||||
}
|
||||
|
||||
func (request *baseRequest) SetDomain(host Host) {
|
||||
request.Domain = host
|
||||
}
|
||||
|
||||
func (request *baseRequest) GetScheme() string {
|
||||
return request.Scheme
|
||||
}
|
||||
|
||||
func (request *baseRequest) GetDomain() Host {
|
||||
return request.Domain
|
||||
}
|
||||
|
||||
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 (request *baseRequest) AddHeaderParam(key, val string) {
|
||||
request.Headers[key] = val
|
||||
}
|
||||
|
||||
func (request *baseRequest) addQueryParam(key, val string) {
|
||||
request.QueryParams[key] = val
|
||||
}
|
||||
|
||||
func (request *baseRequest) addFormParam(key, val string) {
|
||||
request.FormParams[key] = val
|
||||
}
|
||||
|
||||
func defaultBaseRequest() (request *baseRequest) {
|
||||
request = &baseRequest{
|
||||
Scheme: HTTP,
|
||||
AcceptFormat: JSON,
|
||||
Method: GET,
|
||||
QueryParams: make(map[string]string),
|
||||
Headers: map[string]string{
|
||||
"Gr-Sdk-Client": "golang/1.14",
|
||||
"Gr-Sdk-Invoke-Type": "normal",
|
||||
"Accept-Encoding": Json,
|
||||
},
|
||||
FormParams: make(map[string]string),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
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 := position
|
||||
if fieldPosition == "" {
|
||||
fieldPosition, _ = field.Tag.Lookup("position")
|
||||
}
|
||||
|
||||
fieldDefault, _ := field.Tag.Lookup("default")
|
||||
debug("%s %s %s", name, fieldPosition, fieldDefault)
|
||||
if isContiansNameTag {
|
||||
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
|
||||
}
|
||||
|
||||
if value == "0" && fieldDefault != "" && fieldDefault != "0" {
|
||||
value = fieldDefault
|
||||
}
|
||||
|
||||
err = addParam(request, fieldPosition, name, value)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func addParam(request AcsRequest, position, key, value string) (err error) {
|
||||
if len(value) > 0 {
|
||||
switch position {
|
||||
case Header:
|
||||
request.AddHeaderParam(key, value)
|
||||
case Query:
|
||||
request.addQueryParam(key, value)
|
||||
case Body:
|
||||
request.addFormParam(key, value)
|
||||
default:
|
||||
errmsg := fmt.Sprintf("unsupport positions add param `%s`", position)
|
||||
err = errors.New(errmsg)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
63
sdk/requests/rpc_request.go
Normal file
63
sdk/requests/rpc_request.go
Normal file
@ -0,0 +1,63 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/utils"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type RpcRequest struct {
|
||||
*baseRequest
|
||||
}
|
||||
|
||||
func (request *RpcRequest) init() {
|
||||
request.baseRequest = defaultBaseRequest()
|
||||
request.Method = POST
|
||||
}
|
||||
|
||||
func (request *RpcRequest) BuildUrl() string {
|
||||
|
||||
var hostname string
|
||||
if request.Domain.Func == nil {
|
||||
hostname = request.Domain.Default
|
||||
} else if hostname = request.Domain.Func(request.GetEnv()); hostname == "" {
|
||||
hostname = request.Domain.Default
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s://%s", strings.ToLower(request.Scheme), hostname)
|
||||
if len(request.Port) > 0 {
|
||||
url = fmt.Sprintf("%s:%s", url, request.Port)
|
||||
}
|
||||
return url + request.BuildQueries()
|
||||
}
|
||||
|
||||
func (request *RpcRequest) GetStyle() string {
|
||||
return RPC
|
||||
}
|
||||
|
||||
func (request *RpcRequest) BuildQueries() string {
|
||||
path := strings.TrimLeft(strings.TrimSpace(request.GetActionName()), "/")
|
||||
request.queries = "/" + path + "?" + utils.GetUrlFormedMap(request.QueryParams)
|
||||
return request.queries
|
||||
}
|
||||
|
||||
func (request *RpcRequest) GetActionName() string {
|
||||
return request.actionName
|
||||
}
|
||||
|
||||
func (request *RpcRequest) InitWithApiInfo(domain Host, version, urlPath string) {
|
||||
request.init()
|
||||
request.SetDomain(domain)
|
||||
request.version = version
|
||||
request.actionName = urlPath
|
||||
}
|
||||
|
||||
func (request *RpcRequest) GetBodyReader() io.Reader {
|
||||
if request.FormParams != nil && len(request.FormParams) > 0 {
|
||||
formString := utils.GetUrlFormedMap(request.FormParams)
|
||||
return strings.NewReader(formString)
|
||||
} else {
|
||||
return strings.NewReader("")
|
||||
}
|
||||
}
|
10
sdk/requests/types.go
Normal file
10
sdk/requests/types.go
Normal file
@ -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)
|
||||
}
|
117
sdk/responses/response.go
Normal file
117
sdk/responses/response.go
Normal file
@ -0,0 +1,117 @@
|
||||
package responses
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
Code int `json:"code"`
|
||||
Status bool `json:"status"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
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{},
|
||||
}
|
||||
}
|
||||
|
||||
func Unmarshal(response AcsResponse, httpResponse *http.Response, format string) (err error) {
|
||||
err = response.parseFromHttpResponse(httpResponse)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, isCommonResponse := response.(CommonResponse); isCommonResponse {
|
||||
return
|
||||
}
|
||||
|
||||
if !response.IsSuccess() {
|
||||
if contentType, ok := response.GetHttpHeaders()["Content-Type"]; ok {
|
||||
for _, v := range contentType {
|
||||
if strings.Contains(v, requests.Json) {
|
||||
json.Unmarshal(response.GetHttpContentBytes(), response)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = errors.New(fmt.Sprintf("%d %s", response.GetHttpStatus(), response.GetHttpContentString()))
|
||||
return
|
||||
}
|
||||
|
||||
if format != "xml" {
|
||||
err = json.Unmarshal(response.GetHttpContentBytes(), response)
|
||||
if err != nil {
|
||||
return errors.New("json Unmarshal:" + err.Error())
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
36
sdk/utils/debug.go
Normal file
36
sdk/utils/debug.go
Normal file
@ -0,0 +1,36 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Debug func(format string, v ...interface{})
|
||||
|
||||
var hookPrint = func(input string) {
|
||||
fmt.Println(input)
|
||||
}
|
||||
|
||||
var hookGetEnv = func() string {
|
||||
return os.Getenv("DEBUG")
|
||||
}
|
||||
|
||||
func Init(flag string) Debug {
|
||||
|
||||
enable := false
|
||||
env := hookGetEnv()
|
||||
parts := strings.Split(env, ",")
|
||||
for _, part := range parts {
|
||||
if part == flag {
|
||||
enable = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return func(format string, v ...interface{}) {
|
||||
if enable {
|
||||
hookPrint(fmt.Sprintf(format, v...))
|
||||
}
|
||||
}
|
||||
}
|
111
sdk/utils/utils.go
Normal file
111
sdk/utils/utils.go
Normal file
@ -0,0 +1,111 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"hash"
|
||||
rand2 "math/rand"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UUID [16]byte
|
||||
|
||||
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
func GetUUID() (uuidHex string) {
|
||||
uuid := NewUUID()
|
||||
uuidHex = hex.EncodeToString(uuid[:])
|
||||
return
|
||||
}
|
||||
|
||||
func NewUUID() UUID {
|
||||
ns := UUID{}
|
||||
safeRandom(ns[:])
|
||||
u := newFromHash(md5.New(), ns, RandStringBytes(16))
|
||||
u[6] = (u[6] & 0x0f) | (byte(2) << 4)
|
||||
u[8] = (u[8]&(0xff>>2) | (0x02 << 6))
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
func RandStringBytes(n int) string {
|
||||
b := make([]byte, n)
|
||||
for i := range b {
|
||||
b[i] = letterBytes[rand2.Intn(len(letterBytes))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
|
||||
u := UUID{}
|
||||
h.Write(ns[:])
|
||||
h.Write([]byte(name))
|
||||
copy(u[:], h.Sum(nil))
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
func safeRandom(dest []byte) {
|
||||
if _, err := rand.Read(dest); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func GetUrlFormedMap(source map[string]string) (urlEncoded string) {
|
||||
urlEncoder := url.Values{}
|
||||
for key, value := range source {
|
||||
urlEncoder.Add(key, value)
|
||||
}
|
||||
urlEncoded = urlEncoder.Encode()
|
||||
return
|
||||
}
|
||||
|
||||
func GetUrlByKeySort(source map[string]string) (url string) {
|
||||
keys := make([]string, 0, len(source))
|
||||
for k := range source {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, key := range keys {
|
||||
url += fmt.Sprintf("%s=%s&", key, source[key])
|
||||
}
|
||||
return strings.TrimRight(url, "&")
|
||||
}
|
||||
|
||||
func InitStructWithDefaultTag(bean interface{}) {
|
||||
beantype := reflect.TypeOf(bean)
|
||||
for i := 0; i < beantype.Elem().NumField(); i++ {
|
||||
field := beantype.Elem().Field(i)
|
||||
defaultValue := strings.TrimSpace(field.Tag.Get("default"))
|
||||
if defaultValue == "" || defaultValue == "-" {
|
||||
continue
|
||||
}
|
||||
setter := reflect.ValueOf(bean).Elem().Field(i)
|
||||
fieldTypeName := field.Type.String()
|
||||
switch fieldTypeName {
|
||||
case "int", "int64", "int32", "int8", "int16":
|
||||
intval, _ := strconv.ParseInt(defaultValue, 10, 64)
|
||||
setter.SetInt(intval)
|
||||
case "uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
|
||||
uintval, _ := strconv.ParseUint(defaultValue, 10, 64)
|
||||
setter.SetUint(uintval)
|
||||
case "string":
|
||||
setter.SetString(defaultValue)
|
||||
case "time.Duration":
|
||||
intval, _ := strconv.ParseInt(defaultValue, 10, 64)
|
||||
setter.SetInt(intval * int64(time.Second))
|
||||
case "bool":
|
||||
boolval, _ := strconv.ParseBool(defaultValue)
|
||||
setter.SetBool(boolval)
|
||||
default:
|
||||
fmt.Println(field.Type.String(), field.Name)
|
||||
}
|
||||
}
|
||||
}
|
25
sdk/utils/utils_test.go
Normal file
25
sdk/utils/utils_test.go
Normal file
@ -0,0 +1,25 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TestCase struct {
|
||||
Debug bool `default:"false"`
|
||||
HttpTransport *http.Transport `default:""`
|
||||
Transport http.RoundTripper `default:""`
|
||||
GoRoutinePoolSize int `default:"5"`
|
||||
UserAgent string `default:""`
|
||||
Scheme string `default:"HTTP"`
|
||||
Haha uintptr `default:"232"`
|
||||
Timeout time.Duration `default:"5"`
|
||||
}
|
||||
|
||||
func TestInitStructWithDefaultTag(t *testing.T) {
|
||||
testcase := &TestCase{}
|
||||
InitStructWithDefaultTag(testcase)
|
||||
fmt.Printf("%+v", testcase)
|
||||
}
|
37
services/apk/add_apk.go
Normal file
37
services/apk/add_apk.go
Normal file
@ -0,0 +1,37 @@
|
||||
package apk
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
type AddApkRequest struct {
|
||||
*requests.RpcRequest
|
||||
List string `position:"Body" field:"list" default:"[]" `
|
||||
}
|
||||
|
||||
type AddApkResponse struct {
|
||||
*responses.BaseResponse
|
||||
Code int `json:"code"`
|
||||
Status bool `json:"status"`
|
||||
Msg string `json:"msg"`
|
||||
Data struct {
|
||||
Count int `json:"count"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
func CreateAddApkRequest() (req *AddApkRequest) {
|
||||
req = &AddApkRequest{
|
||||
RpcRequest: &requests.RpcRequest{},
|
||||
}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/apk/add")
|
||||
req.Method = requests.POST
|
||||
return
|
||||
}
|
||||
|
||||
func CreateAddApkResponse() (response *AddApkResponse) {
|
||||
response = &AddApkResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
36
services/apk/add_top.go
Normal file
36
services/apk/add_top.go
Normal file
@ -0,0 +1,36 @@
|
||||
package apk
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
type AddTopRequest struct {
|
||||
*requests.RpcRequest
|
||||
Id int `position:"Body" field:"id" default:"0" `
|
||||
Ids string `position:"Body" field:"ids" default:"" `
|
||||
Top int `position:"Body" field:"top" default:"0"`
|
||||
}
|
||||
|
||||
type AddTopResponse struct {
|
||||
*responses.BaseResponse
|
||||
Code int `json:"code"`
|
||||
Status bool `json:"status"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
func CreateAddTopRequest() (req *AddTopRequest) {
|
||||
req = &AddTopRequest{
|
||||
RpcRequest: &requests.RpcRequest{},
|
||||
}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/apk/AddTop")
|
||||
req.Method = requests.POST
|
||||
return
|
||||
}
|
||||
|
||||
func CreateAddTopResponse() (response *AddTopResponse) {
|
||||
response = &AddTopResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
66
services/apk/client.go
Normal file
66
services/apk/client.go
Normal file
@ -0,0 +1,66 @@
|
||||
package apk
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
)
|
||||
|
||||
const (
|
||||
VERSION = "2021-07-30"
|
||||
)
|
||||
|
||||
var HOST requests.Host = requests.Host{
|
||||
Default: "c.api.gaore.com",
|
||||
Func: func(s string) string {
|
||||
var a = map[string]string{
|
||||
requests.RELEASE: "c.api.gaore.com",
|
||||
requests.PRE: "c.api.gaore.com",
|
||||
requests.TEST: "c.api.gaore.com",
|
||||
}
|
||||
return a[s]
|
||||
},
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
sdk.Client
|
||||
}
|
||||
|
||||
func NewClient() (client *Client) {
|
||||
client = &Client{}
|
||||
client.InitWithAccessKey("", "", "")
|
||||
return
|
||||
}
|
||||
|
||||
// 打包任务添加优先级
|
||||
func (c *Client) AddApkTop(req *AddTopRequest) (response *AddTopResponse, err error) {
|
||||
response = CreateAddTopResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
||||
|
||||
// 添加打包任务
|
||||
func (c *Client) AddApk(req *AddApkRequest) (response *AddApkResponse, err error) {
|
||||
response = CreateAddApkResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
||||
|
||||
// 清除cdn
|
||||
func (c *Client) RefreshApkR(req *RefreshApkRequest) (response *RefreshApkResponse, err error) {
|
||||
response = CreateRefreshApkResponse()
|
||||
if len(req.CdnUrlArray) > 0 {
|
||||
cdnurls, _ := json.Marshal(req.CdnUrlArray)
|
||||
req.cdnUrls = string(cdnurls)
|
||||
}
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取打包日志
|
||||
func (c *Client) SearchApk(req *SearchApkRequest) (response *SearchApkResponse, err error) {
|
||||
response = CreateSearchApkResponse()
|
||||
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
21
services/apk/client_test.go
Normal file
21
services/apk/client_test.go
Normal file
@ -0,0 +1,21 @@
|
||||
package apk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestClient_GetUserInfo(t *testing.T) {
|
||||
c := NewClient()
|
||||
req := CreateSearchApkRequest()
|
||||
req.GameIds = "3503"
|
||||
req.Ver = "1.0.0"
|
||||
req.SetReadTimeout(60 * time.Second)
|
||||
resp, err := c.SearchApk(req)
|
||||
|
||||
fmt.Println(req)
|
||||
fmt.Println(resp.GetHttpContentString())
|
||||
fmt.Println(err)
|
||||
|
||||
}
|
36
services/apk/refresh_apk.go
Normal file
36
services/apk/refresh_apk.go
Normal file
@ -0,0 +1,36 @@
|
||||
package apk
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
type RefreshApkRequest struct {
|
||||
*requests.RpcRequest
|
||||
cdnUrls string `position:"Body" field:"cdn_urls" default:"[]" `
|
||||
CdnUrlArray []string
|
||||
}
|
||||
|
||||
type RefreshApkResponse struct {
|
||||
*responses.BaseResponse
|
||||
Code int `json:"code"`
|
||||
Status bool `json:"status"`
|
||||
Msg string `json:"msg"`
|
||||
Data map[string]string `json:"data"`
|
||||
}
|
||||
|
||||
func CreateRefreshApkRequest() (req *RefreshApkRequest) {
|
||||
req = &RefreshApkRequest{
|
||||
RpcRequest: &requests.RpcRequest{},
|
||||
}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/apk/refresh")
|
||||
req.Method = requests.POST
|
||||
return
|
||||
}
|
||||
|
||||
func CreateRefreshApkResponse() (response *RefreshApkResponse) {
|
||||
response = &RefreshApkResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
74
services/apk/search_apk.go
Normal file
74
services/apk/search_apk.go
Normal file
@ -0,0 +1,74 @@
|
||||
package apk
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SearchApkRequest struct {
|
||||
*requests.RpcRequest
|
||||
StartTime string `position:"Body" field:"startTime" default:"" `
|
||||
EndTime string `position:"Body" field:"endTime" default:"" `
|
||||
State string `position:"Body" field:"state" default:"" `
|
||||
SiteIds string `position:"Body" field:"siteIds" default:"" `
|
||||
Ver string `position:"Body" field:"ver" default:"" `
|
||||
SiteId int `position:"Body" field:"siteId" default:"" `
|
||||
AgentId int `position:"Body" field:"agentId" default:"" `
|
||||
Top int `position:"Body" field:"top" default:"" `
|
||||
GameIds string `position:"Body" field:"gameIds" default:"" `
|
||||
Autor string `position:"Body" field:"autor" default:"" `
|
||||
Page int `position:"Body" field:"page" default:"1" `
|
||||
Pagesize int `position:"Body" field:"pagesize" default:"20" `
|
||||
Order string `position:"Body" field:"order" default:"" `
|
||||
}
|
||||
|
||||
type ApkLog struct {
|
||||
ID int `json:"Id"`
|
||||
GameID int `json:"GameId"`
|
||||
GameName string `json:"GameName"`
|
||||
Ver string `json:"Ver"`
|
||||
Top int `json:"Top"`
|
||||
AgentID int `json:"AgentId"`
|
||||
SiteID int `json:"SiteId"`
|
||||
Addtime time.Time `json:"Addtime"`
|
||||
Edittime time.Time `json:"Edittime"`
|
||||
State int `json:"State"`
|
||||
Times int `json:"Times"`
|
||||
ReleaseTime int `json:"ReleaseTime"`
|
||||
Env int `json:"Env"`
|
||||
AliOss int `json:"AliOss"`
|
||||
NeedCdn bool `json:"NeedCdn"`
|
||||
Autor string `json:"Autor"`
|
||||
Ext string `json:"Ext"`
|
||||
IsAugment bool `json:"IsAugment"`
|
||||
}
|
||||
|
||||
type SearchApkResponse struct {
|
||||
*responses.BaseResponse
|
||||
Code int `json:"code"`
|
||||
Status bool `json:"status"`
|
||||
Msg string `json:"msg"`
|
||||
Data struct {
|
||||
Page int `json:"Page"`
|
||||
PageSize int `json:"PageSize"`
|
||||
Total int `json:"Total"`
|
||||
List []ApkLog `json:"List"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
func CreateSearchApkRequest() (req *SearchApkRequest) {
|
||||
req = &SearchApkRequest{
|
||||
RpcRequest: &requests.RpcRequest{},
|
||||
}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/apk/list")
|
||||
req.Method = requests.POST
|
||||
return
|
||||
}
|
||||
|
||||
func CreateSearchApkResponse() (response *SearchApkResponse) {
|
||||
response = &SearchApkResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
48
services/callback/client.go
Normal file
48
services/callback/client.go
Normal file
@ -0,0 +1,48 @@
|
||||
package callback
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
)
|
||||
|
||||
const (
|
||||
VERSION = "2021-11-30"
|
||||
)
|
||||
|
||||
var HOST requests.Host = requests.Host{
|
||||
Default: "callback.api.gaore.com",
|
||||
Func: func(s string) string {
|
||||
var a = map[string]string{
|
||||
requests.RELEASE: "callback.api.gaore.com",
|
||||
requests.PRE: "callback.api.gaore.com",
|
||||
requests.TEST: "callback.api.gaore.com",
|
||||
}
|
||||
return a[s]
|
||||
},
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
sdk.Client
|
||||
}
|
||||
|
||||
func NewClient() (client *Client) {
|
||||
client = &Client{}
|
||||
client.InitWithAccessKey("", "", "")
|
||||
return
|
||||
}
|
||||
|
||||
// 上报关键行为
|
||||
func (c *Client) SendAction(req *SendActionRequest) (response *SendActionResponse, err error) {
|
||||
response = CreateSendActionResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
||||
|
||||
// 上报激活
|
||||
func (c *Client) SendActive() {
|
||||
|
||||
}
|
||||
|
||||
// 上报付费
|
||||
|
||||
// 上报注册
|
49
services/callback/send_action.go
Normal file
49
services/callback/send_action.go
Normal file
@ -0,0 +1,49 @@
|
||||
package callback
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
const OS_ANDROID = 2
|
||||
|
||||
const OS_IOS = 1
|
||||
|
||||
type SendActionRequest struct {
|
||||
*requests.RpcRequest
|
||||
GameId int64 `position:"Query" field:"game_id" default:"" `
|
||||
AgentId int64 `position:"Query" field:"agent_id" default:"" `
|
||||
SiteId int64 `position:"Query" field:"site_id" default:"" `
|
||||
Imei string `position:"Query" field:"imei" default:"" `
|
||||
Oaid string `position:"Query" field:"oaid" default:"" `
|
||||
Ip string `position:"Query" field:"ip" default:"" `
|
||||
Ua string `position:"Query" field:"ua" default:"" `
|
||||
Os int `position:"Query" field:"os" default:"" `
|
||||
ParamsArray []string
|
||||
}
|
||||
|
||||
type SendActionResponseData struct {
|
||||
Account string `json:"account"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type SendActionResponse struct {
|
||||
*responses.BaseResponse
|
||||
Data SendActionResponseData `json:"data"`
|
||||
}
|
||||
|
||||
func CreateSendActionRequest() (req *SendActionRequest) {
|
||||
req = &SendActionRequest{
|
||||
RpcRequest: &requests.RpcRequest{},
|
||||
}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/callback/ads_callback/sendAction")
|
||||
req.Method = requests.GET
|
||||
return
|
||||
}
|
||||
|
||||
func CreateSendActionResponse() (response *SendActionResponse) {
|
||||
response = &SendActionResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
29
services/jedi/README.md
Normal file
29
services/jedi/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
|
||||
### 发送短信调用示例
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/services/jedi"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c, err := jedi.NewClientWithAccessKey("accessKeyId", "accessKeySecret", "xxx.xxx.com")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
req := jedi.CreateSendSmsRequest()
|
||||
// sso统一用户名uid, 多个用户用逗句隔开
|
||||
req.User = "liangzy,liaoks"
|
||||
// 公共模板的代码模板
|
||||
req.Code = "d7kt5IwP"
|
||||
// 模板参数,模板里有多少个模板参数就传入几个替换字符串,
|
||||
req.ParamsArray = []string{"www", "线上", "好人"}
|
||||
if resp, err := c.SendSms(req); err == nil {
|
||||
grlogs.Informational(fmt.Sprintf("%+v", resp.GetHttpContentString()))
|
||||
} else {
|
||||
grlogs.Error(err)
|
||||
}
|
||||
}
|
||||
```
|
48
services/jedi/client.go
Normal file
48
services/jedi/client.go
Normal file
@ -0,0 +1,48 @@
|
||||
package jedi
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
VERSION = "2020-09-24"
|
||||
)
|
||||
|
||||
var HOST requests.Host = requests.Host{
|
||||
Default: "jedi.api.gaore.com",
|
||||
Func: func(s string) string {
|
||||
var a = map[string]string{
|
||||
requests.RELEASE: "jedi.api.gaore.com",
|
||||
requests.PRE: "jedi.api.gaore.com",
|
||||
requests.TEST: "jedi.oapi.gaore.com",
|
||||
}
|
||||
return a[s]
|
||||
},
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
sdk.Client
|
||||
}
|
||||
|
||||
func (c *Client) SendSms(req *SendSmsRequest) (response *SendSmsResponse, err error) {
|
||||
if req.ParamsArray != nil && len(req.ParamsArray) > 0 {
|
||||
req.Params = strings.Join(req.ParamsArray, ",,,")
|
||||
}
|
||||
response = CreateSendSmsResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
|
||||
client = &Client{}
|
||||
err = client.InitWithAccessKey(accesskey, secrect, source)
|
||||
return
|
||||
}
|
||||
|
||||
func NewClientWithAliAppcode(accesskey, secrect string, env ...string) (client *Client, err error) {
|
||||
client = &Client{}
|
||||
err = client.InitWithAliAppcode(accesskey, secrect, env...)
|
||||
return
|
||||
}
|
40
services/jedi/send_sms.go
Normal file
40
services/jedi/send_sms.go
Normal file
@ -0,0 +1,40 @@
|
||||
package jedi
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
type SendSmsRequest struct {
|
||||
*requests.RpcRequest
|
||||
User string `position:"Body" field:"user" default:"" `
|
||||
Code string `position:"Body" field:"code" default:"" `
|
||||
Params string `position:"Body" field:"params" default:"" `
|
||||
ParamsArray []string
|
||||
}
|
||||
|
||||
type SendSmsResponseData struct {
|
||||
Account string `json:"account"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type SendSmsResponse struct {
|
||||
*responses.BaseResponse
|
||||
Data SendSmsResponseData `json:"data"`
|
||||
}
|
||||
|
||||
func CreateSendSmsRequest() (req *SendSmsRequest) {
|
||||
req = &SendSmsRequest{
|
||||
RpcRequest: &requests.RpcRequest{},
|
||||
}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/sms/send")
|
||||
req.Method = requests.POST
|
||||
return
|
||||
}
|
||||
|
||||
func CreateSendSmsResponse() (response *SendSmsResponse) {
|
||||
response = &SendSmsResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
50
services/mail/client.go
Normal file
50
services/mail/client.go
Normal file
@ -0,0 +1,50 @@
|
||||
package mail
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
VERSION = "2021-09-27"
|
||||
)
|
||||
|
||||
var HOST requests.Host = requests.Host{
|
||||
Default: "mail.gaore.com",
|
||||
Func: func(s string) string {
|
||||
var a = map[string]string{
|
||||
requests.RELEASE: "mail.gaore.com",
|
||||
requests.PRE: "mail.gaore.com",
|
||||
requests.TEST: "mail.gaore.com",
|
||||
}
|
||||
return a[s]
|
||||
},
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
sdk.Client
|
||||
}
|
||||
|
||||
func NewClient() (client *Client) {
|
||||
client = &Client{}
|
||||
client.InitWithAccessKey("", "", "")
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) SendEmail(req *PostEmailRequest) (response *PostEmailResponse, err error) {
|
||||
|
||||
now := time.Now().Second()
|
||||
key := "04573fc4c8e01999a0909ab9c00bca5a"
|
||||
signstr := fmt.Sprintf("%d%s", now, key)
|
||||
data := []byte(signstr)
|
||||
has := md5.Sum(data)
|
||||
sign := fmt.Sprintf("%x", has)
|
||||
req.Time = now
|
||||
req.Sign = sign
|
||||
response = CreatePostEmailResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
22
services/mail/client_test.go
Normal file
22
services/mail/client_test.go
Normal file
@ -0,0 +1,22 @@
|
||||
package mail
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestClient_GetUserInfo(t *testing.T) {
|
||||
c := NewClient()
|
||||
req := CreatePostEmailRequest()
|
||||
req.Addresses = "3002467428@qq.com"
|
||||
req.Body = "1111"
|
||||
req.FromName = "213123121"
|
||||
req.SetReadTimeout(60 * time.Second)
|
||||
resp, err := c.SendEmail(req)
|
||||
|
||||
fmt.Println(req)
|
||||
fmt.Println(resp.GetHttpContentString())
|
||||
fmt.Println(err)
|
||||
|
||||
}
|
36
services/mail/end_email.go
Normal file
36
services/mail/end_email.go
Normal file
@ -0,0 +1,36 @@
|
||||
package mail
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
type PostEmailRequest struct {
|
||||
*requests.RpcRequest
|
||||
Addresses string `position:"Body" field:"addresses" default:"" `
|
||||
Subject string `position:"Body" field:"subject" default:"" `
|
||||
Body string `position:"Body" field:"body" default:""`
|
||||
FromName string `position:"Body" field:"fromName" default:""`
|
||||
Time int `position:"Body" field:"time" default:""`
|
||||
Sign string `position:"Body" field:"sign" default:""`
|
||||
}
|
||||
|
||||
type PostEmailResponse struct {
|
||||
*responses.BaseResponse
|
||||
}
|
||||
|
||||
func CreatePostEmailRequest() (req *PostEmailRequest) {
|
||||
req = &PostEmailRequest{
|
||||
RpcRequest: &requests.RpcRequest{},
|
||||
}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/email/post_email.php")
|
||||
req.Method = requests.POST
|
||||
return
|
||||
}
|
||||
|
||||
func CreatePostEmailResponse() (response *PostEmailResponse) {
|
||||
response = &PostEmailResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
31
services/mkt/client.go
Normal file
31
services/mkt/client.go
Normal file
@ -0,0 +1,31 @@
|
||||
package mkt
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
)
|
||||
|
||||
const (
|
||||
VERSION = "2020-11-16"
|
||||
)
|
||||
|
||||
var HOST = requests.Host{
|
||||
Default: "mkt",
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
sdk.Client
|
||||
}
|
||||
|
||||
// PkgNotice 打包通知
|
||||
func (c *Client) PkgNotice(req *PkgNoticeRequest) (response *PkgNoticeResponse, err error) {
|
||||
response = CreatePkgNoticeResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
|
||||
client = &Client{}
|
||||
err = client.InitWithAccessKey(accesskey, secrect, source)
|
||||
return
|
||||
}
|
36
services/mkt/pkg_notice.go
Normal file
36
services/mkt/pkg_notice.go
Normal file
@ -0,0 +1,36 @@
|
||||
package mkt
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
// PkgNoticeRequest 打包通知请求信息
|
||||
type PkgNoticeRequest struct {
|
||||
*requests.RpcRequest
|
||||
SiteID int64 `position:"Body" field:"site_id"` // 广告位ID
|
||||
Status int `position:"Body" field:"status"` // 打包状态(0:失败 1:成功)
|
||||
}
|
||||
|
||||
// PkgNoticeResponse 打包通知响应信息
|
||||
type PkgNoticeResponse struct {
|
||||
*responses.BaseResponse
|
||||
}
|
||||
|
||||
// CreatePkgNoticeRequest 创建通知接口
|
||||
func CreatePkgNoticeRequest() (req *PkgNoticeRequest) {
|
||||
req = &PkgNoticeRequest{
|
||||
RpcRequest: &requests.RpcRequest{},
|
||||
}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/game/pkgnotice")
|
||||
req.Method = requests.POST
|
||||
return
|
||||
}
|
||||
|
||||
// CreatePkgNoticeResponse 创建通知响应
|
||||
func CreatePkgNoticeResponse() (response *PkgNoticeResponse) {
|
||||
response = &PkgNoticeResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
48
services/sso/client.go
Normal file
48
services/sso/client.go
Normal file
@ -0,0 +1,48 @@
|
||||
package sso
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
)
|
||||
|
||||
const (
|
||||
VERSION = "2020-08-07"
|
||||
)
|
||||
|
||||
var HOST = requests.Host{
|
||||
Default: "sso",
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
sdk.Client
|
||||
}
|
||||
|
||||
func (c *Client) CodeAuth(req *CodeAuthRequest) (response *CodeAuthResponse, err error) {
|
||||
response = CreateCodeAuthResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) GetUserInfo(req *GetUserInfoRequest) (response *GetUserInfoResponse, err error) {
|
||||
response = CreateGetUserInfoResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) RefreshToken(req *RefreshTokenRequest) (response *RefreshTokenResponse, err error) {
|
||||
response = CreateRefreshTokenResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) SearchUser(req *SearchUserRequest) (response *SearchUserResponse, err error) {
|
||||
response = CreateSearchUserResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
||||
|
||||
func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
|
||||
client = &Client{}
|
||||
err = client.InitWithAccessKey(accesskey, secrect, source)
|
||||
return
|
||||
}
|
39
services/sso/code_auth.go
Normal file
39
services/sso/code_auth.go
Normal file
@ -0,0 +1,39 @@
|
||||
package sso
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
type CodeAuthRequest struct {
|
||||
*requests.RpcRequest
|
||||
OauthCode string `position:"Body" field:"oauthCode" default:"" `
|
||||
Ident string `position:"Body" field:"ident" default:"" `
|
||||
}
|
||||
|
||||
type CodeAuthResponseData struct {
|
||||
RefreshToken string `json:"refreshToken"`
|
||||
RefreshTokenExpires int64 `json:"refreshTokenExpires"`
|
||||
Token string `json:"token"`
|
||||
TokenExpires int64 `json:"tokenExpires"`
|
||||
User User `json:"user"`
|
||||
}
|
||||
|
||||
type CodeAuthResponse struct {
|
||||
*responses.BaseResponse
|
||||
Data CodeAuthResponseData `json:"data"`
|
||||
}
|
||||
|
||||
func CreateCodeAuthRequest() (req *CodeAuthRequest) {
|
||||
req = &CodeAuthRequest{RpcRequest: &requests.RpcRequest{}}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/userSess/codeAuth")
|
||||
req.Method = requests.POST
|
||||
return
|
||||
}
|
||||
|
||||
func CreateCodeAuthResponse() (response *CodeAuthResponse) {
|
||||
response = &CodeAuthResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
35
services/sso/get_user.go
Normal file
35
services/sso/get_user.go
Normal file
@ -0,0 +1,35 @@
|
||||
package sso
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
type GetUserInfoRequest struct {
|
||||
*requests.RpcRequest
|
||||
Token string `position:"Body" field:"token" default:"" `
|
||||
Ident string `position:"Body" field:"ident" default:"" `
|
||||
}
|
||||
|
||||
type GetUserInfoResponseData struct {
|
||||
User User `json:"user"`
|
||||
}
|
||||
|
||||
type GetUserInfoResponse struct {
|
||||
*responses.BaseResponse
|
||||
Data GetUserInfoResponseData `json:"data"`
|
||||
}
|
||||
|
||||
func CreateGetUserInfoRequest() (req *GetUserInfoRequest) {
|
||||
req = &GetUserInfoRequest{RpcRequest: &requests.RpcRequest{}}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/userSess/getUserInfo")
|
||||
req.Method = requests.POST
|
||||
return
|
||||
}
|
||||
|
||||
func CreateGetUserInfoResponse() (response *GetUserInfoResponse) {
|
||||
response = &GetUserInfoResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
37
services/sso/refresh_token.go
Normal file
37
services/sso/refresh_token.go
Normal file
@ -0,0 +1,37 @@
|
||||
package sso
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
type RefreshTokenRequest struct {
|
||||
*requests.RpcRequest
|
||||
RefreshToken string `position:"Body" field:"refreshToken" default:"" `
|
||||
Ident string `position:"Body" field:"ident" default:"" `
|
||||
}
|
||||
|
||||
type RefreshTokenResponseData struct {
|
||||
Token string `json:"token"`
|
||||
TokenExpires int64 `json:"tokenExpires"`
|
||||
User User `json:"user"`
|
||||
}
|
||||
|
||||
type RefreshTokenResponse struct {
|
||||
*responses.BaseResponse
|
||||
Data GetUserInfoResponseData `json:"data"`
|
||||
}
|
||||
|
||||
func CreateRefreshTokenRequest() (req *RefreshTokenRequest) {
|
||||
req = &RefreshTokenRequest{RpcRequest: &requests.RpcRequest{}}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/userSess/refreshToken")
|
||||
req.Method = requests.POST
|
||||
return
|
||||
}
|
||||
|
||||
func CreateRefreshTokenResponse() (response *RefreshTokenResponse) {
|
||||
response = &RefreshTokenResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
34
services/sso/search_user.go
Normal file
34
services/sso/search_user.go
Normal file
@ -0,0 +1,34 @@
|
||||
package sso
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
type SearchUserRequest struct {
|
||||
*requests.RpcRequest
|
||||
Uid string `position:"Body" field:"uid" default:"" `
|
||||
}
|
||||
|
||||
type SearchUserResponseData struct {
|
||||
User User `json:"user"`
|
||||
}
|
||||
|
||||
type SearchUserResponse struct {
|
||||
*responses.BaseResponse
|
||||
Data SearchUserResponseData `json:"data"`
|
||||
}
|
||||
|
||||
func CreateSearchUserRequest() (req *SearchUserRequest) {
|
||||
req = &SearchUserRequest{RpcRequest: &requests.RpcRequest{}}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/user/search")
|
||||
req.Method = requests.POST
|
||||
return
|
||||
}
|
||||
|
||||
func CreateSearchUserResponse() (response *SearchUserResponse) {
|
||||
response = &SearchUserResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
27
services/sso/struct.go
Normal file
27
services/sso/struct.go
Normal file
@ -0,0 +1,27 @@
|
||||
package sso
|
||||
|
||||
type User struct {
|
||||
Uid string `json:"uid"`
|
||||
UidNumber string `json:"uidNumber"`
|
||||
Name string `json:"name"`
|
||||
FirstName string `json:"firstname"`
|
||||
LastName string `json:"lastname"`
|
||||
RealName string `json:"realname"`
|
||||
Mobile string `json:"mobile"`
|
||||
Mail string `json:"mail"`
|
||||
Department Department `json:"department"`
|
||||
Roles []Role `json:"roles"`
|
||||
Domains []string `json:"domains"`
|
||||
}
|
||||
|
||||
type Department struct {
|
||||
Gid string `json:"gid"`
|
||||
Name string `json:"name"`
|
||||
Abbr string `json:"abbr"`
|
||||
}
|
||||
|
||||
type Role struct {
|
||||
Name string `json:"name"`
|
||||
Domains []string `json:"domains"`
|
||||
Abbr string `json:"abbr"`
|
||||
}
|
44
services/www/client.go
Normal file
44
services/www/client.go
Normal file
@ -0,0 +1,44 @@
|
||||
package www
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
)
|
||||
|
||||
const (
|
||||
VERSION = "2020-09-24"
|
||||
)
|
||||
|
||||
var HOST requests.Host = requests.Host{
|
||||
Default: "apisdk.9ooo.cn",
|
||||
Func: func(s string) string {
|
||||
var a = map[string]string{
|
||||
requests.RELEASE: "apisdk.9ooo.cn",
|
||||
requests.PRE: "apisdk.9ooo.cn",
|
||||
requests.TEST: "apisdk.9ooo.cn",
|
||||
}
|
||||
return a[s]
|
||||
},
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
sdk.Client
|
||||
}
|
||||
|
||||
func NewClientWithAccessKey(accesskey, secrect, source string) (client *Client, err error) {
|
||||
client = &Client{}
|
||||
err = client.InitWithAccessKey(accesskey, secrect, source)
|
||||
return
|
||||
}
|
||||
|
||||
func NewClientWithAliAppcode(accesskey, secrect string, env ...string) (client *Client, err error) {
|
||||
client = &Client{}
|
||||
err = client.InitWithAliAppcode(accesskey, secrect, env...)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) GetUserInfo(req *GetPwdRequest) (response *GetPwdResponse, err error) {
|
||||
response = CreateGetPwdResponse()
|
||||
err = c.DoAction(req, response)
|
||||
return
|
||||
}
|
25
services/www/client_test.go
Normal file
25
services/www/client_test.go
Normal file
@ -0,0 +1,25 @@
|
||||
package www
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestClient_GetUserInfo(t *testing.T) {
|
||||
|
||||
c, err := NewClientWithAliAppcode("203874304", "9e5489a82dd641729186cdad166d81a3")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
req := CreateGetPwdRequest()
|
||||
req.UserName = "ttom666"
|
||||
|
||||
resp, err := c.GetUserInfo(req)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
fmt.Println(resp.GetHttpContentString())
|
||||
fmt.Println(resp.GetHttpHeaders())
|
||||
}
|
38
services/www/get_pwd.go
Normal file
38
services/www/get_pwd.go
Normal file
@ -0,0 +1,38 @@
|
||||
package www
|
||||
|
||||
import (
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/requests"
|
||||
"golib.gaore.com/GaoreGo/gaore-common-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
type GetPwdRequest struct {
|
||||
*requests.RpcRequest
|
||||
UserName string `position:"Query" field:"user_name" default:"-" `
|
||||
Uid int64 `position:"Query" field:"uid" default:"0"`
|
||||
}
|
||||
|
||||
type GetPwdResponse struct {
|
||||
*responses.BaseResponse
|
||||
Ret int `json:"ret"`
|
||||
Msg string `json:"msg"`
|
||||
Data struct {
|
||||
UserName string `json:"user_name"`
|
||||
UserPwd string `json:"user_pwd"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
func CreateGetPwdRequest() (req *GetPwdRequest) {
|
||||
req = &GetPwdRequest{
|
||||
RpcRequest: &requests.RpcRequest{},
|
||||
}
|
||||
req.InitWithApiInfo(HOST, VERSION, "/api/limit/getPwd.php")
|
||||
req.Method = requests.GET
|
||||
return
|
||||
}
|
||||
|
||||
func CreateGetPwdResponse() (response *GetPwdResponse) {
|
||||
response = &GetPwdResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
1
services/www/get_token.go
Normal file
1
services/www/get_token.go
Normal file
@ -0,0 +1 @@
|
||||
package www
|
Loading…
Reference in New Issue
Block a user