예제 #1
0
 /**
  * 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;
 }
예제 #2
0
파일: SubjectTxt.php 프로젝트: poppen/p2
 /**
  * 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;
 }