2012-09-03 4 views
1

getimagesize()을 사용하여 이미지의 유효성을 검사 할 수 있지만 문제가있는 사용자가 10GB random file에 링크하면 내 프로덕션 서버의 대역폭이 줄어 듭니다. 파일 크기를 어떻게 제한합니까 getimagesize()가 나타 납니까? (예 : 최대 이미지 크기 5MB)getimagesize() 원격 URL에 대한 파일 크기 제한

PS : 묻기 전에 research을 사용했습니다.

+1

어쩌면이 사용 사례에 맞는 http://stackoverflow.com/questions/4635936/super-fast -getimagesize-in-php – Mike

답변

2

:

function mygetimagesize($url, $max_size = -1) 
{ 
     // create temporary file to store data from $url 
     if (false === ($tmpfname = tempnam(sys_get_temp_dir(), uniqid('mgis')))) { 
       return false; 
     } 
     // open input and output 
     if (false === ($in = fopen($url, 'rb')) || false === ($out = fopen($tmpfname, 'wb'))) { 
       unlink($tmpfname); 
       return false; 
     } 
     // copy at most $max_size bytes 
     stream_copy_to_stream($in, $out, $max_size); 

     // close input and output file 
     fclose($in); fclose($out); 

     // retrieve image information 
     $info = getimagesize($tmpfname); 

     // get rid of temporary file 
     unlink($tmpfname); 

     return $info; 
} 
+0

100 명의 사용자가 동시에 업로드하는 경우 안녕하세요, 'stream_copy_to_stream'에 메모리 문제가 있습니까? – Michelle

+0

@Severus 어떻게 상상할 수 있겠습니까? 내부적으로 그것은 8K 버퍼를 사용하여 내가 믿는 사본을 수행합니다. –

+0

@Severus가 더 구체적 일 수 있습니까? :) –

2

먼저 이미지를 다운로드하고 크기를 확인한 다음 다운로드 한 이미지 데이터를 삭제하므로 getimagesize('http://example.com')과 같은 것을하고 싶지는 않습니다. 그건 대역폭의 실제 낭비입니다.

그래서 다운로드 프로세스를 이미지 크기 검사와 분리하십시오. 예를 들어 fopen을 사용하여 이미지 URL을 열고 조금 읽은 다음 읽은 파일의 수를 유지하면서 임시 파일에 기록합니다. 5MB를 넘고 아직 읽지 못하면 이미지를 멈추고 거부합니다.

당신 분명 큰 파일을 걸러 낼 수있는 실제 다운로드를 시작하기 전에 HTTP 컨텐츠 크기의 헤더 을 읽으려고 수 있지만 스푸핑 또는 생략 할 수 있기 때문에 당신은 그것에 의존 할 수 없다.

2

여기는 example입니다. 요구 사항에 맞게 변경해야합니다.

function getimagesize_limit($url, $limit) 
{ 
global $phpbb_root_path; 
$tmpfilename = tempnam($phpbb_root_path . 'store/', unique_id() . '-'); 
    $fp = fopen($url, 'r'); 
if (!$fp) return false; 
$tmpfile = fopen($tmpfilename, 'w'); 
    $size = 0; 
while (!feof($fp) && $size<$limit) 
{ 
    $content = fread($fp, 8192); 
    $size += 8192; fwrite($tmpfile, $content); 
} 
    fclose($fp); 
fclose($tmpfile); 
    $is = getimagesize($tmpfilename); 
unlink($tmpfilename); 
return $is; 
} 
당신은 다운로드하고자하는 최대 크기 부과, 별도로 파일을 다운로드 할 수 있습니다
+0

왜 '8192'를 추가하는지 질문 할 수 있습니까? – Michelle

+0

@Severus 그것은 단지 8kb를 한 번 읽고 특별한 의미가없는 것을 의미합니다. – xdazz

+0

phpbb에서 어떤 파일이 구현 되었습니까? – Michelle