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