2011-12-08 17 views
17

私は 'location'ディレクティブを最適化しようとしており、特定の場所の一致が試行されたかどうかを判断する良い方法を見つけることができません。場所ブロック内にechoを使用してもここでは役に立ちません。NGINX 'Location'ディレクティブマッチングの順序を制御する方法は?

The NGINX ngx_http_core_module documentation多少混乱します。

は、正規表現を使用するには、接頭辞を使用する必要があります一致、大文字と小文字を区別するために

  1. ~

  2. ~*試合が行われたどのよう

に一致する大文字と小文字を区別するために:

  1. プレフィックスが正確に一致する=プレフィックスのディレクティブ。見つかった場合、検索は停止します。

  2. 従来の文字列の残りのすべての指令。この一致が接頭辞^~を使用した場合、検索は停止します。

  3. 正規表現は、設定ファイルで定義されている順序で指定します。

  4. #3が一致した場合、その結果が使用されます。それ以外の場合は、#2からの一致が使用されます。ここ

ナンバー2は、「従来の文字列は」言うけど、それは^~接頭辞で使用することができると言います。 ~はRegExpを意味しませんか?そうでなければ、RegExpではないものがどのように決定されますか?

具体的には、私は次のことをしたい:

  1. 直接/assetsリテラルの外に何かを添えます。検索を停止します。

  2. 高速CGI停止検索を介してRegExp \.php$|/$と一致するものを提供します。

  3. リテラル/

経由で直接この方法は、他のすべてのサーブ、唯一の非動的なファイル用/マッチ試みが資産の外部から務めています。

私が持っている:

location ^~ /assets {}  # search-terminating literal? or regex? 
location ~ \.php$|/$ {} 
location/{}    # is this match always attempted? 

を文書から、実際の順序は、常にリテラル/マッチを実行している、1-3-2だろうかのように、それが見えます。はい、この最適化は実際のパフォーマンスには何の違いもありませんが、あいまいさを取り除きたいだけです。ウィキから

答えて

7

:だから

location =/{ 
    # matches the query/only. 
    [ configuration A ] 
} 
location/{ 
    # matches any query, since all queries begin with /, but regular 
    # expressions and any longer conventional blocks will be 
    # matched first. 
    [ configuration B ] 
} 

、これは最初にマッチします: location ~ \.php$ {}

資産は、PHPブロック内location/{}

の外に提供されているにもかかわらず、あなたも確保したいですfastcgiに渡す前に悪意のあるアップロードに対して:

if ($uri ~* "^/uploads/") { 
    return 404; 
} 

ご覧のとおり、nginxは期待していたよりも少し違った働きをします。

+0

正規表現が最初に一致する理由はまだ分かりません。与えられた "="指令はありません。次は、 "従来の文字列を使用した残りのすべての命令"です。 '/'は従来の文字列であり、正規表現の前にマッチする必要があります。正規表現全体は暗黙の最適化の手持ちであるため、nginxはここで行うように見えるため、評価の真の順序を決定することが不可能になります。私はapache/iptablesなどは、if/else-if/elseブロックとして定義された同じ順序で、予測可能に処理することで正しく取得できると思います。暗黙的な「より多くの/より少ない」具体的な規則はありません。 – leeoniya

+0

これは間違いなくnginx、特にnginxの 'if'を書き直し/リターンのためだけに使うべきです。私は彼らがこれを単純化することに取り組んでいると思う。あなたの状況では、次のように動作します:1. PHP正規表現が一致する場合は停止します。2. /は静的コンテンツの場合。 – m33lky

+0

注文について間違っています。最初に/ assetsルールを文字列として持つのは、すべての要求に対してPHP正規表現を実行するオーバーヘッドを避けることです。実際、私はFCGIを通さずにassets/docs/example.phpのようなものを提供したいと思っています。私は現在このセットアップを実行しており、正規表現はexample.phpを捕まえません。 ^〜/ assets、/、〜\ .php $ |/$ – leeoniya

関連する問題