488 lines
12 KiB
Go
488 lines
12 KiB
Go
package opensdk
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/sha256"
|
|
"crypto/tls"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"math/rand"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"path/filepath"
|
|
"qteam/app/third/dfpOpenSdk/config"
|
|
"qteam/app/third/dfpOpenSdk/exception"
|
|
"qteam/app/third/dfpOpenSdk/util"
|
|
"reflect"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type OpenSDK struct {
|
|
Configure config.OpenSdkConfigure
|
|
KeyConfigure config.KeyConfigure
|
|
}
|
|
|
|
func (sdk OpenSDK) Gateway(reqUri string, reqMethod string, headParams map[string]string, urlParams map[string]string, bodyParams map[string]string) {
|
|
//sdk.Configure.GetKeyConfigure()
|
|
}
|
|
|
|
func (sdk OpenSDK) GateWayWithKeyId(reqUri string, reqMethod string, headParams map[string]string,
|
|
urlParams map[string]string, bodyParams map[string]string, keyId string) (string, error) {
|
|
if keyId == "" {
|
|
return "", nil
|
|
}
|
|
|
|
keyConfigure := sdk.Configure.KeyConfigures[keyId]
|
|
if keyConfigure == nil {
|
|
return "", &exception.SdkError{Code: "", Msg: ""}
|
|
}
|
|
result := sdk.exec(reqUri, reqMethod, headParams, urlParams, bodyParams, "", *keyConfigure, "")
|
|
return result, nil
|
|
}
|
|
|
|
func (sdk OpenSDK) GatewayJsonWithKeyId(reqUri string, reqMethod string, headParams map[string]string,
|
|
urlParams map[string]string, bodyJson string, keyId string) (string, error) {
|
|
keyConfigure := sdk.Configure.GetKeyConfigure(keyId)
|
|
|
|
if keyConfigure == nil {
|
|
|
|
return "", &exception.SdkError{Code: "", Msg: ""}
|
|
}
|
|
|
|
if !json.Valid([]byte(bodyJson)) {
|
|
return "", exception.PARAM_ERR()
|
|
}
|
|
|
|
// 发送请求
|
|
exec := sdk.exec(reqUri, reqMethod, headParams, urlParams, nil, "", *keyConfigure, bodyJson)
|
|
return exec, nil
|
|
}
|
|
|
|
// 文件下载
|
|
func (sdk OpenSDK) DownloadFile(fileId string) (string, error) {
|
|
urlParams := make(map[string]string)
|
|
urlParams["fileId"] = fileId
|
|
|
|
// 发送请求
|
|
nonce := getNonce(32)
|
|
authorization := sdk.getAuthInfo("GET", "/api/open/downloadFile", nonce, urlParams, sdk.KeyConfigure)
|
|
|
|
postUrl := sdk.getPostUrl() + "/api/open/downloadFile"
|
|
request, _ := http.NewRequest(http.MethodGet, postUrl, nil)
|
|
|
|
request.Header.Add("Authorization", authorization)
|
|
|
|
client := &http.Client{}
|
|
response, err := client.Do(request)
|
|
if err != nil {
|
|
return response.Status, nil
|
|
}
|
|
body := &bytes.Buffer{}
|
|
writer := multipart.NewWriter(body)
|
|
file, err := os.Open(fileId)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
part, err := writer.CreateFormFile(fileId, fileId)
|
|
_, err = io.Copy(part, file)
|
|
defer func(file *os.File) {
|
|
err := file.Close()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}(file)
|
|
var result string
|
|
return result, nil
|
|
}
|
|
func (sdk OpenSDK) UploadFileWithKeyId(path string, keyId string) (string, error) {
|
|
keyConfigure := sdk.Configure.GetKeyConfigure(keyId)
|
|
|
|
if keyConfigure == nil {
|
|
return "", &exception.SdkError{Code: "", Msg: ""}
|
|
}
|
|
reqUri := "/api/open/uploadFile"
|
|
hash := util.FileHash(path)
|
|
if util.EmptyString(hash) {
|
|
return "", exception.FILE_ERROR_RESULT()
|
|
}
|
|
var bodyParamMap = map[string]string{
|
|
"fileHashValue": hash,
|
|
}
|
|
exec := sdk.exec(reqUri, http.MethodPost, nil, nil, bodyParamMap, path, *keyConfigure, "")
|
|
return exec, nil
|
|
}
|
|
|
|
// UploadFile 文件上传
|
|
func (sdk OpenSDK) UploadFile(path string) (string, error) {
|
|
file, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
// 计算文件hash
|
|
h := sha256.New()
|
|
h.Write(file)
|
|
hash := h.Sum(nil)
|
|
bodyParams := make(map[string]string)
|
|
bodyParams["fileHashValue"] = hex.EncodeToString(hash)
|
|
|
|
buf := new(bytes.Buffer)
|
|
bw := multipart.NewWriter(buf)
|
|
|
|
formFile, err := bw.CreateFormFile("file", path)
|
|
open, err := os.Open(path)
|
|
io.Copy(formFile, open)
|
|
|
|
defer func(bw *multipart.Writer) {
|
|
err := bw.Close()
|
|
if err != nil {
|
|
}
|
|
}(bw)
|
|
nonce := getNonce(32)
|
|
authorization := sdk.getAuthInfo("POST", "/api/open/uploadFile", nonce, bodyParams, sdk.KeyConfigure)
|
|
|
|
// 创建request
|
|
postUrl := sdk.getPostUrl() + "/api/open/uploadFile"
|
|
request, _ := http.NewRequest(http.MethodPost, postUrl, buf)
|
|
request.Header.Add("Authorization", authorization)
|
|
request.Header.Set("Content-Type", "multipart/form-data")
|
|
|
|
client := &http.Client{}
|
|
response, err := client.Do(request)
|
|
|
|
fmt.Println(response.Body)
|
|
// 发送请求
|
|
return "", err
|
|
}
|
|
|
|
func (sdk OpenSDK) DownloadFileWithKeyId(fileId string, saveFilePath, keyId string) (string, error) {
|
|
keyConfigure := sdk.Configure.GetKeyConfigure(keyId)
|
|
|
|
if keyConfigure == nil {
|
|
return "", &exception.SdkError{Code: "", Msg: ""}
|
|
}
|
|
reqUri := "/api/open/downloadFile"
|
|
var urlParamMap = map[string]string{
|
|
"fileId": fileId,
|
|
}
|
|
body := sdk.exec(reqUri, http.MethodGet, nil, urlParamMap, nil, "", *keyConfigure, "")
|
|
if reflect.TypeOf(body).Kind() == reflect.String {
|
|
return body, nil
|
|
}
|
|
|
|
saveFile, err := os.Create(saveFilePath)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
defer func(saveFile *os.File) {
|
|
err := saveFile.Close()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}(saveFile)
|
|
|
|
content := []byte(body)
|
|
write, err := saveFile.Write(content)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if len(content) != write {
|
|
return "", nil
|
|
}
|
|
|
|
return "", nil
|
|
}
|
|
|
|
func (sdk OpenSDK) exec(url string, method string, headParams map[string]string, urlParams map[string]string,
|
|
bodyParamMap map[string]string, filePath string, keyConfigure config.KeyConfigure, bodyJson string) string {
|
|
signParams := make(map[string]string)
|
|
|
|
if headParams != nil {
|
|
for k, v := range headParams {
|
|
signParams[k] = v
|
|
}
|
|
}
|
|
|
|
if urlParams != nil {
|
|
for k, v := range urlParams {
|
|
signParams[k] = v
|
|
}
|
|
}
|
|
|
|
if bodyParamMap != nil {
|
|
for k, v := range bodyParamMap {
|
|
signParams[k] = v
|
|
}
|
|
}
|
|
|
|
if !util.EmptyString(bodyJson) {
|
|
signParams["BODY"] = bodyJson
|
|
}
|
|
|
|
reqUri := util.CheckReqUri(url)
|
|
nonce := getNonce(32)
|
|
authorization := sdk.getAuthInfo(method, reqUri, nonce, signParams, keyConfigure)
|
|
|
|
// 拼接请求参数并进行编码
|
|
urlParamString := util.JointMap(urlParams)
|
|
|
|
buffer := bytes.Buffer{}
|
|
|
|
buffer.WriteString(sdk.getPostUrl())
|
|
buffer.WriteString(reqUri)
|
|
|
|
switch method {
|
|
case http.MethodGet, http.MethodPost:
|
|
if urlParamString != "" {
|
|
if strings.Contains(buffer.String(), "?") {
|
|
buffer.WriteString("&")
|
|
} else {
|
|
buffer.WriteString("?")
|
|
}
|
|
buffer.WriteString(urlParamString)
|
|
}
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
|
|
response := sdk.send(buffer.String(), method, authorization, headParams, filePath, bodyParamMap, keyConfigure, bodyJson)
|
|
|
|
return response
|
|
}
|
|
|
|
// 获取签名信息
|
|
func (sdk OpenSDK) getAuthInfo(method string, reqUri string, nonce string, signParams map[string]string, keyConfigure config.KeyConfigure) string {
|
|
timestamp := time.Now().Format("20060102150405")
|
|
signstr := keyConfigure.KeyId + "&" + timestamp + "&" + nonce + "&" + method + "&" + reqUri
|
|
|
|
keys := make([]string, 0, len(signParams))
|
|
for k := range signParams {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
for _, k := range keys {
|
|
signstr = signstr + "&" + k + "=" + signParams[k]
|
|
}
|
|
|
|
user := keyConfigure.KeyId + "_" + timestamp + "_" + nonce
|
|
|
|
pwd, _ := util.SignatureBySM2(signstr, keyConfigure.PriKey)
|
|
|
|
return "Basic " + base64.StdEncoding.EncodeToString([]byte(user+":"+pwd))
|
|
}
|
|
|
|
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
|
|
|
// 获取n位随机字符串
|
|
func getNonce(n int) string {
|
|
b := make([]rune, n)
|
|
rand.Seed(time.Now().UnixNano())
|
|
for i := range b {
|
|
b[i] = letters[rand.Intn(len(letters))]
|
|
}
|
|
return string(b)
|
|
}
|
|
|
|
// 发送请求
|
|
func (sdk OpenSDK) send(urlPath string, method string, authInfo string, headParams map[string]string, filePath string,
|
|
bodyParamMap map[string]string, keyConfigure config.KeyConfigure, bodyJson string) string {
|
|
var client *http.Client
|
|
|
|
// 测试环境跳过证书校验
|
|
if sdk.Configure.DevEnv {
|
|
tr := &http.Transport{
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
}
|
|
client = &http.Client{Transport: tr}
|
|
} else {
|
|
client = &http.Client{}
|
|
}
|
|
|
|
var request *http.Request
|
|
if method == http.MethodGet {
|
|
request, _ = http.NewRequest(http.MethodGet, urlPath, nil)
|
|
} else {
|
|
if filePath != "" {
|
|
file, _ := os.Open(filePath)
|
|
defer func(file *os.File) {
|
|
err := file.Close()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}(file)
|
|
var requestBody bytes.Buffer
|
|
multipartWriter := multipart.NewWriter(&requestBody)
|
|
|
|
part, err := multipartWriter.CreateFormFile("file", filepath.Base(filePath))
|
|
if err != nil {
|
|
fmt.Println("Failed to create form file:", err)
|
|
}
|
|
|
|
// 将文件内容复制到multipart.Part中
|
|
_, err = io.Copy(part, file)
|
|
if err != nil {
|
|
fmt.Println("Failed to copy file content:", err)
|
|
}
|
|
|
|
// 添加其他表单字段
|
|
for k, v := range bodyParamMap {
|
|
err := multipartWriter.WriteField(k, v)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
}
|
|
|
|
err = multipartWriter.Close()
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
request, _ = http.NewRequest(method, urlPath, &requestBody)
|
|
request.Header.Set("Content-Type", multipartWriter.FormDataContentType())
|
|
} else {
|
|
if bodyJson != "" {
|
|
request, _ = http.NewRequest(method, urlPath, bytes.NewReader([]byte(bodyJson)))
|
|
request.Header.Add("Content-Type", "application/json; charset=UTF-8")
|
|
} else {
|
|
urlValues := url.Values{}
|
|
if bodyParamMap != nil {
|
|
for key, val := range bodyParamMap {
|
|
urlValues.Set(key, val)
|
|
}
|
|
}
|
|
request, _ = http.NewRequest(method, urlPath, strings.NewReader(urlValues.Encode()))
|
|
}
|
|
}
|
|
}
|
|
client.Timeout = time.Second * 30
|
|
|
|
// 设置请求头信息
|
|
sdk.setHeader(authInfo, keyConfigure, request, headParams)
|
|
|
|
// 发送HTTP请求
|
|
response, err := client.Do(request)
|
|
defer func(Body io.ReadCloser) {
|
|
err := Body.Close()
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}(response.Body)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
|
|
// 获取返回结果
|
|
body, err := ioutil.ReadAll(response.Body)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
var result = string(body)
|
|
|
|
timestamp := response.Header.Get("Timestamp")
|
|
nonce := response.Header.Get("Nonce")
|
|
signature := response.Header.Get("Signature")
|
|
if strings.HasPrefix(result, "\"code\":\"OPEN") {
|
|
return result
|
|
}
|
|
// 响应报文验签
|
|
if keyConfigure.RespSignSwitch && !strings.HasPrefix(result, "\"code\":\"OPEN") {
|
|
verify, _ := util.VerifyBySM2([]byte(keyConfigure.KeyId+"&"+timestamp+"&"+nonce+"&"+result), signature, keyConfigure.RespPubKey)
|
|
|
|
if !verify {
|
|
return ""
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
//func (sdk OpenSDK) Get(reqUrl string, reqParams map[string]string, headers map[string]string) string {
|
|
// urlParams := url.Values{}
|
|
// Url, _ := url.Parse(reqUrl)
|
|
// for key, val := range reqParams {
|
|
// urlParams.Set(key, val)
|
|
// }
|
|
//
|
|
// //如果参数中有中文参数,这个方法会进行URLEncode
|
|
// Url.RawQuery = urlParams.Encode()
|
|
// urlPath := Url.String()
|
|
//
|
|
// httpRequest, _ := http.NewRequest("GET", urlPath, nil)
|
|
// // 添加请求头
|
|
// if headers != nil {
|
|
// for k, v := range headers {
|
|
// httpRequest.Header.Add(k, v)
|
|
// }
|
|
// }
|
|
// // 发送请求
|
|
// resp, err := httpClient.Do(httpRequest)
|
|
// if err != nil {
|
|
// panic(err)
|
|
// }
|
|
// defer resp.Body.Close()
|
|
// response, _ := ioutil.ReadAll(resp.Body)
|
|
// return string(response)
|
|
//}
|
|
|
|
// 设置请求头
|
|
func (sdk OpenSDK) setHeader(authInfo string, configure config.KeyConfigure, request *http.Request, headParams map[string]string) {
|
|
if configure.EnterpriseBearer != "" {
|
|
authInfo = authInfo + "," + configure.EnterpriseBearer
|
|
}
|
|
request.Header.Add("Authorization", authInfo)
|
|
if configure.XCfcaBasic != "" {
|
|
request.Header.Add("X-Cfca-Basic", configure.XCfcaBasic)
|
|
}
|
|
|
|
if headParams != nil {
|
|
for k, v := range headParams {
|
|
request.Header.Add(k, v)
|
|
}
|
|
}
|
|
|
|
// 灰度发布配置
|
|
if configure.GrayConfigure != nil && len(configure.GrayConfigure) != 0 {
|
|
for k, v := range configure.GrayConfigure {
|
|
request.Header.Add(k, v)
|
|
}
|
|
}
|
|
}
|
|
|
|
//func (sdk OpenSDK) createRequest(urlPath string, method string, bodyJson string) *http.Request {
|
|
// if method == http.MethodGet {
|
|
// //request, err := http.NewRequest(http.MethodGet, urlPath, nil)
|
|
// } else if method == http.MethodPost {
|
|
// if bodyJson != "" {
|
|
// request, _ = http.NewRequest(method, urlPath, bytes.NewReader([]byte(bodyJson)))
|
|
// request.Header.Add("Content-Type", "application/json; charset=UTF-8")
|
|
// } else {
|
|
// request, _ = http.NewRequest(method, urlPath, strings.NewReader(urlValues.Encode()))
|
|
// }
|
|
// }
|
|
// return nil
|
|
//}
|
|
|
|
func (sdk OpenSDK) getPostUrl() string {
|
|
var urlPath = ""
|
|
if sdk.Configure.DevEnv {
|
|
urlPath = sdk.Configure.DevUrl
|
|
} else {
|
|
urlPath = sdk.Configure.ProdUrl
|
|
}
|
|
|
|
if urlPath != "" && strings.HasSuffix(urlPath, "/") {
|
|
return urlPath[0 : len(urlPath)-1]
|
|
}
|
|
|
|
return urlPath
|
|
}
|