'*/*',
'user-agent' => 'mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0)',
'accept-encoding' => 'gzip, deflate',
'host' => $url_info['host'],
'connection' => 'close',
'accept-language' => 'zh-cn',
);
// merge heade
$headers = array_merge($def_headers, $headers);
// get content length
$content_length = self::get_content_size($url_info['host'], $url_info['port'], $url_info['request'], $headers, $timeout);
// content length not exist
if (!$content_length) {
throw new exception('content-length is not exists');
}
// get exists length
$exists_length = is_file($save_file) ? filesize($save_file) : 0;
// get tmp data file
$data_file = $save_file . '.data';
// get tmp data
$exists_data = is_file($data_file) ? json_decode(file_get_contents($data_file), 1) : array();
// check file is valid
if ($exists_length == $content_length) {
$exists_data && @unlink($data_file);
return true;
}
// check file is expire
if ($exists_data['length'] != $content_length || $exists_length > $content_length) {
$exists_data = array(
'length' => $content_length,
);
}
// write exists data
file_put_contents($data_file, json_encode($exists_data));
try {
$download_status = self::download_content($url_info['host'], $url_info['port'], $url_info['request'], $save_file, $content_length, $exists_length, $speed, $headers, $timeout);
if ($download_status) {
@unlink($data_file);
}
} catch (exception $e) {
throw new exception($e->getmessage());
}
return true;
}
/**
* parse url
*
* @param $url
* @return bool|mixed
*/
static function parse_url($url) {
$url_info = parse_url($url);
if (!$url_info['host']) {
return false;
}
$url_info['port'] = $url_info['port'] ? $url_info['host'] : 80;
$url_info['request'] = $url_info['path'] . ($url_info['query'] ? '?' . $url_info['query'] : '');
return $url_info;
}
/**
* download content by chunk
*
* @param $host
* @param $port
* @param $url_path
* @param $headers
* @param $timeout
*/
static function download_content($host, $port, $url_path, $save_file, $content_length, $range_start, $speed, &$headers, $timeout) {
$request = self::build_header('get', $url_path, $headers, $range_start);
$fsocket = @fsockopen($host, $port, $errno, $errstr, $timeout);
stream_set_blocking($fsocket, true);
stream_set_timeout($fsocket, $timeout);
fwrite($fsocket, $request);
$status = stream_get_meta_data($fsocket);
if ($status['timed_out']) {
throw new exception('socket connect timeout');
}
$is_header_end = 0;
$total_size = $range_start;
$file_fp = fopen($save_file, 'a+');
while (!feof($fsocket)) {
if (!$is_header_end) {
$line = @fgets($fsocket);
if (in_array($line, array(\n, \r\n))) {
$is_header_end = 1;
}
continue;
}
$resp = fread($fsocket, $speed);
$read_length = strlen($resp);
if ($resp === false || $content_length $hval) {
$out .= $hkey . ': ' . $hval . \r\n;
}
if ($range_start > -1) {
$out .= accept-ranges: bytes\r\n;
$out .= range: bytes={$range_start}-\r\n;
}
$out .= \r\n;
return $out;
}
}
#use age
/*
try {
if (downloader::get('http://dzs.aqtxt.com/files/11/23636/201604230358308081.rar', 'test.rar')) {
//todo
echo 'download succ';
}
} catch (exception $e) {
echo 'download failed';
}
*/
?>