캐시 시스템을 돌리고 있다고 가정하고,

용량이 큰 이미지라던가 바이너리 파일의 경우,

body를 포함한 전체 파일 데이터를 다 요청하지 않고, 

header만 요청하여 Last-Modified나 ETag 값을 기준으로 캐시를 엎을지 여부를 판별할 수 있음.



[참고]

HEAD : http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4

ETag : http://en.wikipedia.org/wiki/HTTP_ETag




// /cache 라는 디렉토리에 www.aaa.com/img 의 데이터를 캐시처리하고 있다고 가정

$cache_dir = '/cache';

foreach (glob($cache_dir.'/*') as $f) {

    $url = 'http://www.aaa.com/img/'.basename($f);


    // 캐시 ETag는 어딘가에 저장한다고 가정

    // filemitme을 바로 비교할 수 있도록 Last-Modified를 이용하는 게 훨 편할 듯...;;

    $cache_ETag = getCacheETag($f);


    // 캐시 만료

    if (checkExpiredByETag($url, $cache_ETag) === false) {

        // 캐시 갱신

    }

}


// 저장된 ETag와 $url response header의 ETag와 비교

function checkExpiredByETag($url, $cache_ETag)

{

    $header = getHeader($url);

    $ETag = getETagFromHeader($header);

    

    return $ETag == $cache_ETag;

}


// header에서 ETag만 추출

function getETagFromHeader($header)

{

    preg_match("/ETag: \"(.*?)\"/", $header, $matched);


    return $matched[1];

}


// header만 요청

function getHeader($url)

{

    $c = curl_init($url);

    curl_setopt($c, CURLOPT_RETURNTRANSFER, true);

    curl_setopt($c, CURLOPT_CUSTOMREQUEST, 'HEAD');

    curl_setopt($c, CURLOPT_HEADER, 1);

    curl_setopt($c, CURLOPT_NOBODY, true);

    $r = curl_exec($c);

    curl_close($c);


    return $r;

}














Posted by bloodguy
,