Windowsのワイルドカードのちょうどよさ

URLパターンマッチングにphpのpreg_matchは高機能すぎ?

こんにちは、こたかです。

この頃はサーバーセキュリティー機能を開発しています。
URLフィルターを作っていますが、権限によって一部のURLだけ公開する制御を行います。

パターンにマッチしたURLを制御する

URLパターンマッチングで、マッチしたURLに対してアクセス制御するのですが、
この時、phpではpreg_match関数を使用します。

preg_match関数では、細かく制御できる分、ぱっと見たときにURLが読みづらい状態になります。
そこで、preg_matchよりもシンプルなマッチング処理である「ワイルドカード」によるマッチングを検討してみました。

Windows-DOSのワイルドカードの表記が、ちょうど良さそうです。

DOSのワイルドカードはカレントディレクトリ内のファイルが対象

ここで問題になったのが、URLのマッチングでは、DOSのワイルドカードと異なり「ディレクトリ」もマッチング対象であるという事でした。
「/*.css」では「/xxx.css」と「/yyy/xxx.css」がマッチします。親直下のファイル指定のつもりが、子ディレクトリも含まれてしまうわけです。

仕方が無く、独自仕様で「***」を追加し対応しました。
「/*.css」では「*」のマッチング対象文字から’/’を除外しファイルに限定します。
「/***.css」では「***」のマッチング対象文字はすべての文字にします。

こうすることで、ディレクトリ直下用には「*」、子ディレクトリも含めてのファイルでは「***」と2種類のマッチングを使い分けることができるようになりました。

マッチングの前提として「^xxx$」、先頭と末端が決められたマッチングにしています。
たとえば「/*.css」では始めが「/」、終わりは「.css」、「*」には’/’が無いので途中のディレクトリが入ってはいけない、というパターンにできます。

URLマッチング設定は見やすくなったか?

こたかはもともとMS-DOSユーザーだったためか、私的にはかなり見やすさが改善されました。

'url_blocked_list' => [
    // preg_match の正規化で指定する。URLが見づらくなってしまう
    '/wlwmanifest\.xml/',
    '/\.env/',
],

'url_blocked_list_wild'=>[
    // ワイルドカード版。内部でpreg_match文字列を作るので若干遅くなる。
    // '?' と '*' と '***'のみ利用可能。
    "/wp-content/uploads/backwpup-***",
    "/wp-content/uploads/***.php", 
],
'routes'=>[
// ワイルドカード版。
// ファビコン各種
'/favicon.ico'                 => [ '/favicons/%f','rewrite' ], // defaultファビコン
'/apple-*.png'                 => [ '/favicons/%f','rewrite' ], // Apple/iPhone/iPadファビコン
'/icon-*.ico'                  => [ '/favicons/%f','rewrite' ], // iconファビコン
'/site-title-*.ico'            => [ '/favicons/%f','rewrite' ], // siteファビコン
'/android-*.ico'               => [ '/favicons/%f','rewrite' ], // androidファビコン
],

特に、以下の点で見やすくなりました。

  • 「.」と「/」のエスケープが不要になった
  • 「*」がファイル名のワイルドカード、「***」が子ディレクトリも含むワイルドカードが意外と理解しやすい

まとめ

今日はワイルドカードがシンプルで良いというお話でした。

記事の内容を濃くしすぎると、書くのも読むのも大変になってしまうので、
今日は、薄めの内容にしてみました。

それでは、また次回お会いしましょう。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です