/** * 2chの過去ログ倉庫からdat.gzをダウンロード&解凍する * * @access private * @return true|string|false 取得できたか、更新がなかった場合はtrue(または"304 Not Modified")を返す */ function downloadDat2chKako($uri, $ext) { global $_conf; $url = $uri . $ext; $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']; } // デフォルトを80 if (!$send_port) { $send_port = 80; } $request = 'GET ' . $send_path . " HTTP/1.0\r\n"; $request .= "Host: " . $purl['host'] . "\r\n"; $request .= "User-Agent: " . P2Util::getP2UA($withMonazilla = true) . "\r\n"; $request .= "Connection: Close\r\n"; //$request .= "Accept-Encoding: gzip\r\n"; /* if ($modified) { $request .= "If-Modified-Since: $modified\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']; // Partial Content if ($code == "200") { // OK。何もしない // Not Modified } elseif ($code == "304") { fclose($fp); //$this->isonline = true; return "304 Not Modified"; // 予期しないHTTPコード。なかったと判断 } else { fclose($fp); $this->downloadDat2chKakoNotFound($uri, $ext); return false; } // }}} if (isset($h['headers']['Last-Modified'])) { $lastmodified = $h['headers']['Last-Modified']; } if (isset($h['headers']['Content-Length'])) { if (preg_match("/^([0-9]+)/", $h['headers']['Content-Length'], $matches)) { $onbytes = $h['headers']['Content-Length']; } } $isGzip = false; if (isset($h['headers']['Content-Encoding'])) { if (preg_match("/^(x-)?gzip/", $h['headers']['Content-Encoding'], $matches)) { $isGzip = true; } } // bodyを読む $body = ''; while (!feof($fp)) { $body .= fread($fp, 8192); } fclose($fp); $done_gunzip = false; if ($isGzip) { $gztempfile = $this->keydat . '.gz'; FileCtl::mkdirFor($gztempfile); if (file_put_contents($gztempfile, $body, LOCK_EX) === false) { die("Error: cannot write file. downloadDat2chKako()"); return false; } if (extension_loaded('zlib')) { $body = FileCtl::getGzFileContents($gztempfile); } else { // 既に存在するなら一時バックアップ退避 $keydat_bak = $this->keydat . '.bak'; if (file_exists($this->keydat)) { if (file_exists($keydat_bak)) { unlink($keydat_bak); } rename($this->keydat, $keydat_bak); } $rcode = 1; // 解凍 system("gzip -d {$gztempfile}", $rcode); if ($rcode != 0) { if (file_exists($keydat_bak)) { if (file_exists($this->keydat)) { unlink($this->keydat); } // 失敗ならバックアップ戻す rename($keydat_bak, $this->keydat); } $this->pushDownloadDatErrorMsgHtml("<p>p2 info - 2ちゃんねる過去ログ倉庫からのスレッド取り込みは、PHPの<a href=\"http://www.php.net/manual/ja/ref.zlib.php\">zlib拡張モジュール</a>がないか、systemでgzipコマンドが使用可能\でなければできません。</p>"); // gztempファイルを捨てる file_exists($gztempfile) and unlink($gztempfile); $this->diedat = true; return false; } else { if (file_exists($keydat_bak)) { unlink($keydat_bak); } $done_gunzip = true; } } // tempファイルを捨てる file_exists($gztempfile) and unlink($gztempfile); } if (!$done_gunzip) { FileCtl::make_datafile($this->keydat, $_conf['dat_perm']); if (false === file_put_contents($this->keydat, $body, LOCK_EX)) { die("Error: cannot write file. downloadDat2chKako()"); return false; } } //$this->isonline = true; return true; }