nginxがリクエストをどのように処理するか
未定義のサーバ名のリクエストの処理をどうやって避けるか 名前ベースとIPベースのバーチャルサーバの混合 簡単なPHPサイトの設定 |
名前ベースのバーチャルサーバ
nginxはまずどのserverがリクエストを処理しなければならないかを決定します。3つの全てのバーチャルサーバがポート *:80でlistenしている単純な構成からはじめましょう:
server { listen 80; server_name example.org www.example.org; ... } server { listen 80; server_name example.net www.example.net; ... } server { listen 80; server_name example.com www.example.com; ... }
この設定では、nginxはどのサーバにリクエストが発送されるべきかを決めるためにリクエストのヘッダフィールド"Host"だけをテストします。その値がどのサーバ名とも一致しない、あるいはリクエストがヘッダフィールドをまったく含んでいない場合には、次にnginxはこのポートのデフォルトのサーバにリクエストを発送しようとするでしょう。上の設定では、デフォルトサーバは最初のものです - これはnginxの標準的なデフォルトの挙動です。listenディレクティブ内のdefault_server
パラメータを使って、どのサーバがデフォルトかを明示的に設定することもできます。
server { listen 80 default_server; server_name example.net www.example.net; ... }
default_server
パラメータはバージョン0.8.21から利用可能です。それより前のバージョンでは、代わりにdefault
パラメータが使われるべきです。
デフォルトサーバはlistenポートのプロパティでサーバ名のプロパティでは無いことに注意してください。それ以上は後にします。
未定義のサーバ名のリクエストの処理をどうやって避けるか
"Host"ヘッダフィールドが無いリクエストが許可されない場合は、以下のように定義してサーバは単にリクエストを取り落とします:
server { listen 80; server_name ""; return 444; }
ここで、サーバ名は"Host"ヘッダフィールドが無いリクエストにマッチする空の文字列にセットされます。そして接続を閉じるnginxの特別な非標準のコード444が返されます。
バージョン0.8.48からこれはサーバ名のデフォルトの設定になりました。つまりserver_name ""
は省略することができます。前のバージョンでは、マシーンのhostname がデフォルトサーバ名として使われていました。
名前ベースとIPベースのバーチャルサーバの混合
いくつかのサーバが異なるアドレスでlistenするもっと複雑な設定を見てみましょう:
server { listen 192.168.1.1:80; server_name example.org www.example.org; ... } server { listen 192.168.1.1:80; server_name example.net www.example.net; ... } server { listen 192.168.1.2:80; server_name example.com www.example.com; ... }
この設定では、nginxはまずserverブロックのlistenディレクティブに対してリクエストのIPアドレスとポートをテストします。それから、IPアドレスとポートに一致するserverブロックのserver_name エントリに対してリクエストの"Host"ヘッダフィールドをテストします。サーバ名が見つからない場合は、リクエストはデフォルトのサーバによって処理されるでしょう。例えば、192.168.1.1:80ポートで受け取ったwww.example.com
へのリクエストは、このポートで定義されているwww.example.com
が無いため、192.168.1.1:80ポートのデフォルトサーバ、つまり最初のサーバで処理されるでしょう。
既に述べたように、デフォルトのサーバはlistenポートのプロパティであり、異なるポートには異なるデフォルトのサーバが定義されるでしょう。
server { listen 192.168.1.1:80; server_name example.org www.example.org; ... } server { listen 192.168.1.1:80 default_server; server_name example.net www.example.net; ... } server { listen 192.168.1.2:80 default_server; server_name example.com www.example.com; ... }
簡単なPHPサイトの設定
今度は、代表的な単純なPHPサイトへのリクエストを処理するためにnginxがどうやってlocationを選択するかを見てみましょう。
server { listen 80; server_name example.org www.example.org; root /data/www; location / { index index.html index.php; } location ~* \.(gif|jpg|png)$ { expires 30d; } location ~ \.php$ { fastcgi_pass localhost:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
nginxはリストされている順に関係なく、渡された文字列にもっとも明確なプリフィックスをまず検索します。上の設定では、唯一のプリフィックスlocatinoは"/
"であり、それは全てのリクエストに一致するため、最後の手段として使われます。それから、nginxは設定ファイル内でリストされている順番に正規表現のlocationをチェックします。最初に一致した表現で検索を終了し、nginxはこのlocationを利用するでしょう。正規表現がリクエストに一致しない場合は、nginxは以前に発見した最も明確なプリフィックスを利用します。
全ての種類のlocationは引数無しのリクエスト行のURI部分だけをテストすることに注意してください。これはクエリ文字列の引数は複数の方法で与えられるかも知れないからです。例えば:
/index.php?user=john&page=1 /index.php?page=1&user=john
さらに、クエリ文字列に全てを入れてリクエストするかも知れません:
/index.php?page=1&something+else&user=john
さて、上の設定でリクエストがどのように処理されるかを見てみましょう:
-
リクエスト"
/logo.gif
"は、まずプリフィックスlocation "/
"に一致し、それから正規表現"\.(gif|jpg|png)$
"に一致します。従って、後者のlocationで処理されます。ディレクティブ"root /data/www
"使ってリクエストはファイル/data/www/logo.gif
にマップされ、ファイルがクライアントに送信されます。 -
リクエスト"
/index.php
"はプリフィックスlocation"/
"にも最初に一致し、それから正規表現"\.(php)$
"に一致します。従って、後者のlocationによって処理され、リクエストはlocalhost:9000でlistenしているFastCGIに渡されます。fastcgi_paramディレクティブはFastCGIパラメータSCRIPT_FILENAME
を"/data/www/index.php
"に設定し、FastCGIサーバがファイルを実行します。変数$document_root
はrootディレクティブの値に等しく、変数$fastcgi_script_name
はリクエストURI、"/index.php
"に等しいです。 -
リクエスト"
/about.html
"はプリフィックスlocation"/
" だけに一致し、従ってこのlocationで処理されます。ディレクティブ"root /data/www
"を使ってリクエストはファイル/data/www/about.html
にマップされ、ファイルがクライアントに送信されます。 -
リクエスト"
/
"の処理はもっと複雑です。それはプリフィックスlocation"/
"だけに一致し、従ってこのlocationによって処理されます。それから、indexディレクティブはパラメータと"root /data/www
"ディレクティブに従ってindexファイルの存在をテストします。ファイル/data/www/index.html
が存在せず、/data/www/index.php
が存在する場合、ディレクティブは"/index.php
"への内部リダイレクトを実行し、nginxはリクエストがクライアントによって送信されたかのように再びlocationを検索します。以前に見たように、リダイレクトされたリクエストは結局FastCGIサーバによって処理されるでしょう。
written by Igor Sysoev edited by Brian Mercer |