Apache的目录指令的路由顺序
在CakePHP的环境中,有一个案例需要在webroot目录之外放置静态内容,因为遇到了一点问题所以做了一些笔记。
这个内容讨论的是当Directory指令的内容与多个请求匹配时,确定哪个会被匹配。
マージの順番は以下のようになっています:
<Directory> (正規表現無し) と .htaccess を同時に (.htaccess が許可されていれば、それが <Directory> を上書きします)
<DirectoryMatch> (と <Directory ~>
<Files> と <FilesMatch> を同時に
<Location> と <LocationMatch> を同時に
<Directory> 以外は、それぞれのグループは設定ファイルに現れた順番に処理されます。 <Directory> (上のグループ 1) はディレクトリが短いものから長いものへと処理されます。ですから、 例えば <Directory /var/web/dir1> は <Directory /var/web/dir/subdir> の前に処理されます。複数の <Directory> セクションが 同じディレクトリに 適用される場合は、設定ファイル中の順番に従って処理されます。 Include によって挿入された設定は 挿入しているファイルの Include ディレクティブの位置にあったかのように扱われます。
<VirtualHost> セクション中のセクションは バーチャルホストの定義の外側の対応するセクションの 後に適用されます。これによりバーチャルホストが メインのサーバ設定を上書きできるようなります。
简而言之,如果存在多个匹配指令的情况,处理的顺序是按照路径的长度从短到长进行的,所以最优先处理的是最长路径的指令。
根据验证结果,路径长度最长的优先(覆盖)被选择,但是之前通过的指令处理也有效=这意味着只有在存在相同指令时才会被覆盖,较长的路径有优先权。
【Apache指令列表】
http://httpd.apache.org/docs/2.0/zh-cn/mod/core.html#options
所以,我决定亲自试一试。
测试用例
这次,以以下请求为例,希望返回位于[/test/app/View/test1]下的静态内容。
http://localhost/test1/sample.html
首先,是一件失败的作品。
由于是蛋糕,所以我在下面的httpd.conf中按照标准方式编写了用于路由重写的Rewrite,然后尝试通过Alias在适当的路径上添加,结果重写起作用,返回404错误。
嗯,难道不是应该应用较长的路径吗?
<Directory /test/app/>
RewriteEngine On
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</Directory>
<Directory /test/app/webroot/>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
RewriteCond %{THE_REQUEST} "^(.+?) (.*?)/app/webroot/(.*?) (.+?)$"
RewriteRule ^(.*?)$ %2/%3 [R=302,L]
</Directory>
Alias /test1 /test/app/View/test1
<Directory /test/app/View/test1>
AllowOverride none
Options -Indexes FollowSymLinks
</Directory>
这就是正确答案。
如果不覆盖RewriteEngine,则上面的处理将无效,似乎是因为执行了适用于cake的路由,并返回了404错误。
<Directory /test/app/>
RewriteEngine On
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</Directory>
<Directory /test/app/webroot/>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
RewriteCond %{THE_REQUEST} "^(.+?) (.*?)/app/webroot/(.*?) (.+?)$"
RewriteRule ^(.*?)$ %2/%3 [R=302,L]
</Directory>
Alias /test1 /test/app/View/test1
<Directory /test/app/View/test1>
RewriteEngine On
RewriteRule ^(.*)$ $1
AllowOverride none
Options -Indexes FollowSymLinks
</Directory>