Apacheは、Fフラグを無視して、403ではなく404で応答します
私はこの単純なプロジェクト階層を持っています:
ルートフォルダに.htaccess
あるファイルの内容/www
は次のとおりです。
RewriteEngine On
RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} "\.php$"
RewriteRule .* - [F]
のルールは、.phpファイル以外の.phpファイルを要求するときに403.htaccess
を返す必要があります。.phpテンプレートの内容は関係ありません。index.php
私が間違っていない場合、リクエストの最後の部分が既存の.phpファイルの名前であり、書き換えエンジンがオンになっていると、.php部分を指定するかどうかに関係なく、Apacheがそれを提供します。私の場合、の最後の2行をコメントアウトすると、.htaccess
次のURLのいずれかが表示されます。
localhost/pages/page
localhost/pages/page/
の内容を返す /pages/page.php
私の問題は、上記のことを考えると、.htaccess
このURLを書くと:
localhost/pages/page.php
期待通り403が出ました。しかし、私が次のいずれかを書いた場合:
localhost/pages/page
localhost/pages/page/
期待される403の代わりに404(見つかりません)を取得します。なぜ404を取得するのですか?
回答
興味深い... Apache 2.4でこの動作を再現できますが、説明できません。に置き換えるF
とR=403
目的の結果が得られるため、私の意見ではバグのように見えます(違いはないはずです)。以下を参照してください。
明確/pages/page
にするため/pages/page.php
に、最初に解決するためには、有効にMultiViews
されているかどうかに依存します(コメントですでに述べられているように)。または、mod_rewriteを使用してこれを行うことができますが、ここではその証拠はありません。マルチビューはApacheではデフォルトで無効になっていますが、一部の共有ホストでは何らかの理由で有効になっています(拡張子のないURLが「正常に機能」するようになります)。ただし、MultiViewsは、mod_rewriteとの予期しない競合の一般的な原因です。また、拡張子のないURLが「(予期せずに)機能する」という事実は、正規化に関して追加の問題を引き起こす可能性があります。
「バグ」があると思う理由は、F
フラグをに変更するだけでR=403
、「予期される」403応答が返されるためです。
RewriteCond %{REQUEST_FILENAME} "\.php$" RewriteRule .* - [R=403]
違いはありませんF
とR=403
。AFAIKは、F
単なるショートカットです。
試しました
Options -MultiViews
が、同じ結果が得られます
ただし、MultiViewsが無効になっている場合は、404が期待される応答です。
あなたが要求した場合のMultiViewsは、その後無効にして/pages/page
、REQUEST_FILENAME
フォームのものであろう/abs/path/to/pages/page
(なし.php
拡張子)。条件が一致しないため、リクエストは404にフォールスルーします。
MultiViewを無効にして作業することをお勧めします。これは、「通常」のためではない/pages/page
と/pages/page/
し、「魔法」と決意/pages/page.php
。のは、「ノーマル」である/pages/page
と/pages/page/
、このシナリオでは404になります。要求されたURLがファイルシステムにマップされるmod_rewriteで多くのことをしている場合、競合が発生する可能性があります。
MultiViewsは.php
ファイルだけに適用されるわけではないことに注意してください。MultiViewsを有効にすると、拡張機能のないすべてのものが得られます。画像、スクリプト、HTML、スタイルシートなど。共通のベース名とmimeタイプを持つ複数のファイルがある場合、どれが提供されますか?例えば。foo.php
またはfoo.html
?
もちろん、mod_rewriteディレクティブを作成してこの動作を有効にすることはできますが、これは自動ではありません。
更新:より簡潔な例...
/page.php
(ドキュメントルート内の)ファイルがあり、MultiViewsが有効になっている場合。
(例Options +MultiViews
)
リクエスト/page
(または/page/
)すると/page.php
、内部サブリクエストよりも経由でMultiViews / mod_negotiationが提供されます。
ここで、mod_rewriteを使用してすべてのアクセスをブロックし、403Forbiddenを提供しましょう。
RewriteRule ^ - [F]
これはブロックする必要があり、すべての要求、しかし403で要求を/page
か/page/
-されたURLに成功代わりに404が見つかりませんでした応答の結果-のMultiViewsによって書き換えられました!
ただし、R
代わりにフラグを使用するように上記のルールを変更してください。
RewriteRule ^ - [R=403]
これで、上記の2つのURLを含め、すべてが403を返します。しかし、F
とR=403
同じ動作になるはずです。