client.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package request
  2. import (
  3. "bytes"
  4. "io"
  5. "net/http"
  6. "net/http/cookiejar"
  7. "strings"
  8. )
  9. type (
  10. BeforeRequest func(req *http.Request) (err error)
  11. AfterRequest func(req *http.Request, res *http.Response) (err error)
  12. Client struct {
  13. baseUrl string
  14. Authorization Authorization
  15. client *http.Client
  16. cookieJar *cookiejar.Jar
  17. interceptorRequest []BeforeRequest
  18. interceptorResponse []AfterRequest
  19. }
  20. )
  21. func (client *Client) stashUri(urlPath string) string {
  22. var (
  23. pos int
  24. )
  25. if len(urlPath) == 0 {
  26. return client.baseUrl
  27. }
  28. if pos = strings.Index(urlPath, "//"); pos == -1 {
  29. if client.baseUrl != "" {
  30. if urlPath[0] != '/' {
  31. urlPath = "/" + urlPath
  32. }
  33. return client.baseUrl + urlPath
  34. }
  35. }
  36. return urlPath
  37. }
  38. func (client *Client) BeforeRequest(cb BeforeRequest) *Client {
  39. client.interceptorRequest = append(client.interceptorRequest, cb)
  40. return client
  41. }
  42. func (client *Client) AfterRequest(cb AfterRequest) *Client {
  43. client.interceptorResponse = append(client.interceptorResponse, cb)
  44. return client
  45. }
  46. func (client *Client) SetBaseUrl(s string) *Client {
  47. client.baseUrl = strings.TrimSuffix(s, "/")
  48. return client
  49. }
  50. func (client *Client) SetCookieJar(cookieJar *cookiejar.Jar) *Client {
  51. client.client.Jar = cookieJar
  52. return client
  53. }
  54. func (client *Client) SetClient(httpClient *http.Client) *Client {
  55. client.client = httpClient
  56. if client.cookieJar != nil {
  57. client.client.Jar = client.cookieJar
  58. }
  59. return client
  60. }
  61. func (client *Client) SetTransport(transport http.RoundTripper) *Client {
  62. client.client.Transport = transport
  63. return client
  64. }
  65. func (client *Client) Get(urlPath string) *Request {
  66. return newRequest(http.MethodGet, client.stashUri(urlPath), client)
  67. }
  68. func (client *Client) Put(urlPath string) *Request {
  69. return newRequest(http.MethodPut, client.stashUri(urlPath), client)
  70. }
  71. func (client *Client) Post(urlPath string) *Request {
  72. return newRequest(http.MethodPost, client.stashUri(urlPath), client)
  73. }
  74. func (client *Client) Delete(urlPath string) *Request {
  75. return newRequest(http.MethodDelete, client.stashUri(urlPath), client)
  76. }
  77. func (client *Client) execute(r *Request) (res *http.Response, err error) {
  78. var (
  79. n int
  80. buf []byte
  81. reader io.Reader
  82. )
  83. if r.contentType == "" && r.body != nil {
  84. r.contentType = r.detectContentType(r.body)
  85. }
  86. if r.body != nil {
  87. if buf, err = r.readRequestBody(r.contentType, r.body); err != nil {
  88. return
  89. }
  90. reader = bytes.NewReader(buf)
  91. }
  92. if r.rawRequest, err = http.NewRequest(r.method, r.uri, reader); err != nil {
  93. return
  94. }
  95. for k, vs := range r.header {
  96. for _, v := range vs {
  97. r.rawRequest.Header.Add(k, v)
  98. }
  99. }
  100. if r.contentType != "" {
  101. r.rawRequest.Header.Set("Content-Type", r.contentType)
  102. }
  103. if client.Authorization != nil {
  104. r.rawRequest.Header.Set("Authorization", client.Authorization.Token())
  105. }
  106. if r.context != nil {
  107. r.rawRequest = r.rawRequest.WithContext(r.context)
  108. }
  109. n = len(client.interceptorRequest)
  110. for i := n - 1; i >= 0; i-- {
  111. if err = client.interceptorRequest[i](r.rawRequest); err != nil {
  112. return
  113. }
  114. }
  115. if r.rawResponse, err = client.client.Do(r.rawRequest); err != nil {
  116. return nil, err
  117. }
  118. n = len(client.interceptorResponse)
  119. for i := n - 1; i >= 0; i-- {
  120. if err = client.interceptorResponse[i](r.rawRequest, r.rawResponse); err != nil {
  121. _ = r.rawResponse.Body.Close()
  122. return
  123. }
  124. }
  125. return r.rawResponse, err
  126. }
  127. func New() *Client {
  128. client := &Client{
  129. client: http.DefaultClient,
  130. interceptorRequest: make([]BeforeRequest, 0, 10),
  131. interceptorResponse: make([]AfterRequest, 0, 10),
  132. }
  133. client.cookieJar, _ = cookiejar.New(nil)
  134. client.client.Jar = client.cookieJar
  135. return client
  136. }