Not an answer, but too long to be a comment.
@TeroKilkanen made an assumption:
It might be that image_filter
reads the filename from $uri
variable, and it thinks the image is JPEG.
Lets check out if it is true. Fortunately, nginx is an open source software and the source code of ngx_http_image_filter_module
is available here.
The main ngx_http_image_body_filter
function started at line 291. Let's look at the beginning:
...
switch (ctx->phase) {
case NGX_HTTP_IMAGE_START:
ctx->type = ngx_http_image_test(r, in);
conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
if (ctx->type == NGX_HTTP_IMAGE_NONE) {
if (conf->filter == NGX_HTTP_IMAGE_SIZE) {
out.buf = ngx_http_image_json(r, NULL);
if (out.buf) {
out.next = NULL;
ctx->phase = NGX_HTTP_IMAGE_DONE;
return ngx_http_image_send(r, ctx, &out);
}
}
return ngx_http_filter_finalize_request(r,
&ngx_http_image_filter_module,
NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
}
...
We see it is the ngx_http_image_test
function that is responsible for the decision about image validity. Let's look at that function (started at line 423):
static ngx_uint_t
ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in)
{
u_char *p;
p = in->buf->pos;
if (in->buf->last - p < 16) {
return NGX_HTTP_IMAGE_NONE;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"image filter: \"%c%c\"", p[0], p[1]);
if (p[0] == 0xff && p[1] == 0xd8) {
/* JPEG */
return NGX_HTTP_IMAGE_JPEG;
} else if (p[0] == 'G' && p[1] == 'I' && p[2] == 'F' && p[3] == '8'
&& p[5] == 'a')
{
if (p[4] == '9' || p[4] == '7') {
/* GIF */
return NGX_HTTP_IMAGE_GIF;
}
} else if (p[0] == 0x89 && p[1] == 'P' && p[2] == 'N' && p[3] == 'G'
&& p[4] == 0x0d && p[5] == 0x0a && p[6] == 0x1a && p[7] == 0x0a)
{
/* PNG */
return NGX_HTTP_IMAGE_PNG;
} else if (p[0] == 'R' && p[1] == 'I' && p[2] == 'F' && p[3] == 'F'
&& p[8] == 'W' && p[9] == 'E' && p[10] == 'B' && p[11] == 'P')
{
/* WebP */
return NGX_HTTP_IMAGE_WEBP;
}
return NGX_HTTP_IMAGE_NONE;
}
I think it is pretty clear that the above function analyze first 16 bytes of the buffer trying to find one of the four known signatures. So the problem isn't related to the $uri
variable value.
What can be the cause? Well, ngx_http_image_filter_module
documentation says the following:
This module utilizes the libgd library. It is recommended to use the latest available version of the library.
The WebP format support appeared in version 1.11.6. To transform images in this format, the libgd
library must be compiled with the WebP support.
Maybe the problem is in your nginx build. Check the WebP and image_filter
compatibility without any additional URI transformations, something like
location ~ \.webp$ {
image_filter resize 1200 -;
image_filter_jpeg_quality 80;
image_filter_buffer 10M;
}
and then requesting the existing WebP file explicitly. If you'll still get a 415 Unsupported Media Type
error, the problem is most likely in your nginx build.