Score:0

Nginx ส่งคืน 415 เมื่อใช้ image_filter กับ webp

ธง za

ฉันมีไฟล์ jpg/png ที่ได้รับการปรับขนาดในตำแหน่ง (ด้วย image_filter โมดูล) และใช้งานได้ดีแต่ฉันยังมี เว็บ เวอร์ชั่นของรูปภาพบางส่วนและฉันต้องการให้บริการ เว็บ หนึ่งถ้ามีอยู่ ถ้าไม่เดิม jpg/png ควรให้บริการรูปภาพ

ฉันใช้การกำหนดค่าต่อไปนี้:

แผนที่ $http_accept $webp_suffix {
    ค่าเริ่มต้น        "";
    "~image/webp" "webp";
}

ตำแหน่ง ~ "/@s/(.*)(png|jpe?g)" {
    นามแฝง $BASE_PATH/$1;
    try_files $webp_suffix $2 $ยูริ;

    image_filter ปรับขนาด 1200 -;
    image_filter_jpeg_quality 80;
    image_filter_buffer 10M;
}

แต่ nginx ส่งคืน a 415 ประเภทสื่อที่ไม่รองรับ เกิดข้อผิดพลาดเมื่อพบเวอร์ชันของเว็บพี ถ้า เว็บ ไฟล์หายไป ให้บริการไฟล์ jpg/png โดยไม่มีข้อผิดพลาดใดๆ รุ่น Nginx คือ 1.16.1.

Ivan Shatsky avatar
gr flag
สิ่งนี้ตอบคำถามของคุณหรือไม่ [NGINX: แมปและลอง\_ไฟล์ไม่ทำงาน](https://serverfault.com/questions/1036804/nginx-map-and-try-files-not-working)
Ivan Shatsky avatar
gr flag
นอกจากคุณจะใช้คำสั่ง `try_files` ไม่ถูกต้องแล้ว ยังมีข้อแม้อีกประการหนึ่งที่ใช้ตัวแปรที่ได้รับ `map` ภายในตำแหน่งนิพจน์ทั่วไปที่มีกลุ่มการจับภาพที่เป็นตัวเลข คำอธิบายและตัวอย่างการทำงานมีให้ที่นี่: [NGINX: map และ try_files ไม่ทำงาน](https://serverfault.com/questions/1036804/nginx-map-and-try-files-not-working)
Erfun avatar
za flag
@IvanShatsky ฉันเปลี่ยนตัวแปรตัวเลขเป็นตัวแปรที่มีชื่อ แต่ฉันไม่เห็นความแตกต่าง ยังคงได้รับ '415 ประเภทสื่อที่ไม่รองรับ'
us flag
อาจเป็นไปได้ว่า `image_filter` อ่านชื่อไฟล์จากตัวแปร `$uri` และคิดว่าภาพนั้นเป็น JPEG
Erfun avatar
za flag
@TeroKilkanen ตามที่อธิบายไว้ในเอกสาร WEBP ควรได้รับการสนับสนุนใน image_filter แต่ด้วยเหตุผลบางอย่าง มันใช้งานไม่ได้
us flag
ฉันเดาว่ามันรองรับรูปแบบ WEBP อย่างถูกต้องเมื่อ URL คำขอจริงมีนามสกุล `.webp` ในการกำหนดค่าของคุณ URL คำขอคือ `.png` หรือ `.jpg` แล้วแต่ว่าจะเป็นนามสกุลเดิม ดังนั้น `image_filter` จึงพยายามเข้าถึงรูปภาพโดยใช้ตัวถอดรหัสที่ไม่ถูกต้อง อาจเป็นไปไม่ได้ที่จะรวมโมดูลการแมปและ `image_filter`
drboczek avatar
dk flag
คุณแก้ไขปัญหาด้วย nginx และ webp หรือไม่ ผมมีปัญหาเดียวกัน :) centos 7 เช่นกัน ลบ nginx 1.20.1 ฉันลองใช้ nginx repo ด้วย nginx 1.21 แต่ไม่มีผล
Erfun avatar
za flag
@drboczek น่าเสียดายที่ไม่ ฉันทำไม่ได้ แต่ฉันใช้คุณสมบัติการแปลง WEBP ของผู้ให้บริการ CDN ซึ่งมีอยู่ใน Cloudflare แทน
Score:0
ธง us

การกำหนดค่าที่มีประสิทธิภาพมากขึ้นสำหรับสิ่งนี้คือ:

แผนที่ $http_accept $webpuri {
    ~image/webp $uri.webp;
    ค่าเริ่มต้น        "";
}

ตำแหน่ง ~ \.png|jpe?g$ {
    try_files $เว็บปุริ $uri;
    ...
}

ของคุณ ราก คำสั่งใช้ที่นี่เพื่อรับเส้นทางแบบเต็มไปยังไฟล์ในระบบไฟล์ของคุณ

Erfun avatar
za flag
ฉันไม่เข้าใจว่าความแตกต่างคืออะไร ฉันใช้ 'นามแฝง' แทน 'รูท' เพื่อระบุเส้นทางไฟล์ในระบบไฟล์
us flag
โค้ดด้านบนไม่ได้ใช้นิพจน์ทั่วไปเพื่อแยก URI ออกเป็นส่วนฐานและนามสกุลของชื่อไฟล์ ซึ่งค่อนข้างแฮ็ค แต่เราใช้เส้นทางของไฟล์ทั้งหมดและเพิ่ม `.webp` ต่อจากเส้นทางทั้งหมด
Erfun avatar
za flag
ฉันคิดว่า `image_filter` ทำให้เกิดปัญหา ไม่ใช่นิพจน์ทั่วไป ถ้าฉันลบ image_filter ออก โค้ดของฉันเองก็ใช้ได้ เห็นได้ชัดว่าไม่มีอะไรผิดปกติในการระบุที่อยู่ไฟล์
Score:0
ธง gr

ไม่ใช่คำตอบ แต่ยาวเกินไปที่จะแสดงความคิดเห็น

@เทโร คิลคาเนน ตั้งสมมติฐาน:

อาจเป็นอย่างนั้น image_filter อ่านชื่อไฟล์จาก $ยูริ ตัวแปรและคิดว่าภาพนั้นเป็น JPEG

ลองตรวจสอบดูว่าจริงไหม โชคดีที่ nginx เป็นซอฟต์แวร์โอเพ่นซอร์สและเป็นซอร์สโค้ดของ ngx_http_image_filter_module สามารถใช้ได้ ที่นี่.

หลัก ngx_http_image_body_filter การทำงาน เริ่ม ที่สาย 291.ลองดูที่จุดเริ่มต้น:

    ...
    สวิตช์ (ctx->เฟส) {

    กรณี NGX_HTTP_IMAGE_START:

        ctx->type = ngx_http_image_test(r, ใน);

        conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);

        ถ้า (ctx->พิมพ์ == NGX_HTTP_IMAGE_NONE) {

            ถ้า (conf->filter == NGX_HTTP_IMAGE_SIZE) {
                out.buf = ngx_http_image_json(r, NULL);

                ถ้า (out.buf) {
                    out.next = NULL;
                    ctx->เฟส = NGX_HTTP_IMAGE_DONE;

                    ส่งคืน ngx_http_image_send(r, ctx, &ออก);
                }
            }

            ส่งคืน ngx_http_filter_finalize_request(r,
                                              &ngx_http_image_filter_module,
                                              NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
        }
        ...

ที่เราเห็นก็คือ ngx_http_image_test หน้าที่รับผิดชอบในการตัดสินใจเกี่ยวกับความถูกต้องของภาพ ลองดูที่ฟังก์ชันนั้น (เริ่ม ที่บรรทัดที่ 423):

ngx_uint_t แบบคงที่
ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *ใน)
{
    u_char *p;

    p = in->buf->pos;

    ถ้า (in->buf->last - p <16) {
        กลับ NGX_HTTP_IMAGE_NONE;
    }

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->การเชื่อมต่อ->บันทึก, 0,
                   "ฟิลเตอร์รูปภาพ: \"%c%c\"", p[0], p[1]);

    ถ้า (p[0] == 0xff && p[1] == 0xd8) {

        /* JPEG */

        ส่งคืน NGX_HTTP_IMAGE_JPEG;

    } อื่นถ้า (p[0] == 'G' && p[1] == 'I' && p[2] == 'F' && p[3] == '8'
               && p[5] == 'ก')
    {
        ถ้า (p[4] == '9' || p[4] == '7') {
            /* กิฟ */
            ส่งคืน NGX_HTTP_IMAGE_GIF;
        }

    } อื่นถ้า (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 */

        กลับ NGX_HTTP_IMAGE_PNG;

    } อื่นถ้า (p[0] == 'R' && p[1] == 'I' && p[2] == 'F' && p[3] == 'F'
               && p[8] == 'W' && p[9] == 'E' && p[10] == 'B' && p[11] == 'P')
    {
        /* เว็บพี */

        กลับ NGX_HTTP_IMAGE_WEBP;
    }

    กลับ NGX_HTTP_IMAGE_NONE;
}

ฉันคิดว่ามันค่อนข้างชัดเจนว่าฟังก์ชันด้านบนวิเคราะห์ 16 ไบต์แรกของบัฟเฟอร์ที่พยายามค้นหาหนึ่งในสี่ลายเซ็นที่รู้จัก ดังนั้นปัญหาจึงไม่เกี่ยวข้องกับ $ยูริ ค่าตัวแปร

เกิดจากอะไรได้บ้าง? ดี, ngx_http_image_filter_module เอกสาร พูดว่า ต่อไปนี้:

โมดูลนี้ใช้ libgd ห้องสมุด. ขอแนะนำให้ใช้ไลบรารีเวอร์ชันล่าสุดที่มีอยู่

การสนับสนุนรูปแบบ WebP ปรากฏในเวอร์ชัน 1.11.6 ในการแปลงรูปภาพในรูปแบบนี้ libgd ไลบรารีจะต้องรวบรวมด้วยการสนับสนุน WebP

บางทีปัญหาอาจอยู่ในบิลด์ nginx ของคุณ ตรวจสอบ WebP และ image_filter ความเข้ากันได้โดยไม่มีการแปลง URI เพิ่มเติม อะไรทำนองนั้น

ตำแหน่ง ~ \.webp$ {
    image_filter ปรับขนาด 1200 -;
    image_filter_jpeg_quality 80;
    image_filter_buffer 10M;
}

จากนั้นขอไฟล์ WebP ที่มีอยู่อย่างชัดเจน หากคุณยังคงได้รับ 415 ประเภทสื่อที่ไม่รองรับ ข้อผิดพลาด ปัญหาน่าจะอยู่ในบิลด์ nginx ของคุณมากที่สุด

Erfun avatar
za flag
ฉันได้ทดสอบ `image_filter` ด้วย `webp` และพบปัญหา `415 Unsupported Media Type` เหมือนเดิม ดังนั้นจึงน่าจะมีปัญหากับ `libgd` ฉันได้ติดตั้ง `nginx` จากที่เก็บ yum อย่างเป็นทางการแล้ว ฉันควรสร้างด้วยตนเองด้วยการกำหนดค่าที่กำหนดเองหรือไม่
Ivan Shatsky avatar
gr flag
คุณใช้ linux distro อะไร
Erfun avatar
za flag
มันเป็นเซิร์ฟเวอร์ Centos 7
Ivan Shatsky avatar
gr flag
และอีกหนึ่งคำถาม คุณใช้ repo อะไร มันเป็นพื้นที่เก็บข้อมูลอย่างเป็นทางการของ nginx หรือ EPEL หรืออย่างอื่น?
Erfun avatar
za flag
มันคือการซื้อคืน EPEL

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา