mirror of
https://github.com/imgproxy/imgproxy.git
synced 2024-11-24 08:12:38 +02:00
Src file size check
This commit is contained in:
parent
6fa0c539bd
commit
0027db5f8a
@ -140,6 +140,7 @@ type config struct {
|
||||
|
||||
MaxSrcDimension int
|
||||
MaxSrcResolution int
|
||||
MaxSrcFileSize int
|
||||
MaxGifFrames int
|
||||
|
||||
JpegProgressive bool
|
||||
@ -253,6 +254,7 @@ func init() {
|
||||
|
||||
intEnvConfig(&conf.MaxSrcDimension, "IMGPROXY_MAX_SRC_DIMENSION")
|
||||
megaIntEnvConfig(&conf.MaxSrcResolution, "IMGPROXY_MAX_SRC_RESOLUTION")
|
||||
intEnvConfig(&conf.MaxSrcFileSize, "IMGPROXY_MAX_SRC_FILE_SIZE")
|
||||
intEnvConfig(&conf.MaxGifFrames, "IMGPROXY_MAX_GIF_FRAMES")
|
||||
|
||||
boolEnvConfig(&conf.JpegProgressive, "IMGPROXY_JPEG_PROGRESSIVE")
|
||||
@ -371,6 +373,10 @@ func init() {
|
||||
logFatal("Max src resolution should be greater than 0, now - %d\n", conf.MaxSrcResolution)
|
||||
}
|
||||
|
||||
if conf.MaxSrcFileSize < 0 {
|
||||
logFatal("Max src file size should be greater than or equal to 0, now - %d\n", conf.MaxSrcFileSize)
|
||||
}
|
||||
|
||||
if conf.MaxGifFrames <= 0 {
|
||||
logFatal("Max GIF frames should be greater than 0, now - %d\n", conf.MaxGifFrames)
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ $ echo $(xxd -g 2 -l 64 -p /dev/random | tr -d '\n')
|
||||
imgproxy protects you from so-called image bombs. Here is how you can specify maximum image resolution which you consider reasonable:
|
||||
|
||||
* `IMGPROXY_MAX_SRC_RESOLUTION`: the maximum resolution of the source image, in megapixels. Images with larger actual size will be rejected. Default: `16.8`;
|
||||
* `IMGPROXY_MAX_SRC_FILE_SIZE`: the maximum size of the source image, in bytes. Images with larger file size will be rejected. When `0`, file size check is disabled. Default: `0`;
|
||||
|
||||
imgproxy can process animated GIFs, but since this operation is pretty heavy, only one frame is processed by default. You can increase the maximum of GIF frames to process with the following variable:
|
||||
|
||||
|
38
download.go
38
download.go
@ -25,7 +25,8 @@ var (
|
||||
imageDataCtxKey = ctxKey("imageData")
|
||||
|
||||
errSourceDimensionsTooBig = newError(422, "Source image dimensions are too big", "Invalid source image")
|
||||
errSourceResolutionTooBig = newError(422, "Source image resolution are too big", "Invalid source image")
|
||||
errSourceResolutionTooBig = newError(422, "Source image resolution is too big", "Invalid source image")
|
||||
errSourceFileTooBig = newError(422, "Source image file is too big", "Invalid source image")
|
||||
errSourceImageTypeNotSupported = newError(422, "Source image type not supported", "Invalid source image")
|
||||
)
|
||||
|
||||
@ -33,6 +34,26 @@ const msgSourceImageIsUnreachable = "Source image is unreachable"
|
||||
|
||||
var downloadBufPool *bufPool
|
||||
|
||||
type limitReader struct {
|
||||
r io.ReadCloser
|
||||
left int
|
||||
}
|
||||
|
||||
func (lr *limitReader) Read(p []byte) (n int, err error) {
|
||||
n, err = lr.r.Read(p)
|
||||
lr.left = lr.left - n
|
||||
|
||||
if err == nil && lr.left < 0 {
|
||||
err = errSourceFileTooBig
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (lr *limitReader) Close() error {
|
||||
return lr.r.Close()
|
||||
}
|
||||
|
||||
func initDownloading() {
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
@ -76,9 +97,12 @@ func checkDimensions(width, height int) error {
|
||||
|
||||
func checkTypeAndDimensions(r io.Reader) (imageType, error) {
|
||||
imgconf, imgtypeStr, err := image.DecodeConfig(r)
|
||||
if err != nil {
|
||||
if err == image.ErrFormat {
|
||||
return imageTypeUnknown, errSourceImageTypeNotSupported
|
||||
}
|
||||
if err != nil {
|
||||
return imageTypeUnknown, err
|
||||
}
|
||||
|
||||
imgtype, imgtypeOk := imageTypes[imgtypeStr]
|
||||
if !imgtypeOk || !vipsTypeSupportLoad[imgtype] {
|
||||
@ -98,7 +122,13 @@ func readAndCheckImage(ctx context.Context, res *http.Response) (context.Context
|
||||
downloadBufPool.put(buf)
|
||||
}
|
||||
|
||||
imgtype, err := checkTypeAndDimensions(io.TeeReader(res.Body, buf))
|
||||
body := res.Body
|
||||
|
||||
if conf.MaxSrcFileSize > 0 {
|
||||
body = &limitReader{r: body, left: conf.MaxSrcFileSize}
|
||||
}
|
||||
|
||||
imgtype, err := checkTypeAndDimensions(io.TeeReader(body, buf))
|
||||
if err != nil {
|
||||
return ctx, cancel, err
|
||||
}
|
||||
@ -116,7 +146,7 @@ func readAndCheckImage(ctx context.Context, res *http.Response) (context.Context
|
||||
buf.Grow(contentLength - buf.Len())
|
||||
}
|
||||
|
||||
if _, err = buf.ReadFrom(res.Body); err != nil {
|
||||
if _, err = buf.ReadFrom(body); err != nil {
|
||||
return ctx, cancel, newError(404, err.Error(), msgSourceImageIsUnreachable)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user