Điểm:0

Nginx trả về 415 khi sử dụng image_filter với webp

lá cờ za

Tôi có một số tệp jpg/png được thay đổi kích thước ở một vị trí (với image_filter module) và nó hoạt động tốt.Nhưng, tôi cũng có một trang web phiên bản của một số hình ảnh và tôi muốn phục vụ trang web một nếu nó tồn tại. Nếu không, bản gốc jpg/png hình ảnh nên được phục vụ.

Tôi đang sử dụng cấu hình sau:

bản đồ $http_accept $webp_suffix {
    mặc định        "";
    "~hình ảnh/webp" "webp";
}

vị trí ~ "/@s/(.*)(png|jpe?g)" {
    bí danh $BASE_PATH/$1;
    try_files $webp_suffix $2 $uri;

    image_filter thay đổi kích thước 1200 -;
    image_filter_jpeg_quality 80;
    image_filter_buffer 10M;
}

Nhưng nginx trả về một 415 Loại phương tiện không được hỗ trợ lỗi khi tìm thấy phiên bản webp. Nếu trang web tệp bị thiếu, nó phục vụ tệp jpg/png mà không có bất kỳ lỗi nào. Phiên bản Nginx là 1.16.1.

Ivan Shatsky avatar
lá cờ gr
Điều này có trả lời câu hỏi của bạn không? [NGINX: map and try\_files not working](https://serverfault.com/questions/1036804/nginx-map-and-try-files-not-working)
Ivan Shatsky avatar
lá cờ gr
Bên cạnh việc bạn đang sử dụng lệnh `try_files` không chính xác, còn có một lưu ý khác khi sử dụng các biến dẫn xuất `map` bên trong vị trí biểu thức chính quy với các nhóm chụp được đánh số. Một lời giải thích và một ví dụ hoạt động được đưa ra ở đây: [NGINX: map and try_files not working](https://serverfault.com/questions/1036804/nginx-map-and-try-files-not-working).
Erfun avatar
lá cờ za
@IvanShatsky Tôi đã thay đổi các biến số thành các biến được đặt tên nhưng tôi không thấy sự khác biệt. Vẫn nhận được `415 Loại phương tiện không được hỗ trợ`.
lá cờ us
Có thể `image_filter` đọc tên tệp từ biến `$uri` và cho rằng hình ảnh là JPEG.
Erfun avatar
lá cờ za
@TeroKilkanen Như được mô tả trong tài liệu, WEBP phải được hỗ trợ trong image_filter nhưng vì lý do nào đó, nó không hoạt động.
lá cờ us
Tôi đoán nó hỗ trợ đúng định dạng WEBP khi URL yêu cầu thực tế chứa phần mở rộng `.webp`. Trong cấu hình của bạn, URL yêu cầu là `.png` hoặc `.jpg`, tùy theo phần mở rộng gốc nào. Do đó, `image_filter` cố truy cập hình ảnh bằng cách sử dụng bộ giải mã sai. Có thể không kết hợp được các mô-đun ánh xạ và `image_filter`.
drboczek avatar
lá cờ dk
bạn đã giải quyết vấn đề của mình với nginx và webp chưa? Tôi có cùng một vấn đề :) centos 7 cũng vậy, epel nginx 1.20 tôi đang thử repo nginx với nginx 1.21 nhưng không có tác dụng.
Erfun avatar
lá cờ za
@drboczek Rất tiếc là không, tôi không thể. Thay vào đó, tôi đã sử dụng tính năng chuyển đổi WEBP của nhà cung cấp CDN của chúng tôi, tính năng này cũng có sẵn trên Cloudflare.
Điểm:0
lá cờ us

Một cấu hình hợp lý hơn cho việc này là:

bản đồ $http_accept $webpuri {
    ~hình ảnh/webp $uri.webp;
    mặc định        "";
}

vị trí ~ \.png|jpe?g$ {
    try_files $webpuri $uri;
    ...
}

Của bạn nguồn gốc chỉ thị được sử dụng ở đây để có được đường dẫn đầy đủ đến các tệp trên hệ thống tệp của bạn.

Erfun avatar
lá cờ za
Tôi không nhận được sự khác biệt ở đâu. Tôi đã sử dụng `alias` thay vì `root` để giải quyết đường dẫn tệp trên hệ thống tệp.
lá cờ us
Đoạn mã trên không sử dụng các biểu thức chính quy để chia URI thành phần cơ sở tên tệp và phần mở rộng, điều này khá nguy hiểm. Thay vào đó, chúng tôi lấy đường dẫn tệp đầy đủ và thêm `.webp` vào sau toàn bộ đường dẫn.
Erfun avatar
lá cờ za
Tôi nghĩ rằng `image_filter` đã gây ra sự cố chứ không phải cụm từ thông dụng. Nếu tôi xóa image_filter, mã của riêng tôi sẽ hoạt động. Vì vậy, rõ ràng là không có gì sai khi ghi địa chỉ vào tệp.
Điểm:0
lá cờ gr

Không phải là một câu trả lời, nhưng quá dài để là một bình luận.

@TeroKilkanen đưa ra một giả định:

Nó có thể là image_filter đọc tên tệp từ $uri và nó cho rằng hình ảnh là JPEG.

Hãy kiểm tra nếu nó là sự thật. May mắn thay, nginx là một phần mềm mã nguồn mở và mã nguồn của ngx_http_image_filter_module có sẵn đây.

chính ngx_http_image_body_filter chức năng đã bắt đầu ở dòng 291.Hãy nhìn vào phần đầu:

    ...
    công tắc (ctx->pha) {

    trường hợp 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);

                nếu (out.buf) {
                    out.next = NULL;
                    ctx->giai đoạn = NGX_HTTP_IMAGE_DONE;

                    trả về ngx_http_image_send(r, ctx, &out);
                }
            }

            trả về ngx_http_filter_Finalize_request(r,
                                              &ngx_http_image_filter_module,
                                              NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
        }
        ...

Chúng tôi thấy đó là ngx_http_image_test chức năng chịu trách nhiệm cho quyết định về tính hợp lệ của hình ảnh. Hãy xem xét chức năng đó (đã bắt đầu tại dòng 423):

ngx_uint_t tĩnh
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) {
        trả về NGX_HTTP_IMAGE_NONE;
    }

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->kết nối->log, 0,
                   "bộ lọc ảnh: \"%c%c\"", p[0], p[1]);

    nếu (p[0] == 0xff && p[1] == 0xd8) {

        /* JPEG */

        trả về NGX_HTTP_IMAGE_JPEG;

    } khác nếu (p[0] == 'G' && p[1] == 'I' && p[2] == 'F' && p[3] == '8'
               && p[5] == 'a')
    {
        if (p[4] == '9' || p[4] == '7') {
            /* GIF */
            trả lại NGX_HTTP_IMAGE_GIF;
        }

    } khác nếu (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 */

        trả lại NGX_HTTP_IMAGE_PNG;

    } khác nếu (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 */

        trả về NGX_HTTP_IMAGE_WEBP;
    }

    trả về NGX_HTTP_IMAGE_NONE;
}

Tôi nghĩ khá rõ ràng là hàm trên phân tích 16 byte đầu tiên của bộ đệm để cố gắng tìm một trong bốn chữ ký đã biết. Vì vậy, vấn đề không liên quan đến $uri giá trị biến.

Điều gì có thể là nguyên nhân? Tốt, ngx_http_image_filter_module tài liệu nói như sau:

Mô-đun này sử dụng các libgd thư viện. Bạn nên sử dụng phiên bản mới nhất hiện có của thư viện.

Hỗ trợ định dạng WebP đã xuất hiện trong phiên bản 1.11.6. Để chuyển đổi hình ảnh ở định dạng này, libgd thư viện phải được biên dịch với sự hỗ trợ của WebP.

Có thể vấn đề nằm ở bản dựng nginx của bạn. Kiểm tra WebP và image_filter khả năng tương thích mà không cần bất kỳ phép biến đổi URI bổ sung nào, chẳng hạn như

vị trí ~ \.webp$ {
    image_filter thay đổi kích thước 1200 -;
    image_filter_jpeg_quality 80;
    image_filter_buffer 10M;
}

và sau đó yêu cầu tệp WebP hiện có một cách rõ ràng. Nếu bạn vẫn sẽ nhận được một 415 Loại phương tiện không được hỗ trợ lỗi, sự cố rất có thể xảy ra trong bản dựng nginx của bạn.

Erfun avatar
lá cờ za
Tôi đã thử nghiệm `image_filter` với `webp` và vẫn tồn tại vấn đề tương tự `415 Loại phương tiện không được hỗ trợ`. Vì vậy, có thể có vấn đề với `libgd`. Tôi đã cài đặt `nginx` của mình từ kho yum chính thức. Tôi có nên tạo thủ công với bất kỳ cấu hình tùy chỉnh nào không?
Ivan Shatsky avatar
lá cờ gr
Bạn đang sử dụng bản phân phối linux nào?
Erfun avatar
lá cờ za
Đó là một máy chủ Centos 7.
Ivan Shatsky avatar
lá cờ gr
Và một câu hỏi nữa, bạn đang sử dụng repo nào? Đây có phải là kho lưu trữ chính thức của nginx hay EPEL hay cái gì khác không?
Erfun avatar
lá cờ za
Đó là repo EPEL.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.