(CakePHP, ロリポップ) $this->referer() が正常に動作しない
(CakePHP 2.2.1)
コントローラ内でリファラを取得します。
普通なら『http://hoge.jp/controller/view』のようなURLが入るのですが、ロリポップではなぜか『hoge.jp』となり、まったく使い物になりません。
$url = $this->referer();
Cakeのソースから原因を探ります。
どうやら『$this->request』のオブジェクトに丸投げしてるようです。
(lib/Cake/Controller/Controller.php - line:969)
public function referer($default = null, $local = false) {
if ($this->request) {
$referer = $this->request->referer($local);
if ($referer == '/' && $default != null) {
return Router::url($default, true);
}
return $referer;
}
return '/';
}
で、そのオブジェクトの正体は…?
ふむ。
(lib/Cake/Controller/Controller.php - line:98)
* An instance of a CakeRequest object
Linuxの端末で、"CakeRequest"を含むファイルを探します。
見つけました。
find ~/CakePHP/lib/ -name "*.*" -exec grep -l "CakeRequest" {} \;
$ref と $forwarded の値を、ローカル環境とロリポップとで比べてみます。
(lib/Cake/CakeRequest.php - line:393)
public function referer($local = false) {
$ref = env('HTTP_REFERER');
$forwarded = env('HTTP_X_FORWARDED_HOST');
if ($forwarded) {
$ref = $forwarded;
}$base = '';
if (defined('FULL_BASE_URL')) {
$base = FULL_BASE_URL . $this->webroot;
}
if (!empty($ref) && !empty($base)) {
if ($local && strpos($ref, $base) === 0) {
$ref = substr($ref, strlen($base));
if ($ref[0] != '/') {
$ref = '/' . $ref;
}
return $ref;
} elseif (!$local) {
return $ref;
}
}
return '/';
}
ローカル | ロリポップ | |
---|---|---|
$ref | http://localhost/controller/action | http://hoge.jp/controller/action |
$forwarded | (空白) | hoge.jp |
ロリポップでは『env('HTTP_X_FORWARDED_HOST')』に値が入って真になったから、$refを$forwardedが上書きしてしまったんですね。
だったら、下記のような代替手段を使えばOKです。
それにしても、"HTTP_X_FORWARDED_HOST"って何なんでしょうか?
// $url = $this->referer();
$url = env('HTTP_REFERER');
ググッてみたんですが、さっぱり分かりません。
どうも、リバースプロキシを使っている場合には、$ref を $forwarded で上書きする過程は必要らしいのですが…。