Say which input the image processor refuses before decoding
check / check (push) Successful in 16m44s
check / check (push) Successful in 16m44s
README.md, the doc comment of ErrUnsupportedInputFormat and the TODO.md entry say the 415 is for input whose first bytes libvips reads as another format, and no longer read as refusing a damaged image in a source format, which is decoded and answers 500. The doc comment of TestImageProcessor_OrigOfUnnamedFormatRefused says TIFF is refused before it is decoded. Model: opus-5-5
This commit is contained in:
@@ -192,9 +192,10 @@ path under `/v1/` answers 200, in maintenance mode too.
|
|||||||
address in a blocked network (see `blocked_networks`); 429 over
|
address in a blocked network (see `blocked_networks`); 429 over
|
||||||
`image_requests_per_minute` (below); 415 when the upstream answers with a
|
`image_requests_per_minute` (below); 415 when the upstream answers with a
|
||||||
`Content-Type` that is not one of the source formats (below), or with an image
|
`Content-Type` that is not one of the source formats (below), or with an image
|
||||||
libvips would not load as one of them; 502 when the upstream answered with an
|
whose first bytes libvips reads as another format; 502 when the upstream
|
||||||
error status, and for 5 minutes after that for the same source URL; 503 when
|
answered with an error status, and for 5 minutes after that for the same
|
||||||
pixa is busy or in maintenance mode; 500 for any other failure.
|
source URL; 503 when pixa is busy or in maintenance mode; 500 for any other
|
||||||
|
failure.
|
||||||
- `GET` or `HEAD` `/v1/e/<token>/<name>` — an image through an encrypted URL
|
- `GET` or `HEAD` `/v1/e/<token>/<name>` — an image through an encrypted URL
|
||||||
(see Encrypted URLs). Needs: nothing but the URL. Answers: 200; 304 when
|
(see Encrypted URLs). Needs: nothing but the URL. Answers: 200; 304 when
|
||||||
`If-None-Match` matches the image's `ETag`; 400 for a token that does not
|
`If-None-Match` matches the image's `ETag`; 400 for a token that does not
|
||||||
@@ -265,8 +266,8 @@ once, is refused with 400.
|
|||||||
The source image may be JPEG, PNG, GIF, WebP, AVIF or JPEG XL. The upstream's
|
The source image may be JPEG, PNG, GIF, WebP, AVIF or JPEG XL. The upstream's
|
||||||
`Content-Type` must name its format, and the image's first bytes must match it.
|
`Content-Type` must name its format, and the image's first bytes must match it.
|
||||||
An upstream answering with any other `Content-Type`, SVG included, is refused
|
An upstream answering with any other `Content-Type`, SVG included, is refused
|
||||||
with 415, and so is an image that libvips would not load as one of these
|
with 415, and so is an image whose first bytes libvips reads as another format,
|
||||||
formats, such as an SVG whose first bytes pass the check for AVIF.
|
such as an SVG whose first bytes pass the check for AVIF.
|
||||||
|
|
||||||
With the format `auto`, pixa chooses the format for each request from its
|
With the format `auto`, pixa chooses the format for each request from its
|
||||||
`Accept` header, in this order:
|
`Accept` header, in this order:
|
||||||
|
|||||||
@@ -36,14 +36,16 @@ P2: security: per-origin rate limiting
|
|||||||
an upstream `Content-Type` that is not one of the source formats, SVG
|
an upstream `Content-Type` that is not one of the source formats, SVG
|
||||||
included, where they answered 500. Before decoding, the image processor
|
included, where they answered 500. Before decoding, the image processor
|
||||||
refuses with `ErrUnsupportedInputFormat`, also answered 415, any input that
|
refuses with `ErrUnsupportedInputFormat`, also answered 415, any input that
|
||||||
govips' `DetermineImageType`, which picks the libvips loader, does not name as
|
govips' `DetermineImageType`, which picks the libvips loader from the first
|
||||||
a source format. That catches an SVG whose first bytes pass the first-bytes
|
bytes, does not name as a source format. That catches an SVG whose first bytes
|
||||||
check for another type, as an XML comment can make them do for AVIF; an SVG
|
pass the first-bytes check for another type, as an XML comment can make them
|
||||||
whose first bytes do not pass that check answers 500, as before. `orig` is
|
do for AVIF; an SVG whose first bytes do not pass that check answers 500, as
|
||||||
always the source's own format, where a source the processor could not name
|
before, and so does a damaged image in a source format, whose first bytes
|
||||||
was saved as JPEG. `README.md` no longer lists SVG. The SVG detection in
|
`DetermineImageType` names. `orig` is always the source's own format, where a
|
||||||
`internal/magic` stays: the request path does not call it, and it goes with
|
source the processor could not name was saved as JPEG. `README.md` no longer
|
||||||
the unused code of https://git.eeqj.de/sneak/pixa/issues/168.
|
lists SVG. The SVG detection in `internal/magic` stays: the request path does
|
||||||
|
not call it, and it goes with the unused code of
|
||||||
|
https://git.eeqj.de/sneak/pixa/issues/168.
|
||||||
- 2026-10-12 per-client limit on the image routes (closes #236): the new setting
|
- 2026-10-12 per-client limit on the image routes (closes #236): the new setting
|
||||||
`image_requests_per_minute` (`PIXA_IMAGE_REQUESTS_PER_MINUTE`), default 600,
|
`image_requests_per_minute` (`PIXA_IMAGE_REQUESTS_PER_MINUTE`), default 600,
|
||||||
is how many `GET` and `HEAD` requests one client may send to `/v1/image/` and
|
is how many `GET` and `HEAD` requests one client may send to `/v1/image/` and
|
||||||
|
|||||||
@@ -138,7 +138,9 @@ var ErrInputDataTooLarge = errors.New("input data exceeds maximum allowed size")
|
|||||||
var ErrUnsupportedOutputFormat = errors.New("unsupported output format")
|
var ErrUnsupportedOutputFormat = errors.New("unsupported output format")
|
||||||
|
|
||||||
// ErrUnsupportedInputFormat is returned, before the input is decoded, when
|
// ErrUnsupportedInputFormat is returned, before the input is decoded, when
|
||||||
// libvips would not load it as one of the source formats.
|
// libvips reads the input's first bytes as another format than the source
|
||||||
|
// formats, or as none: for example an SVG whose first bytes pass the
|
||||||
|
// first-bytes check for AVIF.
|
||||||
var ErrUnsupportedInputFormat = errors.New("unsupported input format")
|
var ErrUnsupportedInputFormat = errors.New("unsupported input format")
|
||||||
|
|
||||||
// ErrTooManyImages is returned when MaxConcurrentProcessing images are being
|
// ErrTooManyImages is returned when MaxConcurrentProcessing images are being
|
||||||
@@ -223,9 +225,10 @@ func (p *ImageProcessor) Process(
|
|||||||
return nil, ErrInputDataTooLarge
|
return nil, ErrInputDataTooLarge
|
||||||
}
|
}
|
||||||
|
|
||||||
// govips picks the libvips loader with DetermineImageType. Input it
|
// govips picks the libvips loader from the input's first bytes with
|
||||||
// would not load as a source format, such as SVG, which librsvg would
|
// DetermineImageType. Input whose first bytes it reads as no source
|
||||||
// render, is refused before libvips reads it.
|
// format, such as SVG, which librsvg would render, is refused before
|
||||||
|
// libvips reads it.
|
||||||
inputFormat := p.detectFormat(vips.DetermineImageType(data))
|
inputFormat := p.detectFormat(vips.DetermineImageType(data))
|
||||||
|
|
||||||
sourceFormat, err := p.formatFromString(inputFormat)
|
sourceFormat, err := p.formatFromString(inputFormat)
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import (
|
|||||||
"github.com/davidbyttow/govips/v2/vips"
|
"github.com/davidbyttow/govips/v2/vips"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestImageProcessor_OrigOfUnnamedFormatRefused verifies that orig of an
|
// TestImageProcessor_OrigOfUnnamedFormatRefused verifies that orig of a TIFF
|
||||||
// input in a format the processor decodes but cannot name, here TIFF, is
|
// input, which is not a source format, is refused with
|
||||||
// an error, and not the image saved as JPEG.
|
// ErrUnsupportedInputFormat before it is decoded, and not saved as JPEG.
|
||||||
func TestImageProcessor_OrigOfUnnamedFormatRefused(t *testing.T) {
|
func TestImageProcessor_OrigOfUnnamedFormatRefused(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user