/** * subject.txtをダウンロードする * * @return string subject.txt の中身 */ public function downloadSubject() { global $_conf; if ($this->storage === 'file') { FileCtl::mkdirFor($this->subject_file); // 板ディレクトリが無ければ作る if (file_exists($this->subject_file)) { if (!empty($_REQUEST['norefresh']) || empty($_REQUEST['refresh']) && isset($_REQUEST['word'])) { return; // 更新しない場合は、その場で抜けてしまう } elseif (!empty($GLOBALS['expack.subject.multi-threaded-download.done'])) { return; // 並列ダウンロード済の場合も抜ける } elseif (empty($_POST['newthread']) and $this->isSubjectTxtFresh()) { return; // 新規スレ立て時でなく、更新が新しい場合も抜ける } $modified = http_date(filemtime($this->subject_file)); } else { $modified = false; } } // DL $params = array(); $params['timeout'] = $_conf['http_conn_timeout']; $params['readTimeout'] = array($_conf['http_read_timeout'], 0); if ($_conf['proxy_use']) { $params['proxy_host'] = $_conf['proxy_host']; $params['proxy_port'] = $_conf['proxy_port']; } $req = new HTTP_Request($this->subject_url, $params); $modified && $req->addHeader("If-Modified-Since", $modified); $req->addHeader('User-Agent', "Monazilla/1.00 ({$_conf['p2ua']})"); $response = $req->sendRequest(); if (PEAR::isError($response)) { $error_msg = $response->getMessage(); } else { $code = $req->getResponseCode(); if ($code == 302) { // ホストの移転を追跡 $new_host = BbsMap::getCurrentHost($this->host, $this->bbs); if ($new_host != $this->host) { $aNewSubjectTxt = new SubjectTxt($new_host, $this->bbs); $body = $aNewSubjectTxt->downloadSubject(); return $body; } } if (!($code == 200 || $code == 206 || $code == 304)) { //var_dump($req->getResponseHeader()); $error_msg = $code; } } if (isset($error_msg) && strlen($error_msg) > 0) { $url_t = P2Util::throughIme($this->subject_url); $info_msg_ht = "<p class=\"info-msg\">Error: {$error_msg}<br>"; $info_msg_ht .= "rep2 info: <a href=\"{$url_t}\"{$_conf['ext_win_target_at']}>{$this->subject_url}</a> に接続できませんでした。</p>"; P2Util::pushInfoHtml($info_msg_ht); $body = ''; } else { $body = $req->getResponseBody(); } // ■ DL成功して かつ 更新されていたら if ($body && $code != "304") { // したらば or be.2ch.net ならEUCをSJISに変換 if (P2Util::isHostJbbsShitaraba($this->host) || P2Util::isHostBe2chNet($this->host)) { $body = mb_convert_encoding($body, 'CP932', 'CP51932'); } if (FileCtl::file_write_contents($this->subject_file, $body) === false) { p2die('cannot write file'); } } else { // touchすることで更新インターバルが効くので、しばらく再チェックされなくなる // (変更がないのに修正時間を更新するのは、少し気が進まないが、ここでは特に問題ないだろう) if ($this->storage === 'file') { touch($this->subject_file); } } return $body; }
/** * subject.txtをダウンロードする * * @access public * @return array|null|false subject.txtの配列データ(eaccelerator, apc用)、またはnullを返す。 * 失敗した場合はfalseを返す。 */ function downloadSubject() { global $_conf; static $spentDlTime_ = 0; // DL所要合計時間 $perm = isset($_conf['dl_perm']) ? $_conf['dl_perm'] : 0606; $modified = false; if ($this->storage == 'file') { FileCtl::mkdirFor($this->subject_file); // 板ディレクトリが無ければ作る if (file_exists($this->subject_file)) { // ファイルキャッシュがあれば、DL制限時間をかける if (UA::isK()) { $dlSubjectTotalLimitTime = $_conf['dlSubjectTotalLimitTimeM']; } else { $dlSubjectTotalLimitTime = $_conf['dlSubjectTotalLimitTime']; } if ($dlSubjectTotalLimitTime and $spentDlTime_ > $dlSubjectTotalLimitTime) { return null; } // 条件によって、キャッシュを適用する // subject.php でrefresh指定がある時は、キャッシュを適用しない if (!(basename($_SERVER['SCRIPT_NAME']) == $_conf['subject_php'] && !empty($_REQUEST['refresh']))) { // キャッシュ適用指定時は、その場で抜ける if (!empty($_GET['norefresh']) || isset($_REQUEST['word'])) { return null; // 並列ダウンロード済の場合も抜ける } elseif (!empty($GLOBALS['expack.subject.multi-threaded-download.done'])) { return null; // 新規スレ立て時以外で、キャッシュが新鮮な場合も抜ける } elseif (empty($_POST['newthread']) and $this->isSubjectTxtFresh()) { return null; } } $modified = gmdate("D, d M Y H:i:s", filemtime($this->subject_file)) . " GMT"; } } $dlStartTime = $this->microtimeFloat(); // DL require_once 'HTTP/Request.php'; $params = array(); $params['timeout'] = $_conf['fsockopen_time_limit']; if ($_conf['proxy_use']) { $params['proxy_host'] = $_conf['proxy_host']; $params['proxy_port'] = $_conf['proxy_port']; } $req = new HTTP_Request($this->subject_url, $params); $modified && $req->addHeader('If-Modified-Since', $modified); $req->addHeader('User-Agent', sprintf('Monazilla/1.00 (%s/%s)', $_conf['p2uaname'], $_conf['p2version'])); $response = $req->sendRequest(); $error_msg = null; if (PEAR::isError($response)) { $error_msg = $response->getMessage(); } else { $code = $req->getResponseCode(); if ($code == 302) { // ホストの移転を追跡 require_once P2_LIB_DIR . '/BbsMap.php'; $new_host = BbsMap::getCurrentHost($this->host, $this->bbs); if ($new_host != $this->host) { $aNewSubjectTxt = new SubjectTxt($new_host, $this->bbs); return $aNewSubjectTxt->downloadSubject(); } } if (!($code == 200 || $code == 206 || $code == 304)) { //var_dump($req->getResponseHeader()); $error_msg = $code; } } if (!is_null($error_msg) && strlen($error_msg) > 0) { $attrs = array(); if ($_conf['ext_win_target']) { $attrs['target'] = $_conf['ext_win_target']; } $atag = P2View::tagA(P2Util::throughIme($this->subject_url), hs($this->subject_url), $attrs); $msg_ht = sprintf('<div>Error: %s<br>p2 info - %s に接続できませんでした。</div>', hs($error_msg), $atag); P2Util::pushInfoHtml($msg_ht); $body = ''; } else { $body = $req->getResponseBody(); } $dlEndTime = $this->microtimeFloat(); $dlTime = $dlEndTime - $dlStartTime; $spentDlTime_ += $dlTime; // DL成功して かつ 更新されていたら if ($body && $code != '304') { // したらば or be.2ch.net ならEUCをSJISに変換 if (P2Util::isHostJbbsShitaraba($this->host) || P2Util::isHostBe2chNet($this->host)) { $body = mb_convert_encoding($body, 'SJIS-win', 'eucJP-win'); } // eaccelerator or apcに保存する場合 if ($this->storage == 'eaccelerator' || $this->storage == 'apc') { $cache_key = "{$this->host}/{$this->bbs}"; $cont = rtrim($body); $lines = explode("\n", $cont); if ($this->storage == 'eaccelerator') { eaccelerator_lock($cache_key); eaccelerator_put($cache_key, $lines, $_conf['sb_dl_interval']); eaccelerator_unlock($cache_key); } else { apc_store($cache_key, $lines, $_conf['sb_dl_interval']); } return $lines; // ファイルに保存する場合 } else { if (false === FileCtl::filePutRename($this->subject_file, $body)) { // 保存に失敗はしても、既存のキャッシュが読み込めるならよしとしておく if (is_readable($this->subject_file)) { return null; } else { die("Error: cannot write file"); return false; } } chmod($this->subject_file, $perm); } } else { // touchすることで更新インターバルが効くので、しばらく再チェックされなくなる // (変更がないのに修正時間を更新するのは、少し気が進まないが、ここでは特に問題ないだろう) if ($this->storage == 'file') { touch($this->subject_file); } } return null; }