curl.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package helpers
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "net/http"
  8. "os"
  9. "strings"
  10. "time"
  11. )
  12. var (
  13. ErrCurlGetStatus = error(&CurlGetStatusError{})
  14. )
  15. type CurlGetOpts struct {
  16. ExpectStatusCode int
  17. Headers map[string][]string
  18. Timeout time.Duration
  19. }
  20. type CurlGetStatusError struct {
  21. Expected int
  22. Received int
  23. }
  24. func (e *CurlGetStatusError) Is(err error) bool {
  25. if _, ok := err.(*CurlGetStatusError); !ok {
  26. return false
  27. }
  28. return true
  29. }
  30. func (e *CurlGetStatusError) Error() string {
  31. return fmt.Sprintf("CurlGet: expected %d, received %d", e.Expected, e.Received)
  32. }
  33. func CurlGet(ctx context.Context, url string, opts *CurlGetOpts) ([]byte, error) {
  34. if opts == nil {
  35. opts = &CurlGetOpts{
  36. ExpectStatusCode: http.StatusOK,
  37. Headers: nil,
  38. Timeout: time.Second * 60,
  39. }
  40. }
  41. var b []byte
  42. ctx, cancel := context.WithTimeout(ctx, opts.Timeout)
  43. defer cancel()
  44. req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
  45. if err != nil {
  46. return b, err
  47. }
  48. req.Header = opts.Headers
  49. rcl := &http.Client{}
  50. var resp *http.Response
  51. resp, err = rcl.Do(req)
  52. if err != nil {
  53. return b, err
  54. }
  55. defer resp.Body.Close()
  56. b, err = io.ReadAll(resp.Body)
  57. if err != nil {
  58. return b, err
  59. }
  60. if opts.ExpectStatusCode > 0 {
  61. if resp.StatusCode != opts.ExpectStatusCode {
  62. return b, error(&CurlGetStatusError{
  63. Expected: opts.ExpectStatusCode,
  64. Received: resp.StatusCode,
  65. })
  66. }
  67. }
  68. return b, nil
  69. }
  70. func CurlGetFile(ctx context.Context, url string, opts *CurlGetOpts, fileName string, filePath ...string) error {
  71. dir := strings.Join(filePath, string(os.PathSeparator))
  72. f := strings.Join([]string{dir, fileName}, string(os.PathSeparator))
  73. if _, err := os.Stat(f); !errors.Is(err, os.ErrNotExist) {
  74. return os.ErrExist
  75. }
  76. var (
  77. b []byte
  78. err error
  79. )
  80. if b, err = CurlGet(ctx, url, opts); err != nil {
  81. return err
  82. }
  83. if err := os.MkdirAll(dir, os.ModePerm); err != nil {
  84. return err
  85. }
  86. return os.WriteFile(f, b, 0644)
  87. }