10. FastCGIアプリケーション
HAProxyは、Responder型のFastCGIアプリケーションへHTTPリクエストを送れます。この機能はHAProxy 2.1で追加されました。使うには、サーバーでFastCGIプロトコルを使うよう設定し(server行の"proto fcgi"キーワード)、そのサーバーを管理するバックエンドでFastCGIアプリケーションを設定して使用しなければなりません(proxyセクションの"use-fcgi-app"キーワード)。複数のFastCGIアプリケーションを定義できますが、一つのバックエンドが同時に使えるのは一つだけです。
HAProxyは、Responder型アプリケーションに関するFastCGI仕様の全機能を実装しています。特に、単一の接続上で複数のリクエストを多重化できます。
10.1. 設定
10.1.1. Fcgi-appセクション
fcgi-app <name>
<name>という名前のFastCGIアプリケーションを宣言します。有効な設定とするには、少なくともドキュメントルートを定義しなければなりません。
acl <aclname> <criterion> [flags] [operator] <value> ...
アクセスリストを宣言、または既存の宣言を補完します。
詳細は、セクション4.2 の"acl"キーワードと、ACLの使い方についてのセクション7 を参照してください。FastCGIアプリケーション用に定義したACLは、そのアプリケーション専用です。ほかのアプリケーションやプロキシからは使えません。同様に、ほかのセクションで定義したACLも、FastCGIアプリケーションからは使えません。ただし、定義済みACLは利用できます。
docroot <path>
リモートホスト上のドキュメントルートを定義します。<path>は、FastCGIパラメーターSCRIPT_FILENAMEとPATH_TRANSLATEDのデフォルト値の構築に使います。必須の設定です。
index <script-name>
スラッシュ("/")で終わるURIの後に追加するスクリプト名を定義し、FastCGIパラメーターSCRIPT_NAMEのデフォルト値を設定します。任意の設定です。
例:
log-stderr global
FastCGIアプリケーションが出力するSTDERRメッセージのログ記録を有効にします。
詳細は、セクション4.2 の"log"キーワードを参照してください。任意の設定です。デフォルトでは、STDERRメッセージは無視されます。
pass-header <name> [ { if | unless } <condition> ]
FastCGIアプリケーションへ渡すリクエストヘッダーの名前を指定します。後ろに任意でACLに基づく条件を付けられ、その場合は、条件が真のときだけ評価されます。
ほとんどのリクエストヘッダーは、すでに"HTTP_“の接頭辞付きでFastCGIアプリケーションから利用できます。そのため、このディレクティブが必要なのは、意図的に除外されているヘッダーを渡す場合だけです。現在は、“Authorization”、“Proxy-Authorization”、およびホップ単位のヘッダーが除外されています。
“Content-type"と"Content-length"ヘッダーは、すでにパラメーターへ変換されているため、FastCGIアプリケーションへ渡されることはありません。
path-info <regex>
URLデコード済みのパスからscript-nameとpath-infoを抽出する正規表現を定義します。<regex>は二つのキャプチャーを持つことができ、最初のものはスクリプト名、二番目はpath-infoを取得します。最初のキャプチャーは必須で、二番目は任意です。そのため、path-infoを無視して、パスからscript-nameだけを抽出できます。これは任意の設定です。未定義の場合はパスの照合を行わず、FastCGIパラメーターのPATH_INFOとPATH_TRANSLATEDには値を設定しません。
セキュリティ上の理由から、この正規表現を定義した場合、URLデコード後のパスに改行文字とヌル文字を含めることは禁止されます。これらがあると、HAProxyでの正規表現の実行方法の制限により、照合が必ず失敗するためです。そのため、URLデコード済みのパスにどちらかの文字が見つかった場合は、クライアントへエラーを返します。ここでは驚き最小の原則を適用しています。
例:
option get-values
接続管理に関する変数の取得を有効または無効にします。
HAProxyは、接続確立時にFCGI_GET_VALUESレコードを送信し、次の変数の値を取得できます。
* FCGI_MAX_REQS このアプリケーションが受け付ける同時リクエスト数の上限。
* FCGI_MPXS_CONNS このアプリケーションが接続の多重化を行わない場合は"0"、
行う場合は"1"。
この機能をサポートしないFastCGIアプリケーションもあります。また、応答を送った直後に接続を閉じるものもあります。そのため、このオプションはデフォルトで無効です。
FastCGIアプリケーションが受け付ける同時リクエスト数の上限は、接続に属する変数であることに注意してください。制限されるのは、接続ごとのストリーム数だけです。アプリケーション全体の負荷を制限する必要がある場合は、サーバーパラメーターの"maxconn"と"pool-max-conn"を設定しなければなりません。また、アプリケーションが接続の多重化をサポートしない場合、同時リクエスト数の上限は自動的に1に設定されます。
option keep-conn
応答を送信した後も接続を開いたままにするかどうかを、FastCGIアプリケーションへ指示します。
無効にすると、FastCGIアプリケーションはこのリクエストに応答した後、接続を閉じます。デフォルトでは有効です。
option max-reqs <reqs>
このアプリケーションが受け付ける同時リクエスト数の上限を定義します。
接続確立時に変数FCGI_MAX_REQSを取得すると、このオプションが上書きされる場合があります。また、アプリケーションが接続の多重化をサポートしない場合、このオプションは無視されます。デフォルトは1です。
option mpxs-conns
接続の多重化のサポートを有効または無効にします。
接続確立時に変数FCGI_MPXS_CONNSを取得すると、このオプションが上書きされる場合があります。デフォルトでは無効です。
set-param <name> <fmt> [ { if | unless } <condition> ]
このアプリケーションへ渡すFastCGIパラメーターを設定します。<fmt>で定義する値は、カスタムログ形式の規則に従わなければなりません(セクション8.2.6
「カスタムログ形式」を参照)。後ろに任意でACLに基づく条件を付けられ、その場合は、条件が真のときだけ評価されます。
このディレクティブで、デフォルトのFastCGIパラメーターの値を上書きできます。評価結果が空文字列になる場合、そのルールは無視されます。これらのディレクティブは、宣言順に評価されます。
例:
10.1.2. Proxyセクション
use-fcgi-app <name> バックエンドで使うFastCGIアプリケーションを定義します。
引数:
このキーワードは、バックエンド機能を持ち、FastCGIサーバーが少なくとも一つあるHTTPプロキシでのみ利用できます。FastCGIサーバーとHTTPサーバーを混在させることはできますが、十分な理由がない限り推奨しません(詳細は制限についてのセクション10.3 を参照)。一つのバックエンドに対して同時に定義できるアプリケーションは一つだけです。
バックエンドからFastCGIアプリケーションを参照すると、リクエストをFastCGIサーバーへ送らない場合でも、設定によっては一部の処理が行われる点に注意してください。パラメーターの設定や、アプリケーションへヘッダーを渡すためのルールが評価されます。
10.1.3. 例
10.2. デフォルトのパラメーター
Responder型のFastCGIアプリケーションは、CGI/1.1プログラムと同じ役割を持ちます。CGI/1.1仕様(RFC3875)では、いくつかの変数をスクリプトへ渡さなければなりません。そのため、HAProxyはそれらに加え、FastCGIアプリケーションでよく使われる変数も設定します。これらの変数はすべて上書きできますが、注意が必要です。
10.3. 制限
現在の実装には、いくつかの制限があります。最初は、一部のリクエストヘッダーをFastCGIアプリケーションへ見せない方法に関するものです。この処理は、接続確立前、バックエンド側のヘッダー解析時に行われます。この段階では、HAProxyはバックエンドがFastCGIアプリケーションを使うことは分かりますが、リクエストがFastCGIサーバーへ送られるかは分かりません。ヘッダーを隠すために、HTXメッセージから単純に削除します。そのため、最終的にHTTPサーバーへ送られた場合、そのサーバーはこれらのヘッダーを受け取りません。これが、同じバックエンドにFastCGIサーバーとHTTPサーバーを混在させることを推奨しない理由です。
同様に、“set-param"と"pass-header"のルールも、リクエストヘッダーの解析時に評価します。そのため、最終的にHTTPサーバーへ転送する場合も、常に評価されます。
“set-param"ルールを適用すると、HTXメッセージへ擬似ヘッダーが追加されます。そのため、HTTPヘッダーの書き換えと同様に、バッファーが満杯の場合は失敗することがあります。“set-param"ルールは、“http-request"ルールと領域を取り合います。
最後に、すべてのFastCGIパラメーターとHTTPヘッダーは、単一のFCGI_PARAMレコードで送ります。このレコードのエンコードは一度で行わなければならず、できなければ処理エラーを返します。つまり、エンコード後のFCGI_PARAMレコードは、バッファーのサイズを超えてはなりません。ただし、ここでは確保しておくべき予約領域はありません。