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{} }