request.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package http
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/json"
  6. "encoding/xml"
  7. "eta_mini_ht_api/common/client"
  8. "github.com/medivhzhan/weapp/v3/logger"
  9. "io"
  10. "mime/multipart"
  11. "net/http"
  12. "os"
  13. )
  14. // ContentType 请求内容类型
  15. type ContentType uint
  16. const (
  17. ContentTypePlain ContentType = iota
  18. ContentTypeXML
  19. ContentTypeJSON
  20. )
  21. func (ctp ContentType) String() string {
  22. switch ctp {
  23. case ContentTypeXML:
  24. return "application/xml"
  25. case ContentTypeJSON:
  26. return "application/json"
  27. default:
  28. return "text/plain"
  29. }
  30. }
  31. type Request struct {
  32. http *client.HttpClient
  33. // 获取日志记录器
  34. logger func() logger.Logger
  35. contentType ContentType
  36. }
  37. func NewRequest(http *client.HttpClient, ctp ContentType, logger func() logger.Logger) *Request {
  38. return &Request{
  39. http: http,
  40. logger: logger,
  41. contentType: ctp,
  42. }
  43. }
  44. func (cli *Request) Get(url string, response interface{}) error {
  45. cli.logger().Info(context.Background(), "request url: %s", url)
  46. resp, err := cli.http.Get(url)
  47. if err != nil {
  48. cli.logger().Error(context.Background(), "get error: %s", err)
  49. return err
  50. }
  51. defer resp.Body.Close()
  52. switch cli.contentType {
  53. case ContentTypeXML:
  54. return xml.NewDecoder(resp.Body).Decode(response)
  55. case ContentTypeJSON:
  56. return json.NewDecoder(resp.Body).Decode(response)
  57. default:
  58. return errors.New("invalid content type")
  59. }
  60. }
  61. func (cli *Request) GetWithBody(url string) (*http.Response, error) {
  62. cli.logger().Info(context.Background(), "request url: %s", url)
  63. rsp, err := cli.http.Get(url)
  64. if err != nil {
  65. cli.logger().Error(context.Background(), "get with body error: %s", url)
  66. return nil, err
  67. }
  68. return rsp, nil
  69. }
  70. func (cli *Request) Post(url string, params interface{}, response interface{}) error {
  71. resp, err := cli.PostWithBody(url, params)
  72. if err != nil {
  73. cli.logger().Error(context.Background(), "post error: %s", err)
  74. return err
  75. }
  76. defer resp.Body.Close()
  77. switch cli.contentType {
  78. case ContentTypeXML:
  79. return xml.NewDecoder(resp.Body).Decode(response)
  80. case ContentTypeJSON:
  81. return json.NewDecoder(resp.Body).Decode(response)
  82. default:
  83. return errors.New("invalid content type")
  84. }
  85. }
  86. func (cli *Request) PostWithBody(url string, params interface{}) (*http.Response, error) {
  87. cli.logger().Info(context.Background(), "request url: %s", url)
  88. cli.logger().Info(context.Background(), "request params: %+v", params)
  89. buf := new(bytes.Buffer)
  90. if params != nil {
  91. switch cli.contentType {
  92. case ContentTypeXML:
  93. err := xml.NewEncoder(buf).Encode(params)
  94. if err != nil {
  95. return nil, err
  96. }
  97. case ContentTypeJSON:
  98. enc := json.NewEncoder(buf)
  99. enc.SetEscapeHTML(false)
  100. err := enc.Encode(params)
  101. if err != nil {
  102. return nil, err
  103. }
  104. default:
  105. return nil, errors.New("invalid content type")
  106. }
  107. }
  108. rsp, err := cli.http.Post(url, cli.contentType.String(), buf)
  109. if err != nil {
  110. cli.logger().Error(context.Background(), "post with body error: %s", url)
  111. return nil, err
  112. }
  113. return rsp, nil
  114. }
  115. func (cli *Request) FormPostWithFile(url, field, filename string, response interface{}) error {
  116. file, err := os.Open(filename)
  117. if err != nil {
  118. return err
  119. }
  120. defer file.Close()
  121. return cli.FormPost(url, field, filename, file, response)
  122. }
  123. func (cli *Request) FormPost(url, field, filename string, reader io.Reader, response interface{}) error {
  124. cli.logger().Info(context.Background(), "request url: %s", url)
  125. // Prepare a form that you will submit to that URL.
  126. buf := new(bytes.Buffer)
  127. w := multipart.NewWriter(buf)
  128. fw, err := w.CreateFormFile(field, filename)
  129. if err != nil {
  130. return err
  131. }
  132. if _, err = io.Copy(fw, reader); err != nil {
  133. return err
  134. }
  135. // Don't forget to close the multipart writer.
  136. // If you don't close it, your request will be missing the terminating boundary.
  137. w.Close()
  138. // Now that you have a form, you can submit it to your handler.
  139. req, err := http.NewRequest("POST", url, buf)
  140. if err != nil {
  141. return err
  142. }
  143. // Don't forget to set the content type, this will contain the boundary.
  144. req.Header.Set("Content-Type", w.FormDataContentType())
  145. resp, err := cli.http.Do(req)
  146. if err != nil {
  147. cli.logger().Error(context.Background(), "form post error: %s", err)
  148. return err
  149. }
  150. defer resp.Body.Close()
  151. switch cli.contentType {
  152. case ContentTypeXML:
  153. return xml.NewDecoder(resp.Body).Decode(response)
  154. case ContentTypeJSON:
  155. return json.NewDecoder(resp.Body).Decode(response)
  156. default:
  157. return errors.New("invalid content type")
  158. }
  159. }