【WordPress】HTTP/3環境で「Undefined array key "HTTP_HOST"」エラーが出る場合の対応
nginx + PHP-FPM + HTTP/3 環境下において、一部の WordPress のプラグインで、
Undefined array key "HTTP_HOST"
エラーが出る場合の対処方法と、周辺情報についてまとめておきます。
結論から言うと、これは PHP サーバー環境変数 'HTTP_HOST' がセットされていない場合に発生するエラーです。
PHP のサーバー環境変数 'HTTP_HOST' には、HTTP request header の Host ヘッダ由来の値が格納されますが、現行ブラウザは HTTP/3 でのリクエスト時に Host ヘッダを送出しないため、サーバー環境変数 'HTTP_HOST' は設定されない場合があります。
一部のプラグインは2024年8月現在でもサーバー環境変数 'HTTP_HOST' を参照しており、これが原因で例えば管理画面へのログイン時に「このサイトで重大なエラーが発生しました」エラーが発生してしまう、といったケースもあります。
このような場合の暫定的な対処方法としては、functions.php や wp-config.php に以下のようなコードを追加する策があります。
if (!isset($_SERVER['HTTP_HOST'])) {
$_SERVER['HTTP_HOST'] = 'your.default.domainname';
}
Code language: PHP (php)
HTTP/1.1 時代は HTTP request header の Host ヘッダが必須でしたから、PHP から 'HTTP_HOST' を基本的に取得できたわけですが、HTTP/2、HTTP/3 では新たに :authority 疑似ヘッダが導入。現行ブラウザでは :authority 疑似ヘッダのみを送出し Host ヘッダを送出しない実装が基本となっているため、'HTTP_HOST' は基本的には取得できません。
(余談ですが、ブラウザが :authority 疑似ヘッダ と Host ヘッダを両方送出する場合は値が一致する必要があり、値が異なる場合はサーバー側で :authority 疑似ヘッダを優先する、という仕様だったと記憶しています。)
サーバー変数を PHP-FPM へどのように渡すかは WEB サーバー側の実装・設定に依る部分にはなりますが、少なくとも現時点の nginx + PHP-FPM + HTTP/3 の環境下では、PHP からサーバー変数 'HTTP_HOST' が取得できないケースを CLI 以外、つまり、通常の WEB サーバーでも想定する必要があるわけで、そもそも 'HTTP_HOST' の参照を必須とするプラグインを使い続けるかは考えた方が良いところです。
なお、Host ヘッダ、:authority 疑似ヘッダともにクライアント由来の情報になりますから、'HTTP_HOST' の値を PHP 側で設定する場合は、「Host ヘッダインジェクション」と呼ばれるセキュリティホールにならないよう、'HTTP_HOST' を固定値とするかホワイトリスト方式にすることが望ましいです。
下記参考情報の1番目のリンク先によると、HTTP/3 の :authority 疑似ヘッダは Host ヘッダとは異なる個別のヘッダとして処理されるとのことで、このあたりが fastcgi の HTTP_HOST サーバー変数に :authority 疑似変数の値を渡さない理由となっているようです。
参考までに、nginx 側の設定、具体的には fastcgi.conf あたりで fastcgi_param HTTP_HOST $http_authority;
といった書き方をしても :authority 疑似ヘッダは PHP-FPM 側へは渡せませんでした。
参考情報:
- #2483 (http/3 behaves differently with fastcgi_param/php variables breaks Magento admin page redirection) – nginx
- The value of variable `$http_host` will not fallback to the value of `:authority` pseudo-header when the client not providing the request header `Host` · Issue #3 · nginx-quic/nginx-quic · GitHub
- `$_SERVER['HTTP_HOST']` doesn't exist when requesting via HTTP/3 on nginx · Issue #13021 · php/php-src · GitHub