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