|
|
@@ -0,0 +1,299 @@
|
|
|
+package http
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "fmt"
|
|
|
+ "io"
|
|
|
+ "io/ioutil"
|
|
|
+ "log"
|
|
|
+ "mime/multipart"
|
|
|
+ "net/http"
|
|
|
+ "net/url"
|
|
|
+ "os"
|
|
|
+ "path/filepath"
|
|
|
+ "private-go-sdk/commons"
|
|
|
+ "private-go-sdk/config"
|
|
|
+ "strings"
|
|
|
+)
|
|
|
+
|
|
|
+func DoService(interfaceUrl string, httpParameter *HttpParameter, header *HttpHeader, proxyinfo *config.ProxyInfo) string {
|
|
|
+ method := httpParameter.HttpMethod()
|
|
|
+ switch method {
|
|
|
+ case http.MethodPost:
|
|
|
+ return Post(interfaceUrl, httpParameter, header, proxyinfo)
|
|
|
+ case http.MethodGet:
|
|
|
+ return Get(interfaceUrl, httpParameter, header, proxyinfo)
|
|
|
+ default:
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// post请求json格式
|
|
|
+func DoServiceWithJson(interfaceUrl string, httpParameter *HttpParameter, header *HttpHeader, proxyinfo *config.ProxyInfo) string {
|
|
|
+ client := SetProxy(proxyinfo)
|
|
|
+ req, err := http.NewRequest(http.MethodPost, interfaceUrl, bytes.NewReader([]byte(httpParameter.jsonParamer)))
|
|
|
+ // 设置header参数
|
|
|
+ req.Header.Set("Content-Type", "application/json;charset=UTF-8")
|
|
|
+ SetHeaders(req, header)
|
|
|
+ return GetResponseAsString(err, req, client)
|
|
|
+}
|
|
|
+
|
|
|
+// get请求
|
|
|
+func Get(interfaceUrl string, httpParameter *HttpParameter, header *HttpHeader, proxyinfo *config.ProxyInfo) string {
|
|
|
+ client := SetProxy(proxyinfo)
|
|
|
+ if len(httpParameter.Params()) > 0 {
|
|
|
+ params := encodeParams(httpParameter.Params())
|
|
|
+ encodedURL := url.PathEscape(params)
|
|
|
+ interfaceUrl += "?" + encodedURL
|
|
|
+ print(interfaceUrl)
|
|
|
+
|
|
|
+ }
|
|
|
+ req, err := http.NewRequest(http.MethodGet, interfaceUrl, nil)
|
|
|
+ SetHeaders(req, header)
|
|
|
+ return GetResponseAsString(err, req, client)
|
|
|
+}
|
|
|
+
|
|
|
+// post请求,支持普通参数和文件类型参数
|
|
|
+func Post(interfaceUrl string, httpParameter *HttpParameter, header *HttpHeader, proxyinfo *config.ProxyInfo) string {
|
|
|
+ var req *http.Request
|
|
|
+ client := SetProxy(proxyinfo)
|
|
|
+ var err error
|
|
|
+ if httpParameter.IsMultipart() {
|
|
|
+ req, err = newFileUploadRequest(interfaceUrl, httpParameter, header)
|
|
|
+ } else {
|
|
|
+ req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
|
+ SetHeaders(req, header)
|
|
|
+ params := encodeParams(httpParameter.Params())
|
|
|
+ req, err = http.NewRequest(http.MethodPost, interfaceUrl, strings.NewReader(params))
|
|
|
+ }
|
|
|
+ return GetResponseAsString(err, req, client)
|
|
|
+}
|
|
|
+
|
|
|
+func DoDownloadWithJson(url string, httpParameter *HttpParameter, header *HttpHeader, file *os.File, proxyinfo *config.ProxyInfo) string {
|
|
|
+ client := SetProxy(proxyinfo)
|
|
|
+ // 构造请求对象
|
|
|
+ req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader([]byte(httpParameter.jsonParamer)))
|
|
|
+ // 设置header参数
|
|
|
+ req.Header.Set("Content-Type", "application/json;charset=UTF-8")
|
|
|
+ SetHeaders(req, header)
|
|
|
+ return GetResponseAsOutputStream(err, req, file, client)
|
|
|
+}
|
|
|
+
|
|
|
+func DoDownload(url string, httpParameter *HttpParameter, header *HttpHeader, file *os.File, proxyinfo *config.ProxyInfo) string {
|
|
|
+ client := SetProxy(proxyinfo)
|
|
|
+ if len(httpParameter.Params()) > 0 {
|
|
|
+ url += "?" + encodeParams(httpParameter.Params())
|
|
|
+ }
|
|
|
+ req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
|
+ SetHeaders(req, header)
|
|
|
+ return GetResponseAsOutputStream(err, req, file, client)
|
|
|
+}
|
|
|
+
|
|
|
+// 创建文件上传请求
|
|
|
+func newFileUploadRequest(url string, httpParameter *HttpParameter, header *HttpHeader) (*http.Request, error) {
|
|
|
+ body := &bytes.Buffer{}
|
|
|
+ writer := multipart.NewWriter(body)
|
|
|
+ // 普通参数
|
|
|
+ if len(httpParameter.params) > 0 {
|
|
|
+ for k, v := range httpParameter.Params() {
|
|
|
+ if commons.IsNil(v) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ switch t := v.(type) {
|
|
|
+ case string:
|
|
|
+ if len(t) != 0 {
|
|
|
+ writer.WriteField(k, t)
|
|
|
+ }
|
|
|
+ case *int, *int32, *int64:
|
|
|
+ if f, ok := v.(*int64); ok {
|
|
|
+ writer.WriteField(k, fmt.Sprintf("%d", *f))
|
|
|
+ }
|
|
|
+ case *float32, *float64:
|
|
|
+ if f, ok := v.(*float64); ok {
|
|
|
+ writer.WriteField(k, fmt.Sprintf("%f", *f))
|
|
|
+ }
|
|
|
+ case *bool:
|
|
|
+ if f, ok := v.(*bool); ok {
|
|
|
+ writer.WriteField(k, fmt.Sprintf("%t", *f))
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ writer.WriteField(k, fmt.Sprintf("%v", t))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 文件参数
|
|
|
+ if len(httpParameter.files) > 0 {
|
|
|
+ for k, v := range httpParameter.Files() {
|
|
|
+ file, err := os.Open(v.Name())
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ defer file.Close()
|
|
|
+ part, err := writer.CreateFormFile(k, filepath.Base(v.Name()))
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ _, err = io.Copy(part, file)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 文件列表参数
|
|
|
+ if len(httpParameter.listFiles) > 0 {
|
|
|
+ for k, files := range httpParameter.ListFiles() {
|
|
|
+ if len(files) > 0 {
|
|
|
+ for _, v := range files {
|
|
|
+ file, err := os.Open(v.Name())
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ defer file.Close()
|
|
|
+ part, err := writer.CreateFormFile(k, filepath.Base(v.Name()))
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ _, err = io.Copy(part, file)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ err := writer.Close()
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ req, err := http.NewRequest(http.MethodPost, url, body)
|
|
|
+ req.Header.Set("Content-Type", writer.FormDataContentType())
|
|
|
+ SetHeaders(req, header)
|
|
|
+ return req, err
|
|
|
+}
|
|
|
+
|
|
|
+// 将返回结果解析为字符串
|
|
|
+func GetResponseAsString(err error, req *http.Request, client *http.Client) string {
|
|
|
+ if err != nil {
|
|
|
+ log.Fatal("NewRequest failed:", err)
|
|
|
+ }
|
|
|
+ response, err := client.Do(req)
|
|
|
+ if err != nil {
|
|
|
+ log.Fatal("Do request failed:", err)
|
|
|
+ }
|
|
|
+ defer response.Body.Close()
|
|
|
+ // 处理响应
|
|
|
+ responseDataBytes, err := ioutil.ReadAll(response.Body)
|
|
|
+ if err != nil {
|
|
|
+ log.Fatal("ReadAll failed:", err)
|
|
|
+ }
|
|
|
+ return string(responseDataBytes)
|
|
|
+}
|
|
|
+
|
|
|
+// 将返回结果解析为流
|
|
|
+func GetResponseAsOutputStream(err error, req *http.Request, file *os.File, client *http.Client) string {
|
|
|
+ if err != nil {
|
|
|
+ log.Fatal("NewRequest failed:", err)
|
|
|
+ }
|
|
|
+ response, err := client.Do(req)
|
|
|
+ if err != nil {
|
|
|
+ log.Fatal("Do request failed:", err)
|
|
|
+ }
|
|
|
+ defer response.Body.Close()
|
|
|
+ responseDataBytes, err := ioutil.ReadAll(response.Body)
|
|
|
+ //处理返回结果
|
|
|
+ contentType := response.Header.Get("Content-Type")
|
|
|
+ if len(contentType) > 0 {
|
|
|
+ lowerStr := strings.ToLower(contentType)
|
|
|
+ if strings.Contains(lowerStr, "application/json") {
|
|
|
+ //返回的是字符串
|
|
|
+ return string(responseDataBytes)
|
|
|
+ } else {
|
|
|
+ //返回的是流
|
|
|
+ if err != nil {
|
|
|
+ log.Fatal("ReadAll failed:", err)
|
|
|
+ }
|
|
|
+ _, err = file.Write(responseDataBytes)
|
|
|
+ if err != nil {
|
|
|
+ log.Fatal("WriteFile failed:", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+}
|
|
|
+
|
|
|
+// 编码请求参数
|
|
|
+func encodeParams(params map[string]interface{}) string {
|
|
|
+ var parts []string
|
|
|
+ for k, v := range params {
|
|
|
+ if commons.IsNil(v) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ switch t := v.(type) {
|
|
|
+ case string:
|
|
|
+ if len(t) != 0 {
|
|
|
+ parts = append(parts, k+commons.EQUALSIGN+fmt.Sprintf("%v", t))
|
|
|
+ }
|
|
|
+ case *int, *int32, *int64:
|
|
|
+ if f, ok := v.(*int64); ok {
|
|
|
+ parts = append(parts, k+commons.EQUALSIGN+fmt.Sprintf("%d", *f))
|
|
|
+ }
|
|
|
+ case *float32, *float64:
|
|
|
+ if f, ok := v.(*float64); ok {
|
|
|
+ parts = append(parts, k+commons.EQUALSIGN+fmt.Sprintf("%f", *f))
|
|
|
+ }
|
|
|
+ case *bool:
|
|
|
+ if f, ok := v.(*bool); ok {
|
|
|
+ parts = append(parts, k+commons.EQUALSIGN+fmt.Sprintf("%t", *f))
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ parts = append(parts, k+commons.EQUALSIGN+fmt.Sprintf("%v", t))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return strings.Join(parts, commons.CONNECTOR)
|
|
|
+}
|
|
|
+
|
|
|
+func SetHeaders(req *http.Request, header *HttpHeader) {
|
|
|
+ req.Header.Set(commons.ACCESS_TOKEN, header.AccessToken)
|
|
|
+ req.Header.Set(commons.TIMESTAMP, header.Timestamp)
|
|
|
+ req.Header.Set(commons.SIGNATURE, header.Signature)
|
|
|
+ req.Header.Set(commons.NONCE, header.Nonce)
|
|
|
+ req.Header.Set(commons.SIGNATURE_VERSION, header.SignatureVersion)
|
|
|
+ req.Header.Set(commons.IDEMPOTENTTOKEN, header.IdempotentToken)
|
|
|
+ req.Header.Set(commons.TRACEID, header.TraceId)
|
|
|
+ req.Header.Set(commons.BODY, "")
|
|
|
+ req.Header.Set("Connection", "close")
|
|
|
+ if header.CustomHeaders != nil && len(header.CustomHeaders) != 0 {
|
|
|
+ for k, v := range header.CustomHeaders {
|
|
|
+ req.Header.Set(k, v)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func SetProxy(proxyinfo *config.ProxyInfo) *http.Client {
|
|
|
+ if proxyinfo != nil {
|
|
|
+ if len(proxyinfo.ProxyHost) > 0 && len(proxyinfo.ProxyPort) > 0 {
|
|
|
+ // 创建一个代理 URL
|
|
|
+ proxyStr := "http://" + proxyinfo.ProxyHost + ":" + proxyinfo.ProxyPort
|
|
|
+ proxyURL, err := url.Parse(proxyStr)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("无效的代理 URL:", err)
|
|
|
+ return &http.Client{}
|
|
|
+ }
|
|
|
+ // 设置代理的用户名和密码
|
|
|
+ if len(proxyinfo.ProxyUsername) > 0 && len(proxyinfo.ProxyPassword) > 0 {
|
|
|
+ proxyURL.User = url.UserPassword(proxyinfo.ProxyUsername, proxyinfo.ProxyPassword)
|
|
|
+ }
|
|
|
+ // 创建一个自定义的 Transport
|
|
|
+ transport := &http.Transport{
|
|
|
+ Proxy: http.ProxyURL(proxyURL),
|
|
|
+ }
|
|
|
+ // 创建自定义的 Client
|
|
|
+ client := &http.Client{
|
|
|
+ Transport: transport,
|
|
|
+ }
|
|
|
+ return client
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return &http.Client{}
|
|
|
+}
|