マップnginxでの正規表現の使用について

私は長い間何も書いていなかったので、金曜日の終わりをNginxでの単純な、しかし必ずしも明白ではない検索で薄めましょう





このWebサーバーには、構成を大幅に簡素化および短縮できるすばらしいマップディレクティブがあります。ディレクティブの本質は、新しい変数を作成できることです。その値は、1つ以上の元の変数の値に依存します。正規表現を使用すると、ディレクティブはさらに強力になりますが、同時に1つの重要な点について忘れられます。マニュアルからの抜粋:





変数は使用時にのみ評価されるため、マップ変数の宣言自体多数ある場合でも、追加のクエリ処理のオーバーヘッドは発生しません。





そしてここで重要なのは、「マップはリクエストを処理するための追加コストを必要としない」だけでなく「変数は使用時にのみ計算される」ことです。





ご存知のように、Nginx構成はほとんど宣言型です。これはmapディレクティブにも当てはまりhttpコンテキストにあるにもかかわらず、リクエストが処理されるまで評価されません。つまり、結果の変数をコンテキストサーバー、場所、ifなどで使用する場合です。計算の最終結果ではなく、この結果が適切なタイミングで計算される「式」のみを「代入」します。正規表現を使用するまで、この構成の決疑論に問題はありません。つまり、選択を伴う正規表現。より正確には、名前のない選択を含む正規表現。例を示す方が簡単です。





ru.example.com、en.example.com、de.example.comなどの多くの第3レベルのサブドメインを持つドメインexample.comがあり、それらを新しいサブドメインru.exampleにリダイレクトするとします。 org、en.example.org、de.example.orgなど。数百行のリダイレクトを説明する代わりに、次のようにします。





map $host $redirect_host {
  default "example.org";
  "~^(\S+)\.example\.com$"  $1.example.org;
}
server {
    listen       *:80;
    server_name  .example.com;
  location / {
        rewrite ^(.*)$ https://$redirect_host$1 permanent;
    
}
      
      



ここでは、ru.example.comリクエストすると、正規表現マップで計算されるため、場所到達すると$ redirect_host変数ru.example.orgの値が含まれると誤って予想していましたが、実際にはそうではありません:





$ GET -Sd ru.example.com
GET http://ru.example.com
301 Moved Permanently
GET https://ru.example.orgru
      
      



, ru.example.orgru. - , " " rewrite .





- regexp map , , :





map $host $redirect_host {
  default "example.org";
  "~^(\S+)\.example\.com$"  $1.example.org;
}
server {
    listen       *:80;
    server_name  .example.com;
    location / {
        return 301 https://$redirect_host$request_uri;
    }
}
      
      



, ( ).

map:





map $host $redirect_host {
  default "example.org";
  "~^(?<domainlevel3>\S+)\.example\.com$"  $domainlevel3.example.org;
}
server {
    listen       *:80;
    server_name  .example.com;
    location / {
        rewrite ^(.*)$ https://$redirect_host$1 permanent;
    }
}
      
      



:





$ GET -Sd ru.example.com
GET http://ru.example.com
301 Moved Permanently
GET https://ru.example.orgru
      
      



名前のない割り当て$ 1は、名前の付いた$ domainlevel3の結果を取得するためですつまり、両方の正規表現で名前付き選択を使用する必要があります。





map $host $redirect_host {
  default "example.org";
  "~^(?<domainlevel3>\S+)\.example\.com$"  $domainlevel3.example.org;
}
server {
    listen       *:80;
    server_name  .example.com;
    location / {
        rewrite ^(?<requri>.*)$ https://$redirect_host$requri permanent;
    }
}
      
      



そして今、すべてが期待どおりに機能します:





$ GET -Sd ru.example.com
GET http://ru.example.com
301 Moved Permanently
GET https://ru.example.org/
      
      






All Articles