factory.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package imagedata
  2. import (
  3. "bytes"
  4. "encoding/base64"
  5. "io"
  6. "net/http"
  7. "os"
  8. "github.com/imgproxy/imgproxy/v3/imagemeta"
  9. "github.com/imgproxy/imgproxy/v3/imagetype"
  10. "github.com/imgproxy/imgproxy/v3/security"
  11. )
  12. // NewFromBytesWithFormat creates a new ImageData instance from the provided format,
  13. // http headers and byte slice.
  14. func NewFromBytesWithFormat(format imagetype.Type, b []byte, headers http.Header) ImageData {
  15. var h http.Header
  16. if headers == nil {
  17. h = make(http.Header)
  18. } else {
  19. h = headers.Clone()
  20. }
  21. return &imageDataBytes{
  22. data: b,
  23. format: format,
  24. headers: h,
  25. cancel: nil,
  26. }
  27. }
  28. // NewFromBytes creates a new ImageData instance from the provided byte slice.
  29. func NewFromBytes(b []byte) (ImageData, error) {
  30. r := bytes.NewReader(b)
  31. meta, err := imagemeta.DecodeMeta(r)
  32. if err != nil {
  33. return nil, err
  34. }
  35. return NewFromBytesWithFormat(meta.Format(), b, nil), nil
  36. }
  37. // NewFromPath creates a new ImageData from an os.File
  38. func NewFromPath(path string, secopts security.Options) (ImageData, error) {
  39. f, err := os.Open(path)
  40. if err != nil {
  41. return nil, err
  42. }
  43. defer f.Close()
  44. fr, err := security.LimitFileSize(f, secopts)
  45. if err != nil {
  46. return nil, err
  47. }
  48. b, err := io.ReadAll(fr)
  49. if err != nil {
  50. return nil, err
  51. }
  52. r := bytes.NewReader(b)
  53. // NOTE: This will be removed in the future in favor of VIPS metadata extraction
  54. // It's here temporarily to maintain compatibility with existing code
  55. meta, err := imagemeta.DecodeMeta(r)
  56. if err != nil {
  57. return nil, err
  58. }
  59. err = security.CheckMeta(meta, secopts)
  60. if err != nil {
  61. return nil, err
  62. }
  63. return NewFromBytes(b)
  64. }
  65. // NewFromBase64 creates a new ImageData from a base64 encoded byte slice
  66. func NewFromBase64(encoded string, secopts security.Options) (ImageData, error) {
  67. b, err := base64.StdEncoding.DecodeString(encoded)
  68. if err != nil {
  69. return nil, err
  70. }
  71. r := bytes.NewReader(b)
  72. // NOTE: This will be removed in the future in favor of VIPS metadata extraction
  73. // It's here temporarily to maintain compatibility with existing code
  74. meta, err := imagemeta.DecodeMeta(r)
  75. if err != nil {
  76. return nil, err
  77. }
  78. err = security.CheckMeta(meta, secopts)
  79. if err != nil {
  80. return nil, err
  81. }
  82. return NewFromBytes(b)
  83. }