HttpClient.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. package http
  2. import (
  3. "bytes"
  4. "fmt"
  5. "git.sxidc.com/student-physical-examination/contract_lock_sdk/commons"
  6. "git.sxidc.com/student-physical-examination/contract_lock_sdk/config"
  7. "io"
  8. "io/ioutil"
  9. "log"
  10. "mime/multipart"
  11. "net/http"
  12. "net/url"
  13. "os"
  14. "path/filepath"
  15. "strings"
  16. )
  17. func DoService(interfaceUrl string, httpParameter *HttpParameter, header *HttpHeader, proxyinfo *config.ProxyInfo) string {
  18. method := httpParameter.HttpMethod()
  19. switch method {
  20. case http.MethodPost:
  21. return Post(interfaceUrl, httpParameter, header, proxyinfo)
  22. case http.MethodGet:
  23. return Get(interfaceUrl, httpParameter, header, proxyinfo)
  24. default:
  25. return ""
  26. }
  27. }
  28. // post请求json格式
  29. func DoServiceWithJson(interfaceUrl string, httpParameter *HttpParameter, header *HttpHeader, proxyinfo *config.ProxyInfo) string {
  30. client := SetProxy(proxyinfo)
  31. req, err := http.NewRequest(http.MethodPost, interfaceUrl, bytes.NewReader([]byte(httpParameter.jsonParamer)))
  32. // 设置header参数
  33. req.Header.Set("Content-Type", "application/json;charset=UTF-8")
  34. SetHeaders(req, header)
  35. return GetResponseAsString(err, req, client)
  36. }
  37. // get请求
  38. func Get(interfaceUrl string, httpParameter *HttpParameter, header *HttpHeader, proxyinfo *config.ProxyInfo) string {
  39. client := SetProxy(proxyinfo)
  40. if len(httpParameter.Params()) > 0 {
  41. params := encodeParams(httpParameter.Params())
  42. encodedURL := url.PathEscape(params)
  43. interfaceUrl += "?" + encodedURL
  44. print(interfaceUrl)
  45. }
  46. req, err := http.NewRequest(http.MethodGet, interfaceUrl, nil)
  47. SetHeaders(req, header)
  48. return GetResponseAsString(err, req, client)
  49. }
  50. // post请求,支持普通参数和文件类型参数
  51. func Post(interfaceUrl string, httpParameter *HttpParameter, header *HttpHeader, proxyinfo *config.ProxyInfo) string {
  52. var req *http.Request
  53. client := SetProxy(proxyinfo)
  54. var err error
  55. if httpParameter.IsMultipart() {
  56. req, err = newFileUploadRequest(interfaceUrl, httpParameter, header)
  57. } else {
  58. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  59. SetHeaders(req, header)
  60. params := encodeParams(httpParameter.Params())
  61. req, err = http.NewRequest(http.MethodPost, interfaceUrl, strings.NewReader(params))
  62. }
  63. return GetResponseAsString(err, req, client)
  64. }
  65. func DoDownloadWithJson(url string, httpParameter *HttpParameter, header *HttpHeader, file *os.File, proxyinfo *config.ProxyInfo) string {
  66. client := SetProxy(proxyinfo)
  67. // 构造请求对象
  68. req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader([]byte(httpParameter.jsonParamer)))
  69. // 设置header参数
  70. req.Header.Set("Content-Type", "application/json;charset=UTF-8")
  71. SetHeaders(req, header)
  72. return GetResponseAsOutputStream(err, req, file, client)
  73. }
  74. func DoDownload(url string, httpParameter *HttpParameter, header *HttpHeader, file *os.File, proxyinfo *config.ProxyInfo) string {
  75. client := SetProxy(proxyinfo)
  76. if len(httpParameter.Params()) > 0 {
  77. url += "?" + encodeParams(httpParameter.Params())
  78. }
  79. req, err := http.NewRequest(http.MethodGet, url, nil)
  80. SetHeaders(req, header)
  81. return GetResponseAsOutputStream(err, req, file, client)
  82. }
  83. // 创建文件上传请求
  84. func newFileUploadRequest(url string, httpParameter *HttpParameter, header *HttpHeader) (*http.Request, error) {
  85. body := &bytes.Buffer{}
  86. writer := multipart.NewWriter(body)
  87. // 普通参数
  88. if len(httpParameter.params) > 0 {
  89. for k, v := range httpParameter.Params() {
  90. if commons.IsNil(v) {
  91. continue
  92. }
  93. switch t := v.(type) {
  94. case string:
  95. if len(t) != 0 {
  96. writer.WriteField(k, t)
  97. }
  98. case *int, *int32, *int64:
  99. if f, ok := v.(*int64); ok {
  100. writer.WriteField(k, fmt.Sprintf("%d", *f))
  101. }
  102. case *float32, *float64:
  103. if f, ok := v.(*float64); ok {
  104. writer.WriteField(k, fmt.Sprintf("%f", *f))
  105. }
  106. case *bool:
  107. if f, ok := v.(*bool); ok {
  108. writer.WriteField(k, fmt.Sprintf("%t", *f))
  109. }
  110. default:
  111. writer.WriteField(k, fmt.Sprintf("%v", t))
  112. }
  113. }
  114. }
  115. // 文件参数
  116. if len(httpParameter.files) > 0 {
  117. for k, v := range httpParameter.Files() {
  118. file, err := os.Open(v.Name())
  119. if err != nil {
  120. log.Println(err)
  121. }
  122. defer file.Close()
  123. part, err := writer.CreateFormFile(k, filepath.Base(v.Name()))
  124. if err != nil {
  125. log.Println(err)
  126. }
  127. _, err = io.Copy(part, file)
  128. if err != nil {
  129. log.Println(err)
  130. }
  131. }
  132. }
  133. // 文件列表参数
  134. if len(httpParameter.listFiles) > 0 {
  135. for k, files := range httpParameter.ListFiles() {
  136. if len(files) > 0 {
  137. for _, v := range files {
  138. file, err := os.Open(v.Name())
  139. if err != nil {
  140. log.Println(err)
  141. }
  142. defer file.Close()
  143. part, err := writer.CreateFormFile(k, filepath.Base(v.Name()))
  144. if err != nil {
  145. log.Println(err)
  146. }
  147. _, err = io.Copy(part, file)
  148. if err != nil {
  149. log.Println(err)
  150. }
  151. }
  152. }
  153. }
  154. }
  155. err := writer.Close()
  156. if err != nil {
  157. return nil, err
  158. }
  159. req, err := http.NewRequest(http.MethodPost, url, body)
  160. req.Header.Set("Content-Type", writer.FormDataContentType())
  161. SetHeaders(req, header)
  162. return req, err
  163. }
  164. // 将返回结果解析为字符串
  165. func GetResponseAsString(err error, req *http.Request, client *http.Client) string {
  166. if err != nil {
  167. log.Fatal("NewRequest failed:", err)
  168. }
  169. response, err := client.Do(req)
  170. if err != nil {
  171. log.Fatal("Do request failed:", err)
  172. }
  173. defer response.Body.Close()
  174. // 处理响应
  175. responseDataBytes, err := ioutil.ReadAll(response.Body)
  176. if err != nil {
  177. log.Fatal("ReadAll failed:", err)
  178. }
  179. return string(responseDataBytes)
  180. }
  181. // 将返回结果解析为流
  182. func GetResponseAsOutputStream(err error, req *http.Request, file *os.File, client *http.Client) string {
  183. if err != nil {
  184. log.Fatal("NewRequest failed:", err)
  185. }
  186. response, err := client.Do(req)
  187. if err != nil {
  188. log.Fatal("Do request failed:", err)
  189. }
  190. defer response.Body.Close()
  191. responseDataBytes, err := ioutil.ReadAll(response.Body)
  192. //处理返回结果
  193. contentType := response.Header.Get("Content-Type")
  194. if len(contentType) > 0 {
  195. lowerStr := strings.ToLower(contentType)
  196. if strings.Contains(lowerStr, "application/json") {
  197. //返回的是字符串
  198. return string(responseDataBytes)
  199. } else {
  200. //返回的是流
  201. if err != nil {
  202. log.Fatal("ReadAll failed:", err)
  203. }
  204. _, err = file.Write(responseDataBytes)
  205. if err != nil {
  206. log.Fatal("WriteFile failed:", err)
  207. os.Exit(1)
  208. }
  209. }
  210. }
  211. return ""
  212. }
  213. // 编码请求参数
  214. func encodeParams(params map[string]interface{}) string {
  215. var parts []string
  216. for k, v := range params {
  217. if commons.IsNil(v) {
  218. continue
  219. }
  220. switch t := v.(type) {
  221. case string:
  222. if len(t) != 0 {
  223. parts = append(parts, k+commons.EQUALSIGN+fmt.Sprintf("%v", t))
  224. }
  225. case *int, *int32, *int64:
  226. if f, ok := v.(*int64); ok {
  227. parts = append(parts, k+commons.EQUALSIGN+fmt.Sprintf("%d", *f))
  228. }
  229. case *float32, *float64:
  230. if f, ok := v.(*float64); ok {
  231. parts = append(parts, k+commons.EQUALSIGN+fmt.Sprintf("%f", *f))
  232. }
  233. case *bool:
  234. if f, ok := v.(*bool); ok {
  235. parts = append(parts, k+commons.EQUALSIGN+fmt.Sprintf("%t", *f))
  236. }
  237. default:
  238. parts = append(parts, k+commons.EQUALSIGN+fmt.Sprintf("%v", t))
  239. }
  240. }
  241. return strings.Join(parts, commons.CONNECTOR)
  242. }
  243. func SetHeaders(req *http.Request, header *HttpHeader) {
  244. req.Header.Set(commons.ACCESS_TOKEN, header.AccessToken)
  245. req.Header.Set(commons.TIMESTAMP, header.Timestamp)
  246. req.Header.Set(commons.SIGNATURE, header.Signature)
  247. req.Header.Set(commons.NONCE, header.Nonce)
  248. req.Header.Set(commons.SIGNATURE_VERSION, header.SignatureVersion)
  249. req.Header.Set(commons.IDEMPOTENTTOKEN, header.IdempotentToken)
  250. req.Header.Set(commons.TRACEID, header.TraceId)
  251. req.Header.Set(commons.BODY, "")
  252. req.Header.Set("Connection", "close")
  253. if header.CustomHeaders != nil && len(header.CustomHeaders) != 0 {
  254. for k, v := range header.CustomHeaders {
  255. req.Header.Set(k, v)
  256. }
  257. }
  258. }
  259. func SetProxy(proxyinfo *config.ProxyInfo) *http.Client {
  260. if proxyinfo != nil {
  261. if len(proxyinfo.ProxyHost) > 0 && len(proxyinfo.ProxyPort) > 0 {
  262. // 创建一个代理 URL
  263. proxyStr := "http://" + proxyinfo.ProxyHost + ":" + proxyinfo.ProxyPort
  264. proxyURL, err := url.Parse(proxyStr)
  265. if err != nil {
  266. fmt.Println("无效的代理 URL:", err)
  267. return &http.Client{}
  268. }
  269. // 设置代理的用户名和密码
  270. if len(proxyinfo.ProxyUsername) > 0 && len(proxyinfo.ProxyPassword) > 0 {
  271. proxyURL.User = url.UserPassword(proxyinfo.ProxyUsername, proxyinfo.ProxyPassword)
  272. }
  273. // 创建一个自定义的 Transport
  274. transport := &http.Transport{
  275. Proxy: http.ProxyURL(proxyURL),
  276. }
  277. // 创建自定义的 Client
  278. client := &http.Client{
  279. Transport: transport,
  280. }
  281. return client
  282. }
  283. }
  284. return &http.Client{}
  285. }