option.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package client
  2. import (
  3. "context"
  4. "net/http"
  5. "net/http/httputil"
  6. "time"
  7. "github.com/kataras/golog"
  8. "golang.org/x/time/rate"
  9. )
  10. // All the builtin client options should live here, for easy discovery.
  11. type Option = func(*Client)
  12. // BaseURL registers the base URL of this client.
  13. // All of its methods will prepend this url.
  14. func BaseURL(uri string) Option {
  15. return func(c *Client) {
  16. c.BaseURL = uri
  17. }
  18. }
  19. // Timeout specifies a time limit for requests made by this
  20. // Client. The timeout includes connection time, any
  21. // redirects, and reading the response body.
  22. // A Timeout of zero means no timeout.
  23. //
  24. // Defaults to 15 seconds.
  25. func Timeout(d time.Duration) Option {
  26. return func(c *Client) {
  27. c.HTTPClient.Timeout = d
  28. }
  29. }
  30. // Handler specifies an iris.Application or any http.Handler
  31. // instance which can be tested using this Client.
  32. //
  33. // It registers a custom HTTP client transport
  34. // which allows "fake calls" to the "h" server. Use it for testing.
  35. func Handler(h http.Handler) Option {
  36. return func(c *Client) {
  37. c.HTTPClient.Transport = new(handlerTransport)
  38. }
  39. }
  40. // PersistentRequestOptions adds one or more persistent request options
  41. // that all requests made by this Client will respect.
  42. func PersistentRequestOptions(reqOpts ...RequestOption) Option {
  43. return func(c *Client) {
  44. c.PersistentRequestOptions = append(c.PersistentRequestOptions, reqOpts...)
  45. }
  46. }
  47. // RateLimit configures the rate limit for requests.
  48. //
  49. // Defaults to zero which disables rate limiting.
  50. func RateLimit(requestsPerSecond int) Option {
  51. return func(c *Client) {
  52. c.rateLimiter = rate.NewLimiter(rate.Limit(requestsPerSecond), requestsPerSecond)
  53. }
  54. }
  55. // Debug enables the client's debug logger.
  56. // It fires right before request is created
  57. // and right after a response from the server is received.
  58. //
  59. // Example Output for request:
  60. //
  61. // [DBUG] 2022/03/01 21:54 Iris HTTP Client: POST / HTTP/1.1
  62. // Host: 127.0.0.1:50948
  63. // User-Agent: Go-http-client/1.1
  64. // Content-Length: 22
  65. // Accept: application/json
  66. // Content-Type: application/json
  67. // Accept-Encoding: gzip
  68. //
  69. // {"firstname":"Makis"}
  70. //
  71. // Example Output for response:
  72. //
  73. // [DBUG] 2022/03/01 21:54 Iris HTTP Client: HTTP/1.1 200 OK
  74. // Content-Length: 27
  75. // Content-Type: application/json; charset=utf-8
  76. // Date: Tue, 01 Mar 2022 19:54:03 GMT
  77. //
  78. // {
  79. // "firstname": "Makis"
  80. // }
  81. func Debug(c *Client) {
  82. handler := &debugRequestHandler{
  83. logger: golog.Child("Iris HTTP Client: ").SetLevel("debug"),
  84. }
  85. c.requestHandlers = append(c.requestHandlers, handler)
  86. }
  87. type debugRequestHandler struct {
  88. logger *golog.Logger
  89. }
  90. func (h *debugRequestHandler) BeginRequest(ctx context.Context, req *http.Request) error {
  91. dump, err := httputil.DumpRequestOut(req, true)
  92. if err != nil {
  93. return err
  94. }
  95. h.logger.Debug(string(dump))
  96. return nil
  97. }
  98. func (h *debugRequestHandler) EndRequest(ctx context.Context, resp *http.Response, err error) error {
  99. if err != nil {
  100. h.logger.Debugf("%s: %s: ERR: %s", resp.Request.Method, resp.Request.URL.String(), err.Error())
  101. } else {
  102. dump, err := httputil.DumpResponse(resp, true)
  103. if err != nil {
  104. return err
  105. }
  106. h.logger.Debug(string(dump))
  107. }
  108. return err
  109. }