curl.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package helpers
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "net/http"
  7. "time"
  8. )
  9. var (
  10. ErrCurlGetStatus = error(&CurlGetStatusError{})
  11. )
  12. type CurlGetOpts struct {
  13. ExpectStatusCode int
  14. Headers map[string][]string
  15. Timeout time.Duration
  16. }
  17. type CurlGetStatusError struct {
  18. Expected int
  19. Received int
  20. }
  21. func (e *CurlGetStatusError) Is(err error) bool {
  22. if _, ok := err.(*CurlGetStatusError); !ok {
  23. return false
  24. }
  25. return true
  26. }
  27. func (e *CurlGetStatusError) Error() string {
  28. return fmt.Sprintf("CurlGet: expected %d, received %d", e.Expected, e.Received)
  29. }
  30. func CurlGet(ctx context.Context, url string, opts *CurlGetOpts) ([]byte, error) {
  31. if opts == nil {
  32. opts = &CurlGetOpts{
  33. ExpectStatusCode: http.StatusOK,
  34. Headers: nil,
  35. Timeout: time.Second * 60,
  36. }
  37. }
  38. var b []byte
  39. ctx, cancel := context.WithTimeout(ctx, opts.Timeout)
  40. defer cancel()
  41. req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
  42. if err != nil {
  43. return b, err
  44. }
  45. req.Header = opts.Headers
  46. rcl := &http.Client{}
  47. var resp *http.Response
  48. resp, err = rcl.Do(req)
  49. if err != nil {
  50. return b, err
  51. }
  52. defer resp.Body.Close()
  53. b, err = io.ReadAll(resp.Body)
  54. if err != nil {
  55. return b, err
  56. }
  57. if opts.ExpectStatusCode > 0 {
  58. if resp.StatusCode != opts.ExpectStatusCode {
  59. return b, error(&CurlGetStatusError{
  60. Expected: opts.ExpectStatusCode,
  61. Received: resp.StatusCode,
  62. })
  63. }
  64. }
  65. return b, nil
  66. }