location コンテキスト
まず location コンテキストの公式の説明は下記を見て欲しい。
・location コンテキスト:Module ngx_http_core_module の location 項目
location コンテキストは,nginx.conf(それ自体が main コンテキストとなっている)の中の http コンテキストの中の server コンテキストの中に置かれるコンテキストである(言葉で書くとややこしいなぁ…)。前回を見て欲しいが,nginx.conf では,http コンテキストで web サーバーとしての設定を記載する。その中には,複数の(仮想)サーバー(バーチャルホスト)を列挙することができ,(仮想)サーバー1個ごとに1つの server コンテキストを記載する。 server コンテキストの中では,どのポート宛のものに応答するかや,どのサーバー名宛のリクエストに応答するか,などを記載するが,その server に対するリクエスト URI( server 中の特定のディレクトリや特定の拡張子を持つファイルへのアクセス等を記載)にどのように応答するか,を記載するのが location コンテキストである。 そのため location コンテキストは通常は server コンテキスト中に複数(多数)存在することになる。
以下に location コンテキストのパターンを書こう(公式ドキュメントの location 項目の記載をそのまま手コピーしただけだが…)
location = / { [ configuration A ] } location / { [ configuration B ] } location /documents/ { [ configuration C ] } location ^~ /images/ { [ configuration D ] } location ~* \.(gif|jpg|jpeg)$ { [ configuration E ] }
location コンテキストは,第1パラメーターとして「一致条件((修飾子+)URI)」を必要とする。 リクエスト URI がこの一致条件に合致すれば,その location コンテキストの内容が適用される。
一致条件には大きく分けて2種類あり,「接頭辞文字列」(prefix string) と「正規表現」がある。 修飾子が「~」あるいは「~*」の場合は正規表現とみなされ,それ以外の修飾子(「=」,「^~」,(なし))の場合は接頭辞文字列とみなされる。
正規表現の場合,修飾子「~*」は大文字小文字を区別せず,「~」の場合は大文字小文字を区別する正規表現として,合致するかどうかが判断される。
「=」修飾子の接頭辞文字列の場合は,リクエスト URI と完全に一致した時に合致したとみなされる(完全一致)。
他の接頭辞文字列の場合,リクエスト URI の先頭から接頭辞文字列に一致していれば,後ろには何が続いても合致するとみなされる(前方一致)。
nginx では,要求された URI に対して,複数ある location コンテキストの一致条件を検索する。
(1) 一番優先度が高いのが「=」修飾子を持つ接頭辞文字列の場合であり, 記載順に検索して最初に一致した「=」接頭辞文字列の場合の location コンテキストの設定が適用される。 (2) 次にその他の接頭辞文字列条件を「すべて」検索し,「最も長く一致する」接頭辞文字列の場合を「記憶」しておく。 ここで最も長く一致する接頭辞文字列が「^~」修飾子を持つ場合は,その location コンテキストの設定が適用される。 (3) その次に正規表現で合致するものを,記載順(上から順)に調べていき, 最初に一致した正規表現を持つ location コンテキストの設定が適用される。 (4) 正規表現で合致するものがなければ,接頭辞文字列で 一番長く一致した location コンテキストの設定が適用される。
上記の表の例だと,「/」のみのリクエストなら,設定「A」が適用される。 「/index.html」なら設定「B」になる。 「/documents/document.html」なら設定「C」になり,「/images/1.gif」なら「D」,「/documents/1.jpg」なら「E」が適用される。
この判定条件がわかっていないと,nginx の設定をしてもうまく動作しない,ということになってしまう。
nginx における CGI
nginx で CGI を使うには,(1) nginx に FCGI モジュールを組み込み,(2) fcgiwrap アプリを用いればよい。 この場合,nginx と fcgiwrap の間のやりとりは unix domain socket を通じて行う。 ちまたでは,fcgiwrap の他に spawn-fcgi も必要と書いてあることがあるが,unix domain socket を使う場合にはいらないみたい。
nginx 自体は CGI を使うためのモジュールはもっていない。 その代わり FastCGI (FCGI) のモジュールが公式にサポートされている。 nginx で fcgi を使うには,インストール時に fcgi モジュールを組み込んでおかないといけないが,FreeBSD の /usr/ports/www/nginx/ からインストールした場合には,make config の際に fcgi モジュールを選ぶ選択肢はなかったので,最初から組み込まれるようになっているような気がする。 そのため,今回は特に何かをしないといけない,ということはなかった。
fcgiwrap は cgi を fcgi で使えるようにするものであり,ほとんどの場合,cgi のスクリプトをそのまま実行してくれる。 FreeBSD では /usr/ports/www/fcgiwrap/ からインストールできる。 インストール後,/etc/rc.conf に以下を追加した。
fcgiwrap_enable="YES" fcgiwrap_user="www" fcgiwrap_socket_owner="www" fcgiwrap_socket="unix:/var/run/fcgiwrap/fcgiwrap.socket"ここで user と socket_owner を共に www にしている。 これは nginx と fcgiwrap の間で socket をやり取りする際に,同じ user,owner でなければうまくいかなかったから,である。 最後の行が unix domain socket を使う,と宣言してるようなもの,だと思っている(実はわかってない…)
rc.conf の中に /var/run/fcgiwrap/ というディレクトリが出てくるので,念のために「/var/run/fcgiwrap/」を作り,permission を 777 にしておいた。
後は,以下のようにして起動すれば準備できあがり,である。
# service fcgiwrap start
CGI を使うための nginx の設定
以下に CGI を使うための nginx.conf の簡単な例を載せよう。 前回書いた設定ファイルの例と違う部分に色を付けてみた。 赤い部分は,fcgi とは直接関係はなく,青い部分が fcgi に関連している。 説明は設定例の下で書こう。
(nginx 設定ファイル:CGI を使う例) user www www; worker_processes 2; error_log /var/log/nginx/error.log error; pid /var/run/nginx.pid; # ================================================================== events { worker_connections 500; use kqueue; } # ================================================================== http { server_tokens off; include mime.types; default_type application/octet-stream; charset UTF-8; sendfile on; tcp_nopush on; keepalive_timeout 75; gzip on; root /usr/local/www/data; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; error_page 401 /401.html; error_page 403 404 /404.html; error_page 500 502 503 504 /50x.html; # --------------------------------------------------------- server { listen 80 default_server; server_name www.xxxxx.com yyy.xxxxx.com zzz.xxxxx.com; location / { index index.html /index.html; } location ~ \.cgi$ { include fastcgi_params; fastcgi_pass unix:/var/run/fcgiwrap/fcgiwrap.socket; fastcgi_index index.cgi; fastcgi_param SCRIPT_FILENAME /usr/local/www/data$fastcgi_script_name; } } }まずは,fcgi に関連する青い部分について書こう。 と言っても,あまり説明するところはないが…。
最初に,location コンテキストの一致条件は「正規表現」で与えられ,リクエスト URI が「.cgi」で終わっている場合に適用される。 それ以外は一個上の「/」を「接頭辞文字列」として持つ location コンテキストの設定が適用される。
次に「fastcgi_params」を読み込んで (include) いる。 これは FreeBSD の場合 /usr/local/etc/nginx/ の下にインストール時に入れられていた fcgi の設定ファイルみたい。 今回はいじってないので,中身は書かないでおこう。
・fastcgi_pass ディレクティブは,nginx と fcgi モジュール間の通信のルートを示していて,ここでは fcgiwrap の設定と同じ unix domain socket を指定している。unix domain socket 以外には IP + port 番号で指定することもできる。location のコンテキストと,location コンテキスト中の if ディレクティブに記載できる。
・fastcgi_index ディレクティブは,cgi (fcgi) のリクエスト URI がスラッシュで終わっている場合のデフォルトのファイルのファイル名である。location のコンテキストと,location コンテキスト中の if ディレクティブに記載できる。
・fastcgi_param ディレクティブは,第一パラメーターに指定したい「パラメーター名」を書き,第2パラメーターに「値」を書く。今回の例では「SCRIPT_FILENAME」を指定している。 具体的には,FCGI は必ず「/usr/local/www/data」の下にあり,リクエスト URI が,例えば「/info/」なら,「/usr/local/www/data/info/index.cgi」となる(直前の「fcgi_index」と組み合わせている)。 リクエスト URI が「/cgi/hello.cgi」なら「/usr/local/www/data/cgi/hello.cgi」が「SCRIPT_FILENAME」に入れられる。http,server,location のコンテキストに記載できる。
赤い部分は前回書いた設定ファイルの例と違う部分であり,「root」は,全仮想サーバーに共通で「/usr/local/www/data」に置くという指示である。
・error_page ディレクティブは,エラー番号ごとに表示するファイルを指定している。省略するとデフォルトのエラーメッセージが web ページ上に表示されるが,nginx のデフォルトの場合にエラーページに「nginx」と出るので,それが出ないようにページを作っている。また,403 エラーの時には 404 と同じエラーページを表示するようにしている。http,server,location のコンテキストと,location コンテキスト中の if ディレクティブに記載できる。
私の場合は,これで cgi を動かすことができた。特にトラブルはなかったように思う。
次回は https 化と Digest 認証について記載しよう。
FreeBSD で nginx に挑戦してみた(その4)に続く
0 件のコメント:
コメントを投稿