page_adsence

2010年10月27日水曜日

さくらレンタルサーバではまった。

さくらレンタルサーバはもう使いたくないってくらいへんな仕様が多い・・・。
hoge.htmlというファイルがあって、「http://www.hogehoge.jp/hoge」のようなURLのリクエストがあった場合、
通常であれば404 Not Foundになるはずなのに、
拡張子の前までの文字のファイルを検索して、マッチしたファイルを表示してしまう。
つまり下記の2つは一緒のファイルが表示される。

http://www.hogehoge.jp/hoge
http://www.hogehoge.jp/hoge.html

この仕様のせいでsymfonyがうまく動かなくて、手間取った。
routing.ymlに書いてあるにも関わらず、デフォルトのルールにマッチしてしまい、
404 Not Foundになってしまうということが起きた。
apacheのmod_rewriteのせいとか色々疑ってみたけど、symfony内部の処理のせいだった。
sfWebRequest.class.phpの中を修正しないとちゃんと動かない。

/**
 * Retrieves the path info for the current web request.
 *
 * @return string Path info
 */
public function getPathInfo()
{
  $pathInfo = '';

  $pathArray = $this->getPathInfoArray();
  // simulate PATH_INFO if needed
  $sf_path_info_key = $this->options['path_info_key'];
  if ( !preg_match('/^(.*)\.php$/', $this->getScriptName(), $matched) ) unset($pathArray[$sf_path_info_key]);
  if (!isset($pathArray[$sf_path_info_key]) || !$pathArray[$sf_path_info_key])
  {
    if (isset($pathArray['REQUEST_URI']))
    {
      $qs = isset($pathArray['QUERY_STRING']) ? $pathArray['QUERY_STRING'] : '';
      $script_name = $this->getScriptName();
      if ( !preg_match('/^(.*)\.php$/', $script_name, $matched) ) $script_name .= '.php';
      else $script_name = $matched[1];
      $uri_prefix = $this->isAbsUri() ? $this->getUriPrefix() : '';
      $pathInfo = preg_replace('/^'.preg_quote($uri_prefix, '/').'/','',$pathArray['REQUEST_URI']);
      $pathInfo = preg_replace('/^'.preg_quote($script_name, '/').'/', '', $pathInfo);
      $prefix_name = preg_replace('#/[^/]+$#', '', $script_name);
      $pathInfo = preg_replace('/^'.preg_quote($prefix_name, '/').'/', '', $pathInfo);
      $pathInfo = preg_replace('/\??'.preg_quote($qs, '/').'$/', '', $pathInfo);
    }
  }
  else
  {
    $pathInfo = $pathArray[$sf_path_info_key];
    if ($relativeUrlRoot = $this->getRelativeUrlRoot())
    {
      $pathInfo = preg_replace('/^'.str_replace('/', '\\/', $relativeUrlRoot).'\//', '', $pathInfo);
    }
  }

  // for IIS
  if (isset($_SERVER['SERVER_SOFTWARE']) && false !== stripos($_SERVER['SERVER_SOFTWARE'], 'iis') && $pos = stripos($pathInfo, '.php'))
  {
    $pathInfo = substr($pathInfo, $pos + 4);
  }

  if (!$pathInfo)
  {
    $pathInfo = '/';
  }

  return $pathInfo;
}

上記のように赤文字になっている部分の処理を修正する必要がある。