IMG-13: http.Header, *ImageData -> ImageData (#1473)

* ImageData.Headers()

* *ImageData -> ImageData

* withmatt -> httpheaders of our own

* .Clone() headers, nil

* NewFromBytesWithFormat -> nil

* svg.go -> do not Clone()
This commit is contained in:
Victor Sokolov
2025-08-01 15:44:21 +02:00
committed by GitHub
parent e40851e460
commit 3d14c85de3
39 changed files with 356 additions and 258 deletions

View File

@@ -2,15 +2,37 @@ package imagedata
import (
"bytes"
"encoding/base64"
"io"
"net/http"
"strings"
"os"
"github.com/imgproxy/imgproxy/v3/imagemeta"
"github.com/imgproxy/imgproxy/v3/imagetype"
"github.com/imgproxy/imgproxy/v3/security"
)
// NewFromBytesWithFormat creates a new ImageData instance from the provided format,
// http headers and byte slice.
func NewFromBytesWithFormat(format imagetype.Type, b []byte, headers http.Header) ImageData {
var h http.Header
if headers == nil {
h = make(http.Header)
} else {
h = headers.Clone()
}
return &imageDataBytes{
data: b,
format: format,
headers: h,
cancel: nil,
}
}
// NewFromBytes creates a new ImageData instance from the provided byte slice.
func NewFromBytes(b []byte, headers http.Header) (*ImageData, error) {
func NewFromBytes(b []byte) (ImageData, error) {
r := bytes.NewReader(b)
meta, err := imagemeta.DecodeMeta(r)
@@ -18,20 +40,64 @@ func NewFromBytes(b []byte, headers http.Header) (*ImageData, error) {
return nil, err
}
return NewFromBytesWithFormat(meta.Format(), b, headers)
return NewFromBytesWithFormat(meta.Format(), b, nil), nil
}
// NewFromBytesWithFormat creates a new ImageData instance from the provided format and byte slice.
func NewFromBytesWithFormat(format imagetype.Type, b []byte, headers http.Header) (*ImageData, error) {
// Temporary workaround for the old ImageData interface
h := make(map[string]string, len(headers))
for k, v := range headers {
h[k] = strings.Join(v, ", ")
// NewFromPath creates a new ImageData from an os.File
func NewFromPath(path string, secopts security.Options) (ImageData, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
fr, err := security.LimitFileSize(f, secopts)
if err != nil {
return nil, err
}
return &ImageData{
data: b,
format: format,
Headers: h,
}, nil
b, err := io.ReadAll(fr)
if err != nil {
return nil, err
}
r := bytes.NewReader(b)
// NOTE: This will be removed in the future in favor of VIPS metadata extraction
// It's here temporarily to maintain compatibility with existing code
meta, err := imagemeta.DecodeMeta(r)
if err != nil {
return nil, err
}
err = security.CheckMeta(meta, secopts)
if err != nil {
return nil, err
}
return NewFromBytes(b)
}
// NewFromBase64 creates a new ImageData from a base64 encoded byte slice
func NewFromBase64(encoded string, secopts security.Options) (ImageData, error) {
b, err := base64.StdEncoding.DecodeString(encoded)
if err != nil {
return nil, err
}
r := bytes.NewReader(b)
// NOTE: This will be removed in the future in favor of VIPS metadata extraction
// It's here temporarily to maintain compatibility with existing code
meta, err := imagemeta.DecodeMeta(r)
if err != nil {
return nil, err
}
err = security.CheckMeta(meta, secopts)
if err != nil {
return nil, err
}
return NewFromBytes(b)
}