PukiwikiのURL表示を"ちゃんと"httpsにする
みなさまごきげんよう、宮野です。
わかりづらい表題ですが、リバースプロキシしたApache上で運用しているPukiwikiのちょっと気になってた点を修正しましたというエントリです。
Pukiwiki を運用しています
最近Pukiwikiの運用をはじめました。宮野がオタク資料を集めたり集めなかったりします。名付けてMiyaDoc。最近の更新はもっぱらアサルトリリィです。
ちょっぴりあった問題
MiyaDocで気になっていた点はページタイトル下のURL表示がhttpに固定されてしまうことでした。MiyaDocもちゃんとHTTPSで通信できるようにしていますから、この挙動はあまりよろしくありません。
原因はわかっていて、宮野鯖はMastodonなどを運用している関係でWebサーバにNginxを使っていますが、Apacheを使うやつ(Pukiwikiもその一つ)も動かしているのでNginxからApacheへリバースプロキシもしているためでした。
解決法
Pukiwikiのこのリンクは lib/func.php
で定義されている get_page_uri()
という関数で呼び出されていますが、HTTPとHTTPSの判別はさらに別の guess_script_absolute_uri()
という関数が呼び出されます。
guess_script_absolute_uri()
の実装を見てみると、$_SERVER['HTTPS']
が定義されていて値が on
であるとき、あるいは $_SERVER['REQUEST_SCHEME']
が定義されていて値が https
であるときに $is_ssl
がtrueになりスキームがhttpsになります。
ここまでわかればやることは明快です。リバースプロキシで X-Forwarded-Proto
ヘッダでHTTPSによるアクセスかどうか飛ばしているならそれを反映させればいいわけです。
$is_forwarded = (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https';
if ($is_ssl || $is_forwarded) { $host = 'https://' . SERVER_NAME . (($port == 443 || $is_forwarded) ? '' : ':' . $port); } else { $host = 'http://' . SERVER_NAME . ($port == 80 ? '' : ':' . $port); }
今回は $is_forwarded
というフラグを別にセットし、リバースプロキシによりフォワードされていた場合はポート番号の付加を省略するようにしました。
解決
URLがちゃんとhttps://で始まるようになりました。
補足
X-Forwarded-proto
ヘッダは事実上の標準となっているヘッダで、現在は Forwarded
という標準化されたヘッダーがあります。
いずれ、Forwarded
で書くのが当たり前になるのかな~と思っています。