download.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package imagedata
  2. import (
  3. "context"
  4. "net/http"
  5. "github.com/imgproxy/imgproxy/v3/config"
  6. "github.com/imgproxy/imgproxy/v3/ierrors"
  7. "github.com/imgproxy/imgproxy/v3/imagefetcher"
  8. "github.com/imgproxy/imgproxy/v3/security"
  9. "github.com/imgproxy/imgproxy/v3/transport"
  10. )
  11. var (
  12. Fetcher *imagefetcher.Fetcher
  13. // For tests
  14. redirectAllRequestsTo string
  15. )
  16. type DownloadOptions struct {
  17. Header http.Header
  18. CookieJar http.CookieJar
  19. }
  20. func initDownloading() error {
  21. ts, err := transport.NewTransport()
  22. if err != nil {
  23. return err
  24. }
  25. Fetcher, err = imagefetcher.NewFetcher(ts, config.MaxRedirects)
  26. if err != nil {
  27. return ierrors.Wrap(err, 0, ierrors.WithPrefix("can't create image fetcher"))
  28. }
  29. return nil
  30. }
  31. func download(ctx context.Context, imageURL string, opts DownloadOptions, secopts security.Options) (ImageData, error) {
  32. // We use this for testing
  33. if len(redirectAllRequestsTo) > 0 {
  34. imageURL = redirectAllRequestsTo
  35. }
  36. req, err := Fetcher.BuildRequest(ctx, imageURL, opts.Header, opts.CookieJar)
  37. if err != nil {
  38. return nil, err
  39. }
  40. defer req.Cancel()
  41. res, err := req.FetchImage()
  42. if err != nil {
  43. if res != nil {
  44. res.Body.Close()
  45. }
  46. return nil, err
  47. }
  48. res, err = security.LimitResponseSize(res, secopts)
  49. if res != nil {
  50. defer res.Body.Close()
  51. }
  52. if err != nil {
  53. return nil, err
  54. }
  55. imgdata, err := readAndCheckImage(res.Body, int(res.ContentLength), secopts)
  56. if err != nil {
  57. return nil, ierrors.Wrap(err, 0)
  58. }
  59. // NOTE: This will be removed in the future in favor of headers/image data separation
  60. for k, v := range res.Header {
  61. for _, v := range v {
  62. imgdata.Headers().Add(k, v)
  63. }
  64. }
  65. return imgdata, nil
  66. }
  67. func RedirectAllRequestsTo(u string) {
  68. redirectAllRequestsTo = u
  69. }
  70. func StopRedirectingRequests() {
  71. redirectAllRequestsTo = ""
  72. }