반응형
php는 중단점 속행을 지원하며, 주로 HTTP 프로토콜의 header HTTP_RANGE에 의해 구현됩니다.
HTTP 중단점 속행 원리
HTTP 헤더 Range, Content-Range( )
HTTP 헤더 중 일반적으로 중단점 다운로드 시에만 Range 및 Content-Range 엔티티 헤더를 사용합니다.
Range 사용자 요청 헤더에서 첫 번째 바이트의 위치와 마지막 바이트의 위치를 지정합니다. (Range: 200)-300)
Content-Range는 응답 헤더에 사용됩니다.
전체 파일 다운로드 요청:
GET/test.rar HTTP/1.1
Connection: close
Host: 116.1.219.219.
Range: bytes=0-801 // 전체 파일 다운로드 요청은 bytes=0- 또는 사용하지 않음이 부분
일반 정상 응답
HTTP/1.1 200 OK
Content-Length:801
Content-Type: application/octet-stream
Content-Range: bytes 0-800/801 //801:파일 총크기
FileDownload.class.php
<?php
/**php 다운로드 클래스, 중단점 속행 지원
* Date: 2013-06-30
* Author: fdipzone
* Ver: 1.0
*
* Func:
* download: 파일 다운로드
* setSpeed: 다운로드 속도 설정
* getRange: header에서 Range
*/
class FileDownload{ // class start
private $_speed = 512; // 다운로드 속도
/** 다운로드
* @param String $file 다운로드할 파일 경로
* @param String $name 파일 이름, 비어 있으면 다운로드한 파일 이름과 같습니다
* @param boolean $reload 중단점 속행 설정 여부
*/
public function download($file, $name='', $reload=false){
if(file_exists($file)){
if($name==''){
$name = basename($file);
}
$fp = fopen($file, 'rb');
$file_size = filesize($file);
$ranges = $this->getRange($file_size);
header('cache-control:public');
header('content-type:application/octet-stream');
header('content-disposition:attachment; filename='.$name);
if($reload && $ranges!=null){ // 속전 사용
header('HTTP/1.1 206 Partial Content');
header('Accept-Ranges:bytes');
// 잔장
header(sprintf('content-length:%u',$ranges['end']-$ranges['start']));
//레인지 정보
header(sprintf('content-range:bytes %s-%s/%s', $ranges['start'], $ranges['end'], $file_size));
// fp 포인터가 중단점 위치로 이동
fseek($fp, sprintf('%u', $ranges['start']));
}else{
header('HTTP/1.1 200 OK');
header('content-length:'.$file_size);
}
while(!feof($fp)){
echo fread($fp, round($this->_speed*1024,0));
ob_flush();
//sleep(1); // 테스트에 사용, 다운로드 속도 감소
}
($fp!=null) && fclose($fp);
}else{
return '';
}
}
/** 다운로드 속도 설정
* @param int $speed
*/
public function setSpeed($speed){
if(is_numeric($speed) && $speed>16 && $speed<4096){
$this->_speed = $speed;
}
}
/** 헤더 레인지 정보 가져오기
* @param int $file_size 파일 크기
* @return Array
*/
private function getRange($file_size){
if(isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])){
$range = $_SERVER['HTTP_RANGE'];
$range = preg_replace('/[\s|,].*/', '', $range);
$range = explode('-', substr($range, 6));
if(count($range)<2){
$range[1] = $file_size;
}
$range = array_combine(array('start','end'), $range);
if(empty($range['start'])){
$range['start'] = 0;
}
if(empty($range['end'])){
$range['end'] = $file_size;
}
return $range;
}
return null;
}
} // class end
?>
demo
<?php
require('FileDownload.class.php');
$file = 'book.zip';
$name = time().'.zip';
$obj = new FileDownload();
$flag = $obj->download($file, $name);
//$flag = $obj->download($file, $name, true); //중단점 속전
if(!$flag){
echo 'file not exists';
}
?>
중단점 속행 테스트 방법:
리눅스 wg 사용et 명령 다운로드 테스트하기, wget-c-O file http://xxx
1.먼저 중단점 속행하기
$flag = $obj->download ($file, $name)
fdipzone@ubuntu:~/Downloads$ wget -O test.rar http://demo.fdipzone.com/demo.php
--2013-06-30 16:52:44-- http://demo.fdipzone.com/demo.php
호스트 구문 분석 중 demo.fdipzone.com... 127.0.0.1
연결 중 demo.fdipzone.com|127.0.0.1|:80... 연결됨。
HTTP 요청, 응답 대기 중... 200 OK
길이: 10445120 (10.0M) [application/octet-stream]
저장 중: “test.rar”
30% [============================> ] 3,146,580 513K/s 시기를 가늠하다 14s
^C
fdipzone@ubuntu:~/Downloads$ wget -c -O test.rar http://demo.fdipzone.com/demo.php
--2013-06-30 16:52:57-- http://demo.fdipzone.com/demo.php
호스트 구문 분석 중 demo.fdipzone.com... 127.0.0.1
연결 중 demo.fdipzone.com|127.0.0.1|:80... 연결됨。
HTTP 요청, 응답 대기 중... 200 OK
길이: 10445120 (10.0M) [application/octet-stream]
저장 중: “test.rar”
30% [============================> ] 3,146,580 515K/s 시기를 가늠하다 14s
^C
볼 수 있습니다. wget-c는 간헐적으로 전송할 수 없습니다
2.브레이크 포인트 속행 열기
$flag = $obj->download ($file, $name, true)
fdipzone@ubuntu:~/Downloads$ wget -O test.rar http://demo.fdipzone.com/demo.php
--2013-06-30 16:53:19-- http://demo.fdipzone.com/demo.php
호스트 구문 분석 중 demo.fdipzone.com... 127.0.0.1
연결됨 demo.fdipzone.com|127.0.0.1|:80... 연결됨v。
HTTP 요청, 응답 대기 중... 200 OK
길이: 10445120 (10.0M) [application/octet-stream]
저장 중: “test.rar”
20% [==================> ] 2,097,720 516K/s 시기를 가늠하다 16s
^C
fdipzone@ubuntu:~/Downloads$ wget -c -O test.rar http://demo.fdipzone.com/demo.php
--2013-06-30 16:53:31-- http://demo.fdipzone.com/demo.php
호스트 구문 분석 중 demo.fdipzone.com... 127.0.0.1
연결 중 demo.fdipzone.com|127.0.0.1|:80... 연결됨。
HTTP 요청, 응답 대기 중... 206 Partial Content
길이: 10445121 (10.0M),7822971 (7.5M) 바이트 잉여 [application/octet-stream]
저장 중: “test.rar”
100%[++++++++++++++++++++++++=========================================================================>] 10,445,121 543K/s 시기를 가늠하다 14s
2013-06-30 16:53:45 (543 KB/s) - 저장됨 “test.rar” [10445121/10445121])
중단점 위치(%20)부터 다운로드를 시작하는 것을 볼 수 있습니다。
반응형
'개발 꿀팁 > PHP' 카테고리의 다른 글
PHP 트래버스 폴더 및 파일류 및 처리류 (0) | 2022.08.17 |
---|---|
php 필터 HTML 태그 속성 클래스 (0) | 2022.08.17 |
php redis 잠금을 사용하여 동시 액세스 제한 (0) | 2022.08.17 |
php redis 카운터 기반 (0) | 2022.08.17 |
php 로고 QR 클래스 만들기 (0) | 2022.08.16 |