Example #1
0
 /**
  * SETTING.TXT をダウンロードして、パースして、キャッシュする
  *
  * @access  public
  * @return  true|null|false  成功|更新なし(キャッシュ)|失敗
  */
 function downloadSettingTxt()
 {
     global $_conf;
     $perm = $_conf['dl_perm'] ? $_conf['dl_perm'] : 0606;
     FileCtl::mkdirFor($this->setting_txt);
     // 板ディレクトリが無ければ作る
     $modified = null;
     if (file_exists($this->setting_srd) && file_exists($this->setting_txt)) {
         // 更新しない場合は、その場で抜けてしまう
         if (!empty($_GET['norefresh']) || isset($_REQUEST['word'])) {
             return null;
             // キャッシュが新しい場合も抜ける
         } elseif ($this->isSettingSrdCacheFresh()) {
             return null;
         }
         $modified = gmdate('D, d M Y H:i:s', filemtime($this->setting_txt)) . ' GMT';
     }
     // DL
     /*
     // PHP5
     if (!class_exists('HTTP_Request', false)) {
         require 'HTTP/Request.php';
     }
     */
     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->url, $params);
     $modified && $req->addHeader('If-Modified-Since', $modified);
     $req->addHeader('User-Agent', 'Monazilla/1.00 (' . $_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) {
                 $aNewSettingTxt = new SettingTxt($new_host, $this->bbs);
                 return $aNewSettingTxt->downloadSettingTxt();
             }
         }
         if (!($code == 200 || $code == 206 || $code == 304)) {
             //var_dump($req->getResponseHeader());
             $error_msg = $code;
         }
     }
     // DLエラー
     if (strlen($error_msg)) {
         P2Util::pushInfoHtml(sprintf('<div>Error: %s<br>p2 info - %s に接続できませんでした。</div>', hs($error_msg), P2View::tagA(P2Util::throughIme($this->url), hs($this->url), array('target' => $_conf['ext_win_target']))));
         touch($this->setting_txt);
         // DL失敗した場合(404)も touch する
         touch($this->setting_srd);
         return false;
     }
     $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, 'SJIS-win', 'eucJP-win');
         }
         if (false === FileCtl::filePutRename($this->setting_txt, $body)) {
             die('Error: cannot write file');
         }
         chmod($this->setting_txt, $perm);
         // パースして
         if (!$this->setSettingArrayFromSettingTxt()) {
             return false;
         }
         // srd保存する
         if (!$this->saveSettingSrd($this->setting_array)) {
             return false;
         }
     } else {
         // touchすることで更新インターバルが効くので、しばらく再チェックされなくなる
         touch($this->setting_txt);
         // 同時にキャッシュもtouchしないと、setting_txtとsetting_srdで更新時間がずれて、
         // 毎回ここまで処理が来る(サーバへのヘッダリクエストが飛ぶ)場合がある。
         touch($this->setting_srd);
     }
     return true;
 }
Example #2
0
 /**
  * 標準方法で 2ch互換 DAT を差分ダウンロードする
  *
  * @access  private
  * @return  true|string|false  取得できたか、更新がなかった場合はtrue(または"304 Not Modified")を返す
  */
 function downloadDat2ch($from_bytes)
 {
     global $_conf;
     global $debug;
     if (!($this->host && $this->bbs && $this->key)) {
         return false;
     }
     $range_bytes = intval($from_bytes);
     if ($range_bytes == 0) {
         $zero_read = true;
     } else {
         $zero_read = false;
         $range_bytes = $from_bytes - 1;
     }
     //$url = 'http://' . $this->host . '/' . $this->bbs . '/dat/' . $this->key . '.dat';
     $url = $this->getDatUrl($this->host, $this->bbs, $this->key);
     $purl = parse_url($url);
     $purl['query'] = isset($purl['query']) ? '?' . $purl['query'] : '';
     // プロキシ
     if ($_conf['proxy_use']) {
         $send_host = $_conf['proxy_host'];
         $send_port = $_conf['proxy_port'];
         $send_path = $url;
     } else {
         $send_host = $purl['host'];
         $send_port = isset($purl['port']) ? $purl['port'] : null;
         $send_path = $purl['path'] . $purl['query'];
     }
     !$send_port and $send_port = 80;
     $request = 'GET ' . $send_path . " HTTP/1.0\r\n";
     $request .= "Host: " . $purl['host'] . "\r\n";
     $request .= "Accept: */*\r\n";
     //$request .= "Accept-Charset: Shift_JIS\r\n";
     //$request .= "Accept-Encoding: gzip, deflate\r\n";
     $request .= "Accept-Language: ja, en\r\n";
     $request .= "User-Agent: " . P2Util::getP2UA($withMonazilla = true) . "\r\n";
     if (!$zero_read) {
         $request .= "Range: bytes={$range_bytes}-\r\n";
     }
     $request .= "Referer: http://{$purl['host']}/{$this->bbs}/\r\n";
     if ($this->modified) {
         $request .= "If-Modified-Since: " . $this->modified . "\r\n";
     }
     // Basic認証用のヘッダ
     if (isset($purl['user']) && isset($purl['pass'])) {
         $request .= "Authorization: Basic " . base64_encode($purl['user'] . ":" . $purl['pass']) . "\r\n";
     }
     $request .= "Connection: Close\r\n";
     $request .= "\r\n";
     // WEBサーバへ接続
     $fp = @fsockopen($send_host, $send_port, $errno, $errstr, $_conf['fsockopen_time_limit']);
     if (!$fp) {
         P2Util::pushInfoHtml(sprintf('<p>サーバ接続エラー: %s (%s)<br>p2 info - %s に接続できませんでした。</div>', hs($errstr), hs($errno), P2View::tagA(P2Util::throughIme($url), hs($url), array('target' => $_conf['ext_win_target']))));
         $this->diedat = true;
         return false;
     }
     // HTTPリクエスト送信
     fputs($fp, $request);
     // HTTPヘッダレスポンスを取得する
     $h = $this->freadHttpHeader($fp);
     if ($h === false) {
         fclose($fp);
         $this->_pushInfoHtmlFreadHttpHeaderError($url);
         $this->diedat = true;
         return false;
     }
     // {{{ HTTPコードをチェック
     $code = $h['code'];
     // 206 Partial Content
     if ($code == "200" || $code == "206") {
         // OK。何もしない
         // Found
     } elseif ($code == "302") {
         // ホストの移転を追跡
         require_once P2_LIB_DIR . '/BbsMap.php';
         $new_host = BbsMap::getCurrentHost($this->host, $this->bbs);
         if ($new_host != $this->host) {
             fclose($fp);
             $this->old_host = $this->host;
             $this->host = $new_host;
             return $this->downloadDat2ch($from_bytes);
         } else {
             fclose($fp);
             // 2007/06/11 302の時に、UAをMonazillaにしないでDATアクセスを試みると203が帰ってきて、
             // body中に'過去ログ ★'とあれば、●落ち中とみなすことにする。
             // 仕様の確証が取れていないので、このような判断でよいのかはっきりしない。
             // 203 Non-Authoritative Information
             // 過去ログ ★
             /*
             名無し募集中。。。<><>2007/06/10(日) 13:29:51.68 0<> http://mlb.yahoo.co.jp/headlines/?a=2279 <br> くわわ>>>>>>>>>>>>>>>>>>>>>井川 <>★くわわメジャー昇格おめ 売上議論14001★
             1001, 131428 (総レス数, サイズ)<><>1181480550000000 (最終更新)<><div style="color:navy;font-size:smaller;">|<br />| 中略<br />|</div><>
             1001<><>Over 1000 Thread<> このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。  <>
             過去ログ ★<><>[過去ログ]<><div style="color:red;text-align:center;">■ このスレッドは過去ログ倉庫に格納されています</div><hr /><br />IE等普通のブラウザで見る場合 http://tubo.80.kg/tubo_and_maru.html<br />専用のブラウザで見る場合 http://www.monazilla.org/<br /><br />2ちゃんねる Viewer を使うと、すぐに読めます。 http://2ch.tora3.net/<br /><div style="color:navy;">この Viewer(通称●) の売上で、2ちゃんねるは設備を増強しています。<br />●が売れたら、新しいサーバを投入できるという事です。</div><br />よくわからない場合はソフトウェア板へGo http://pc11.2ch.net/software/<br /><br />モリタポ ( http://find.2ch.net/faq/faq2.php#c1 ) を持っていれば、50モリタポで表示できます。<br />    こちらから → http://find.2ch.net/index.php?STR=dat:http://ex23.2ch.net/test/read.cgi/morningcoffee/1181449791/<br /><br /><hr /><>
             */
             $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($url, $params);
             $req->setMethod('GET');
             $err = $req->sendRequest(true);
             if (PEAR::isError($err)) {
                 //var_dump('error');
             } else {
                 // レスポンスコードを検証
                 if ('203' == $req->getResponseCode()) {
                     $body2 = $req->getResponseBody();
                     $reason = null;
                     // $body2 "過去ログ ★<><>[過去ログ]<>「隊長! 過去ログ倉庫で、スレッド http://qb5.2ch.net/operate/kako/1103/11034/1103495887.html を発見しました。」<>過去ログ発見![改行]"
                     if (preg_match('/<>過去ログ発見!/', $body2)) {
                         //$reason = 'kakologsoko';
                     } elseif (preg_match('/過去ログ ★<>/', $body2)) {
                         $reason = 'datochi';
                     }
                     $this->downloadDat2chNotFound($reason);
                     return false;
                 }
             }
             $this->downloadDat2chNotFound();
             return false;
         }
         // Not Modified
     } elseif ($code == '304') {
         fclose($fp);
         $this->isonline = true;
         return '304 Not Modified';
         // Requested Range Not Satisfiable
     } elseif ($code == '416') {
         //echo "あぼーん検出";
         fclose($fp);
         $this->clearOnbytesModified();
         return $this->downloadDat2ch(0);
         // あぼーんを検出したので全部取り直し。
         // 予期しないHTTPコード。スレッドがないと判断
     } else {
         fclose($fp);
         $this->downloadDat2chNotFound();
         return false;
     }
     // }}}
     $r = $this->getOnbytesFromHeader($h['headers'], $zero_read);
     if ($r !== false) {
         $this->onbytes = $r;
     }
     if (isset($h['headers']['Last-Modified'])) {
         $this->modified = $h['headers']['Last-Modified'];
     }
     // bodyを読む
     $body = '';
     while (!feof($fp)) {
         $body .= fread($fp, 8192);
     }
     fclose($fp);
     // 末尾の改行であぼーんをチェックする
     if (!$zero_read) {
         if (substr($body, 0, 1) != "\n") {
             //echo "あぼーん検出";
             $this->clearOnbytesModified();
             return $this->downloadDat2ch(0);
             // あぼーんを検出したので全部取り直し。
         }
         $body = substr($body, 1);
     }
     FileCtl::make_datafile($this->keydat, $_conf['dat_perm']);
     $done = false;
     if ($fp = fopen($this->keydat, 'rb+')) {
         flock($fp, LOCK_EX);
         if (0 === fseek($fp, $from_bytes)) {
             if (false !== fwrite($fp, $body)) {
                 ftruncate($fp, $from_bytes + strlen($body));
                 $done = true;
             }
         }
         flock($fp, LOCK_UN);
         fclose($fp);
     }
     if (!$done) {
         trigger_error('cannot write file (' . $this->keydat . ')', E_USER_WARNING);
         die('Error: cannot write file. downloadDat2ch()');
         return false;
     }
     // {{{ 取得後サイズチェック
     $debug && $GLOBALS['profiler']->enterSection('dat_size_check');
     if ($zero_read == false && $this->onbytes) {
         $this->getDatBytesFromLocalDat();
         // $aThread->length をset
         if ($this->onbytes != $this->length) {
             $onbytes = $this->onbytes;
             $this->clearOnbytesModified();
             P2Util::pushInfoHtml("p2 info: {$onbytes}/{$this->length} ファイルサイズが変なので、datを再取得しました<br>");
             $debug && $GLOBALS['profiler']->leaveSection('dat_size_check');
             return $this->downloadDat2ch(0);
             // datサイズは不正。全部取り直し。
         }
     }
     $debug && $GLOBALS['profiler']->leaveSection('dat_size_check');
     // }}}
     $this->isonline = true;
     return true;
     /*
     あぼーん検出漏れについて
     
     0. p2が読み込む 
     1. レスがあぼーんされる 
     2. (あぼーんされたレス-あぼーんテキスト)と全く同サイズのレスが書き込まれる 
     3. p2が読み込む 
     
     0-1-2-3が、完全に連続した時にあぼーん検出漏れはありうる。 
     */
 }
Example #3
0
 /**
  * SETTING.TXT をダウンロードして、パースして、キャッシュする
  *
  * @return boolean 実行成否
  */
 public function downloadSettingTxt()
 {
     global $_conf;
     // まちBBS・したらば は SETTING.TXT が存在しないものとする
     if (P2Util::isHostMachiBbs($this->_host) || P2Util::isHostJbbsShitaraba($this->_host)) {
         return false;
     }
     FileCtl::mkdirFor($this->_setting_txt);
     // 板ディレクトリが無ければ作る
     if (file_exists($this->_setting_srd) && file_exists($this->_setting_txt)) {
         // 更新しない場合は、その場で抜けてしまう
         if (!empty($_GET['norefresh']) || isset($_REQUEST['word'])) {
             return true;
             // キャッシュが新しい場合も抜ける
         } elseif ($this->isCacheFresh()) {
             return true;
         }
         $modified = http_date(filemtime($this->_setting_txt));
     } 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->_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) {
                 $aNewSettingTxt = new SettingTxt($new_host, $this->_bbs);
                 $body = $aNewSettingTxt->downloadSettingTxt();
                 return true;
             }
         }
         if (!($code == 200 || $code == 206 || $code == 304)) {
             //var_dump($req->getResponseHeader());
             $error_msg = $code;
         }
     }
     // DLエラー
     if (isset($error_msg) && strlen($error_msg) > 0) {
         $url_t = P2Util::throughIme($this->_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->_url}</a> に接続できませんでした。</p>";
         P2Util::pushInfoHtml($info_msg_ht);
         touch($this->_setting_txt);
         // DL失敗した場合も touch
         return false;
     }
     $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->_setting_txt, $body) === false) {
             p2die('cannot write file');
         }
         // パースしてキャッシュを保存する
         if (!$this->cacheParsedSettingTxt()) {
             return false;
         }
     } else {
         // touchすることで更新インターバルが効くので、しばらく再チェックされなくなる
         touch($this->_setting_txt);
         // 同時にキャッシュもtouchしないと、_setting_txtと_setting_srdで更新時間がずれ、
         // 毎回ここまで処理が来る(サーバへのヘッダリクエストが飛ぶ)場合がある。
         touch($this->_setting_srd);
     }
     return true;
 }
Example #4
0
 /**
  * 標準方法で 2ch互換 DAT を差分ダウンロードする
  *
  * @return mix 取得できたか、更新がなかった場合はtrueを返す
  */
 protected function _downloadDat2ch($from_bytes)
 {
     global $_conf;
     global $debug;
     if (!($this->host && $this->bbs && $this->key)) {
         return false;
     }
     $from_bytes = intval($from_bytes);
     if ($from_bytes == 0) {
         $zero_read = true;
     } else {
         $zero_read = false;
         $from_bytes = $from_bytes - 1;
     }
     $method = 'GET';
     $url = "http://{$this->host}/{$this->bbs}/dat/{$this->key}.dat";
     //$url="http://news2.2ch.net/test/read.cgi?bbs=newsplus&key=1038486598";
     $purl = parse_url($url);
     // URL分解
     if (isset($purl['query'])) {
         // クエリー
         $purl['query'] = '?' . $purl['query'];
     } else {
         $purl['query'] = '';
     }
     // プロキシ
     if ($_conf['proxy_use']) {
         $send_host = $_conf['proxy_host'];
         $send_port = $_conf['proxy_port'];
         $send_path = $url;
     } else {
         $send_host = $purl['host'];
         $send_port = isset($purl['port']) ? $purl['port'] : 80;
         $send_path = $purl['path'] . $purl['query'];
     }
     if (!$send_port) {
         $send_port = 80;
         // デフォルトを80
     }
     $request = "{$method} {$send_path} HTTP/1.0\r\n";
     $request .= "Host: {$purl['host']}\r\n";
     $request .= "Accept: */*\r\n";
     //$request .= "Accept-Charset: Shift_JIS\r\n";
     //$request .= "Accept-Encoding: gzip, deflate\r\n";
     $request .= "Accept-Language: ja, en\r\n";
     $request .= "User-Agent: Monazilla/1.00 ({$_conf['p2ua']})\r\n";
     if (!$zero_read) {
         $request .= "Range: bytes={$from_bytes}-\r\n";
     }
     $request .= "Referer: http://{$purl['host']}/{$this->bbs}/\r\n";
     if ($this->modified) {
         $request .= "If-Modified-Since: " . $this->modified . "\r\n";
     }
     // Basic認証用のヘッダ
     if (isset($purl['user']) && isset($purl['pass'])) {
         $request .= "Authorization: Basic " . base64_encode($purl['user'] . ":" . $purl['pass']) . "\r\n";
     }
     $request .= "Connection: Close\r\n";
     $request .= "\r\n";
     // WEBサーバへ接続
     $fp = @fsockopen($send_host, $send_port, $errno, $errstr, $_conf['http_conn_timeout']);
     if (!$fp) {
         self::_pushInfoConnectFailed($url, $errno, $errstr);
         $this->diedat = true;
         return false;
     }
     stream_set_timeout($fp, $_conf['http_read_timeout'], 0);
     $wr = "";
     fputs($fp, $request);
     $start_here = false;
     while (!p2_stream_eof($fp, $timed_out)) {
         if ($start_here) {
             if ($code == "200" || $code == "206") {
                 while (!p2_stream_eof($fp, $timed_out)) {
                     $wr .= fread($fp, 4096);
                 }
                 if ($timed_out) {
                     self::_pushInfoReadTimedOut($url);
                     $this->diedat = true;
                     fclose($fp);
                     return false;
                 }
                 // 末尾の改行であぼーんチェック
                 if (!$zero_read) {
                     if (substr($wr, 0, 1) != "\n") {
                         //echo "あぼーん検出";
                         fclose($fp);
                         unset($this->onbytes);
                         unset($this->modified);
                         return $this->_downloadDat2ch(0);
                         // あぼーん検出。全部取り直し。
                     }
                     $wr = substr($wr, 1);
                 }
                 FileCtl::make_datafile($this->keydat, $_conf['dat_perm']);
                 $file_append = $zero_read ? 0 : FILE_APPEND;
                 if (FileCtl::file_write_contents($this->keydat, $wr, $file_append) === false) {
                     p2die('cannot write file.');
                 }
                 //$GLOBALS['debug'] && $GLOBALS['profiler']->enterSection("dat_size_check");
                 // 取得後サイズチェック
                 if ($zero_read == false && $this->onbytes) {
                     $this->getDatBytesFromLocalDat();
                     // $aThread->length をset
                     if ($this->onbytes != $this->length) {
                         fclose($fp);
                         unset($this->onbytes);
                         unset($this->modified);
                         P2Util::pushInfoHtml("<p>rep2 info: {$this->onbytes}/{$this->length} ファイルサイズが変なので、datを再取得</p>");
                         //$GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection("dat_size_check");
                         return $this->_downloadDat2ch(0);
                         //datサイズは不正。全部取り直し。
                         // サイズが同じならそのまま
                     } elseif ($this->onbytes == $this->length) {
                         fclose($fp);
                         $this->isonline = true;
                         //$GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('dat_size_check');
                         return true;
                     }
                 }
                 //$GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('dat_size_check');
                 // スレッドがないと判断
             } else {
                 fclose($fp);
                 return $this->_downloadDat2chNotFound();
             }
         } else {
             $l = fgets($fp, 32800);
             // ex) HTTP/1.1 304 Not Modified
             if (preg_match("/^HTTP\\/1\\.\\d (\\d+) (.+)\r\n/", $l, $matches)) {
                 $code = $matches[1];
                 if ($code == "200" || $code == "206") {
                     // Partial Content
                 } elseif ($code == "302") {
                     // Found
                     // ホストの移転を追跡
                     $new_host = BbsMap::getCurrentHost($this->host, $this->bbs);
                     if ($new_host != $this->host) {
                         fclose($fp);
                         $this->old_host = $this->host;
                         $this->host = $new_host;
                         return $this->_downloadDat2ch($from_bytes);
                     } else {
                         fclose($fp);
                         return $this->_downloadDat2chNotFound($code);
                     }
                 } elseif ($code == "304") {
                     // Not Modified
                     fclose($fp);
                     $this->isonline = true;
                     return "304 Not Modified";
                 } elseif ($code == "416") {
                     // Requested Range Not Satisfiable
                     //echo "あぼーん検出";
                     fclose($fp);
                     unset($this->onbytes);
                     unset($this->modified);
                     return $this->_downloadDat2ch(0);
                     // あぼーん検出。全部取り直し。
                 } else {
                     fclose($fp);
                     return $this->_downloadDat2chNotFound();
                 }
             }
             if ($zero_read) {
                 if (preg_match("/^Content-Length: ([0-9]+)/", $l, $matches)) {
                     $this->onbytes = $matches[1];
                 }
             } else {
                 if (preg_match("/^Content-Range: bytes ([^\\/]+)\\/([0-9]+)/", $l, $matches)) {
                     $this->onbytes = $matches[2];
                 }
             }
             if (preg_match("/^Last-Modified: (.+)\r\n/", $l, $matches)) {
                 //echo $matches[1]."<br>"; //debug
                 $this->modified = $matches[1];
             } elseif ($l == "\r\n") {
                 $start_here = true;
             }
         }
     }
     fclose($fp);
     if ($timed_out) {
         self::_pushInfoReadTimedOut($url);
         $this->diedat = true;
         return false;
     } else {
         $this->isonline = true;
         return true;
     }
 }
Example #5
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;
 }
Example #6
0
 /**
  * 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;
 }