参考: http://httpd.apache.org/docs/2.4/en/mod/mod_headers.html#header
Headerディレクティブは指定子の直後に、省略可能なパラメータとしてconditionを取ることになっている。
conditionはonsuccessかalwaysを指定できる。
省略した場合はonsuccessを指定したことになる。
これは、マニュアルに書かれている通り、レスポンスヘッダ情報を持つ内部テーブルを指定する。
内部テーブルは2つあってrequest_recの持つテーブルだ。
(httpd-2.4.9/include/httpd.h) 781 struct request_rec { : 911 /** MIME header environment for the response */ 912 apr_table_t *headers_out; 913 /** MIME header environment for the response, printed even on errors and 914 * persist across internal redirects */ 915 apr_table_t *err_headers_out; :
condition毎の処理対象のテーブルは以下の通りの対応になっている。
onsuccess | headers_out |
always | err_headers_out |
厄介なことに、"成功時"、"常時"、といった意味のconditionのパラメータになっているが、
必ずしも、その字義通りの条件で機能しない。
私の把握する限りでは、CGIスクリプトの返すレスポンスヘッダの多くは、err_headers_outテーブルにセットされる(Locationや、Content-Lengthなどheaders_outにセットされるものもある)。
mod_proxy_ajpから返されるレスポンスヘッダのほとんどは、逆にheaders_outにセットされる。
つまり mod_proxy_ajpで繋いだ先のTomcatが
X-RESPONSE-HEADER: this is testというレスポンスを返した場合、このヘッダ情報は、headers_outに格納されることになる。
もし、
Header onsuccess append X-RESPONSE-HEADER "set at Apache"と指定すると、最終的なレスポンスヘッダは、
X-RESPONSE-HEADER: this is test, set at Apacheとなる。
これは、headers_outテーブルに対して存在するX-RESPONSE-HEADERヘッダ情報に対して処理が行われたためだ。
他方、同じヘッダをmod_cgid経由で実行されるCGIスクリプトが返した場合、
レスポンスのヘッダは、
X-RESPONSE-HEADER: this is testと2行になってしまう。
X-RESPONSE-HEADER: set at Apache
CGIスクリプトから返されたヘッダは、err_headers_outテーブルに格納されるが、
一方、Headersディレクティブは、headers_outテーブルにappendが指示されている。
そのため、結局2つのテーブルに同じヘッダが作成されてしまうことになってしまう。
そして、最後にレスポンスを返す時、この2つのテーブルがマージされるためにこうなってしまっている。
もし逆に、
Header always append X-RESPONSE-HEADER "set at Apache"とalwaysを指定した場合、
mod_proxy_ajp経由だと、次のようなヘッダになる。
X-RESPONSE-HEADER: set at Apachemod_cgid経由だと、次のようなヘッダになる。
X-RESPONSE-HEADER: this is test
X-RESPONSE-HEADER: this is test, set at Apache
onsuccessの結果が分かれば、こちらは予想通りだろう。
これは、httpd-2.2系でも同じだ。