options.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package cloudflare
  2. import (
  3. "net/http"
  4. "time"
  5. "golang.org/x/time/rate"
  6. )
  7. // Option is a functional option for configuring the API client.
  8. type Option func(*API) error
  9. // HTTPClient accepts a custom *http.Client for making API calls.
  10. func HTTPClient(client *http.Client) Option {
  11. return func(api *API) error {
  12. api.httpClient = client
  13. return nil
  14. }
  15. }
  16. // Headers allows you to set custom HTTP headers when making API calls (e.g. for
  17. // satisfying HTTP proxies, or for debugging).
  18. func Headers(headers http.Header) Option {
  19. return func(api *API) error {
  20. api.headers = headers
  21. return nil
  22. }
  23. }
  24. // UsingAccount allows you to apply account-level changes (Load Balancing,
  25. // Railguns) to an account instead.
  26. func UsingAccount(accountID string) Option {
  27. return func(api *API) error {
  28. api.AccountID = accountID
  29. return nil
  30. }
  31. }
  32. // UsingRateLimit applies a non-default rate limit to client API requests
  33. // If not specified the default of 4rps will be applied
  34. func UsingRateLimit(rps float64) Option {
  35. return func(api *API) error {
  36. // because ratelimiter doesnt do any windowing
  37. // setting burst makes it difficult to enforce a fixed rate
  38. // so setting it equal to 1 this effectively disables bursting
  39. // this doesn't check for sensible values, ultimately the api will enforce that the value is ok
  40. api.rateLimiter = rate.NewLimiter(rate.Limit(rps), 1)
  41. return nil
  42. }
  43. }
  44. // UsingRetryPolicy applies a non-default number of retries and min/max retry delays
  45. // This will be used when the client exponentially backs off after errored requests
  46. func UsingRetryPolicy(maxRetries int, minRetryDelaySecs int, maxRetryDelaySecs int) Option {
  47. // seconds is very granular for a minimum delay - but this is only in case of failure
  48. return func(api *API) error {
  49. api.retryPolicy = RetryPolicy{
  50. MaxRetries: maxRetries,
  51. MinRetryDelay: time.Duration(minRetryDelaySecs) * time.Second,
  52. MaxRetryDelay: time.Duration(maxRetryDelaySecs) * time.Second,
  53. }
  54. return nil
  55. }
  56. }
  57. // UsingLogger can be set if you want to get log output from this API instance
  58. // By default no log output is emitted
  59. func UsingLogger(logger Logger) Option {
  60. return func(api *API) error {
  61. api.logger = logger
  62. return nil
  63. }
  64. }
  65. // UserAgent can be set if you want to send a software name and version for HTTP access logs.
  66. // It is recommended to set it in order to help future Customer Support diagnostics
  67. // and prevent collateral damage by sharing generic User-Agent string with abusive users.
  68. // E.g. "my-software/1.2.3". By default generic Go User-Agent is used.
  69. func UserAgent(userAgent string) Option {
  70. return func(api *API) error {
  71. api.UserAgent = userAgent
  72. return nil
  73. }
  74. }
  75. // parseOptions parses the supplied options functions and returns a configured
  76. // *API instance.
  77. func (api *API) parseOptions(opts ...Option) error {
  78. // Range over each options function and apply it to our API type to
  79. // configure it. Options functions are applied in order, with any
  80. // conflicting options overriding earlier calls.
  81. for _, option := range opts {
  82. err := option(api)
  83. if err != nil {
  84. return err
  85. }
  86. }
  87. return nil
  88. }