ใช้ FallbackResource แม้ว่าจะมีไดเรกทอรีอยู่ก็ตาม


11

ฉันได้ตั้งค่าโฮสต์เสมือนของฉันบน Apache 2.4.7 ด้วยการกำหนดค่าพื้นฐานมาก:

<VirtualHost *:80>
  ServerName foo.example.com
  DocumentRoot /var/www/html

  DirectoryIndex index.php
  FallbackResource /index.php
</VirtualHost>

ภายใต้รูทเอกสารฉันมีโครงสร้างต่อไปนี้:

/index.php
/help/readme.txt

ฉันได้รับผลลัพธ์ต่อไปนี้เมื่อฉันขอ:

/bla     -> 200 OK
/help/   -> 404 Not Found
/help/a  -> 200 OK

ดูเหมือนว่าการมีอยู่จริงของ/help/ไดเรกทอรีทำให้ Apache กลับมา404เพราะไม่มีindex.phpในนั้น แต่ฉันคาดว่าการร้องขอทั้งหมดจะเรียก/index.phpและทำให้การ200 OKตอบสนอง

ฉันจำไม่ได้ว่านี่เป็นปัญหาเมื่อใช้mod_rewriteแต่ฉันชอบใช้FallbackResourceถ้าเป็นไปได้ มีวิธีแก้ไขปัญหานี้หรือไม่?

ปรับปรุง

มันทำงานได้ถ้าผมเอาDirectoryIndexคำสั่ง แต่ทุกข์ว่าจากประเด็นที่ห้าวินาที

อัปเดต 3

ฉันใช้สภาพแวดล้อมการทดสอบต่อไปนี้ โครงสร้างไดเรกทอรีเป็นดังนี้:

./htdocs
   index.html
   test/
      bla.txt
./conf
   httpd.conf
./logs

เนื้อหาของhttpd.confคือ:

ServerName apache-bug.local
Listen 8085

DirectoryIndex disabled
DirectorySlash Off

<VirtualHost *:8085>
DocumentRoot /home/user/apache-bug/htdocs

FallbackResource /index.html
</VirtualHost>

ฉันconfig.niceมี:

"./configure" \
"--enable-debugger-mode" \
"--with-apr=/usr/local/apr/bin/apr-1-config" \
"--enable-dir=static" \
"--with-mpm=prefork" \
"--enable-unixd=static" \
"--enable-authn-core=static" \
"--enable-authz-core=static" \
"$@"

ในการรันเซิร์ฟเวอร์:

httpd -X -d /home/user/work/apache-bug/

และสิ่งที่อยู่ในร่างกายตอบสนองสำหรับ/bla?
zerkms

ฉันไม่แน่ใจว่าฉันเข้าใจปัญหาแล้ว: -S
zerkms

เพื่อให้แน่ใจว่าคุณใช้ Apache เวอร์ชันใดอยู่
Jenny D

@JennyD ฉันทำงานที่ 2.4.7
แจ็ค

คำตอบ:


8

ฉันตอบนี้ตัวเองเป็นอย่างดีเพราะผมค่อนข้างมั่นใจว่าปัญหาที่เกี่ยวข้องกับวิธีการmod_dir.cทำงานภายในและฉันคิดว่ามันเป็นข้อผิดพลาด

หากไม่สามารถแมปทรัพยากรกับระบบไฟล์ในเครื่องได้ฟังก์ชันfixup_dflt()จะทำงานโดยใช้FallbackResourceเพื่อกำหนดว่าควรโหลดเอกสารใดแทน

อย่างไรก็ตามเมื่อทรัพยากรสามารถแมปกับระบบไฟล์ในท้องถิ่นและเป็นไดเรกทอรีก็จะพยายามแก้ไขเอกสารโดยการเรียกใช้fixup_dir(); ฟังก์ชันนี้วนซ้ำตามรายการDirectoryIndexค่าจนกว่าจะพบเอกสารที่เหมาะสมแรก

ในกรณีของฉันการกำหนดค่ามีรายการDirectoryIndexค่าว่างดังนั้นfixup_dir()จะล้มเหลวและส่งคืน 404

แพทช์ต่อไปนี้ใช้งานได้สำหรับฉัน ( PR ):

static int dir_fixups(request_rec *r)
{
    if (r->finfo.filetype == APR_DIR) {
-        return fixup_dir(r);
+        if (fixup_dir(r) != OK) {
+           /* use fallback */
+           return fixup_dflt(r);
+        }
+
+        return OK;
    }
    else if ((r->finfo.filetype == APR_NOFILE) && (r->handler == NULL)) {
        /* No handler and nothing in the filesystem - use fallback */
        return fixup_dflt(r);
    }
    return DECLINED;
}

โดยทั่วไปจะพยายามfixup_dflt()หลังจากfixup_dir()ล้มเหลว

อัปเดต 2015-04-21

แก้ไขได้ถูกส่งไปยังโครงการที่กำหนดไว้สำหรับ 2.5; มันอาจจะเป็นพอร์ตถึง 2.4 เช่นกัน

อัปเดต 2015-05-18

การแก้ไขถูกเปลี่ยนกลับเนื่องจาก:

[... ] มัน [อย่างน้อย] สาเหตุที่FallBackResourceจะเตะเข้าก่อนmod_autoindexอาจเตะเข้า

ฉันยังคงพยายามหาวิธีหลีกเลี่ยงสถานการณ์แบบนี้


ฉันจะบอกว่าข้อผิดพลาดในการfixup_dir()ละเลย FallbackResource
Ricky Beam

@RickyBeam ใช่ แต่ในทางเทคนิคfixup_dir()ไม่ควรรู้เกี่ยวกับfixup_dflt()ดังนั้น IMHO มันจะดีกว่าที่จะแก้ไขได้ "สูงขึ้น" :)
แจ็ค

7

การกำหนดค่าของคุณควรถูกต้อง

ปัญหาแปลกพอดูเหมือนว่าจะmod_deflate

หลังจากทำซ้ำการกำหนดค่าของคุณสำเร็จที่นี่ ( ไม่ได้รับ 404) ฉันก็มีความล่าช้า 5 วินาที อย่างไรก็ตามฉันสังเกตเห็นว่าเมื่อ UA ละเว้นgzipจาก Accept-Headers ของหน้านั้นจะแสดง / รับทันที wgetคุณสามารถทดสอบนี้สำหรับตัวคุณเองด้วย

ที่น่าสนใจคือการดีบั๊กเพิ่มเติมด้วยการstraceแสดงว่า apache ส่งเนื้อหาของคุณFallbackResourceไปยังซ็อกเก็ตของลูกค้าโดยไม่มีความแตกต่างอย่างชัดเจนทั้งสองกรณี และนี่ก็เป็นที่เห็นได้ชัดบนลวดซึ่งเป็นแพคเกจการตอบกลับจะถูกส่งจากเซิร์ฟเวอร์ไปยังลูกค้าหลังจากที่ขอ HTTP โดยไม่ชักช้าโดดเด่นใด ๆ1

ดูเหมือนว่าเมื่อใช้ mod_deflate ในกรณีนี้ UA จะไม่รู้ว่าข้อมูลที่ส่งจากเซิร์ฟเวอร์สิ้นสุดลงเมื่อใดและจะไม่แสดงผลใด ๆ ก่อนการเชื่อมต่อ TCP จะหมดเวลา2และถูกบังคับให้ปิดโดยเซิร์ฟเวอร์ นี่เป็นไปตาม HTTP / 1.0 ซึ่งการเชื่อมต่อที่ปิดหมายถึงการสิ้นสุดของเนื้อหา

สำหรับHTTP / 1.1 , เซิร์ฟเวอร์ที่มีอื่น ๆวิธีการที่มีการส่งสัญญาณการสิ้นสุดของเนื้อหา - แต่ไม่มีใครที่ดูเหมือนจะเกิดขึ้นที่นี่

ข้อผิดพลาดที่แฝงตัวอยู่ใน mod_dir หรือ mod_deflate อยู่นอกเหนือเวลาที่ฉันมีอยู่ตอนนี้ ฉันได้มันไปใช้งานได้อย่างไร้ที่ติโดยปิดการใช้งานการบีบอัด gzip; เพื่อแก้ไขปัญหาจนกว่าปัญหาจะได้รับการแก้ไขให้ดีคุณสามารถปิดการใช้งาน gzip ได้

1 ) สิ่งนี้บอกเราว่าปัญหาไม่ได้เกิดจากบัฟเฟอร์ที่ไม่ได้ล้างบนเซิร์ฟเวอร์
2 ) โดยค่าเริ่มต้นการหมดเวลาคือ 5 วินาทีโดยมี apache - นั่นคือที่มาของ 5 วินาที


ขอบคุณ ปัญหาการหน่วงเวลา 5 วินาทีเป็นปัญหารองของฉันฉันได้อัปเดตคำถามด้วยวิธีการทำให้เกิดปัญหาซ้ำในเครื่อง
แจ็ค
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.