factory.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package imagedatanew
  2. import (
  3. "bytes"
  4. "encoding/base64"
  5. "io"
  6. "net/http"
  7. "os"
  8. "github.com/imgproxy/imgproxy/v3/asyncbuffer"
  9. "github.com/imgproxy/imgproxy/v3/imagemeta"
  10. "github.com/imgproxy/imgproxy/v3/security"
  11. )
  12. // NewFromFile creates a new ImageData from an os.File
  13. func NewFromFile(path string, headers http.Header, secopts security.Options) (*imageDataBytes, error) {
  14. f, err := os.Open(path)
  15. if err != nil {
  16. return nil, err
  17. }
  18. defer f.Close()
  19. fr, err := security.LimitFileSize(f, secopts)
  20. if err != nil {
  21. return nil, err
  22. }
  23. b, err := io.ReadAll(fr)
  24. if err != nil {
  25. return nil, err
  26. }
  27. r := bytes.NewReader(b)
  28. meta, err := imagemeta.DecodeMeta(r)
  29. if err != nil {
  30. return nil, err
  31. }
  32. err = security.CheckMeta(meta, secopts)
  33. if err != nil {
  34. return nil, err
  35. }
  36. return &imageDataBytes{b, meta, headers.Clone()}, nil
  37. }
  38. // NewFromBase64 creates a new ImageData from a base64 encoded byte slice
  39. func NewFromBase64(encoded string, headers http.Header, secopts security.Options) (*imageDataBytes, error) {
  40. b, err := base64.StdEncoding.DecodeString(encoded)
  41. if err != nil {
  42. return nil, err
  43. }
  44. r := bytes.NewReader(b)
  45. meta, err := imagemeta.DecodeMeta(r)
  46. if err != nil {
  47. return nil, err
  48. }
  49. err = security.CheckMeta(meta, secopts)
  50. if err != nil {
  51. return nil, err
  52. }
  53. return &imageDataBytes{b, meta, headers.Clone()}, nil
  54. }
  55. // NewFromBytes creates a new ImageDataBytes from a byte slice
  56. func NewFromBytes(b []byte, headers http.Header, secopts security.Options) (*imageDataBytes, error) {
  57. r := bytes.NewReader(b)
  58. meta, err := imagemeta.DecodeMeta(r)
  59. if err != nil {
  60. return nil, err
  61. }
  62. err = security.CheckMeta(meta, secopts)
  63. if err != nil {
  64. return nil, err
  65. }
  66. return &imageDataBytes{b, meta, headers.Clone()}, nil
  67. }
  68. // NewFromResponse creates a new ImageDataResponse from an http.Response
  69. func NewFromResponse(or *http.Response, secopts security.Options) (*imageDataResponse, error) {
  70. // We must not close the response body here, as is is read in background
  71. //nolint:bodyclose
  72. r, err := security.LimitResponseSize(or, secopts)
  73. if err != nil {
  74. return nil, err
  75. }
  76. b := asyncbuffer.FromReader(r.Body)
  77. c := r.Body
  78. meta, err := imagemeta.DecodeMeta(b.Reader())
  79. if err != nil {
  80. b.Close() // Close the async buffer early
  81. return nil, err
  82. }
  83. err = security.CheckMeta(meta, secopts)
  84. if err != nil {
  85. b.Close() // Close the async buffer early
  86. return nil, err
  87. }
  88. return &imageDataResponse{b, c, meta, or.Header.Clone()}, nil
  89. }