123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- package request
- import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "log"
- "net/http"
- "strings"
- "syno-common/server/utils"
- "time"
- )
- type Option struct {
- Url string
- Resp any
- Accept string
- Headers map[string]string
- ApiKey string
- ApiSecret string
- Sign func(option Option) map[string]string
- }
- // Request 封装请求库
- type Request struct {
- BaseURL string
- Timeout time.Duration
- }
- func defaultSign(option Option) map[string]string {
- if option.Headers == nil {
- option.Headers = map[string]string{}
- }
- apiKey := option.ApiKey
- apiSecret := option.ApiSecret
- timestamp := time.Now().Unix()
- nonce := utils.RandString(16)
- fmt.Printf("key: %v, secret: %v,time: %v,nonce: %v\n", apiKey, apiSecret, timestamp, nonce)
- cipherText := fmt.Sprintf("%v%v%v", apiKey, timestamp, nonce)
- sign, err := utils.AesEncrypt(cipherText, apiSecret)
- if err != nil {
- log.Printf("sign fail: %v", err)
- } else {
- option.Headers["x-api-key"] = apiKey
- option.Headers["x-api-timestamp"] = fmt.Sprintf("%v", timestamp)
- option.Headers["x-api-nonce"] = nonce
- option.Headers["x-api-sign"] = sign
- log.Printf("sign ok: %v", sign)
- }
- //log.Printf("headers: %v", option.Headers)
- return option.Headers
- }
- func NewRequest(baseUrl string, timeout time.Duration) Request {
- return Request{
- BaseURL: baseUrl,
- Timeout: timeout,
- }
- }
- func (r *Request) DoPostJson(requestData any, option Option) (any, error) {
- data, err := json.Marshal(requestData)
- if err != nil {
- return nil, err
- }
- url := fmt.Sprintf("%s%s", r.BaseURL, option.Url)
- if !strings.HasPrefix(option.Url, "/") && !strings.HasSuffix(r.BaseURL, "/") {
- url = fmt.Sprintf("%s/%s", r.BaseURL, option.Url)
- }
- req, err := http.NewRequest("POST", url, bytes.NewReader(data))
- if err != nil {
- return nil, err
- }
- userHeaders := option.Headers
- if option.ApiKey != "" {
- if option.Sign == nil {
- userHeaders = defaultSign(option)
- } else {
- userHeaders = option.Sign(option)
- }
- }
- log.Printf("headers: %v", userHeaders)
- req.Header.Set("Content-Type", "application/json")
- if userHeaders == nil {
- userHeaders = map[string]string{}
- }
- for header := range userHeaders {
- req.Header.Set(header, userHeaders[header])
- }
- client := &http.Client{
- Timeout: r.Timeout,
- }
- rsp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
- if rsp.StatusCode < 200 || rsp.StatusCode > 299 {
- err = errors.New(rsp.Status)
- log.Printf("status: %v", rsp.StatusCode)
- return nil, err
- }
- body, err := io.ReadAll(rsp.Body)
- if err != nil {
- log.Printf("read body fail: %v", err)
- return nil, errors.New("body parse fail")
- }
- if option.Resp != nil {
- err := json.Unmarshal(body, option.Resp)
- if err != nil {
- log.Printf("parse body fail: %v", err)
- return nil, err
- }
- return option.Resp, nil
- }
- if option.Accept == "" || option.Accept == "application/json" {
- var respData = map[string]interface{}{}
- err := json.Unmarshal(body, &respData)
- //log.Printf("resp data: %v", respData)
- if err != nil {
- log.Printf("parse body fail: %v", err)
- return nil, err
- }
- return respData, nil
- }
- return body, nil
- }
- func Test(apiKey string, secret string) {
- request := NewRequest("http://10.10.0.1:20003", time.Second*10)
- data := map[string]interface{}{}
- option := Option{
- Url: "/client/login",
- Resp: nil,
- Accept: "",
- ApiKey: apiKey,
- ApiSecret: secret,
- }
- resp, err := request.DoPostJson(data, option)
- if err != nil {
- log.Fatalln(err)
- }
- log.Printf("resp: %v", resp)
- }
|