/** * Downloads a GeoIP database archive, extracts the .dat file and overwrites the existing * old database. * * If something happens that causes the download to fail, no exception is thrown, but * an error is logged. * * @param string $dbType * @param string $url URL to the database to download. The type of database is determined * from this URL. * @throws Exception */ protected function downloadFile($dbType, $url) { $ext = GeoIPAutoUpdater::getGeoIPUrlExtension($url); // NOTE: using the first item in $dbNames[$dbType] makes sure GeoLiteCity will be renamed to GeoIPCity $zippedFilename = GeoIp::$dbNames[$dbType][0] . '.' . $ext; $zippedOutputPath = GeoIp::getPathForGeoIpDatabase($zippedFilename); $url = self::removeDateFromUrl($url); // download zipped file to misc dir try { $success = Http::sendHttpRequest($url, $timeout = 3600, $userAgent = null, $zippedOutputPath); } catch (Exception $ex) { throw new Exception("GeoIPAutoUpdater: failed to download '{$url}' to " . "'{$zippedOutputPath}': " . $ex->getMessage()); } if ($success !== true) { throw new Exception("GeoIPAutoUpdater: failed to download '{$url}' to " . "'{$zippedOutputPath}'! (Unknown error)"); } Log::info("GeoIPAutoUpdater: successfully downloaded '%s'", $url); try { self::unzipDownloadedFile($zippedOutputPath, $unlink = true); } catch (Exception $ex) { throw new Exception("GeoIPAutoUpdater: failed to unzip '{$zippedOutputPath}' after " . "downloading " . "'{$url}': " . $ex->getMessage()); } Log::info("GeoIPAutoUpdater: successfully updated GeoIP database '%s'", $url); }
/** * Starts or continues a download for a missing GeoIP database. A database is missing if * it has an update URL configured, but the actual database is not available in the misc * directory. * * Input: * 'url' - The URL to download the database from. * 'continue' - 1 if we're continuing a download, 0 if we're starting one. * * Output: * 'error' - If an error occurs this describes the error. * 'to_download' - The URL of a missing database that should be downloaded next (if any). * 'to_download_label' - The label to use w/ the progress bar that describes what we're * downloading. * 'current_size' - Size of the current file on disk. * 'expected_file_size' - Size of the completely downloaded file. */ public function downloadMissingGeoIpDb() { $this->dieIfGeolocationAdminIsDisabled(); Piwik::checkUserHasSuperUserAccess(); if ($_SERVER["REQUEST_METHOD"] == "POST") { try { $this->checkTokenInUrl(); Json::sendHeaderJSON(); // based on the database type (provided by the 'key' query param) determine the // url & output file name $key = Common::getRequestVar('key', null, 'string'); $url = GeoIPAutoUpdater::getConfiguredUrl($key); $ext = GeoIPAutoUpdater::getGeoIPUrlExtension($url); $filename = GeoIp::$dbNames[$key][0] . '.' . $ext; if (substr($filename, 0, 15) == 'GeoLiteCity.dat') { $filename = 'GeoIPCity.dat' . substr($filename, 15); } $outputPath = GeoIp::getPathForGeoIpDatabase($filename); // download part of the file $result = Http::downloadChunk($url, $outputPath, Common::getRequestVar('continue', true, 'int')); // if the file is done if ($result['current_size'] >= $result['expected_file_size']) { GeoIPAutoUpdater::unzipDownloadedFile($outputPath, $unlink = true); $info = $this->getNextMissingDbUrlInfo(); if ($info !== false) { return json_encode($info); } } return json_encode($result); } catch (Exception $ex) { return json_encode(array('error' => $ex->getMessage())); } } }