Published using Google Docs
HTTP Cache tables

HTTP Cache tables

캐시의 종류

Browser Caches

Proxy Caches

Gateway Caches

ex) Internet Explorer, Safari or Mozilla

 

ex) Speedera and Akamai.

캐시의 2가지 동작

요구(Request) 발송을 생략

응답(Response) 발송을 생략

(좌동)

만기일 메커니즘

검증 메커니즘 (강한 검증자)

검증 메커니즘 (약한 검증자)

 

강한 검증자: 엔터티의 일부가 바뀌면 바뀜.

ex: eTag

하지만 약한 검증자도 될 수도 있음(ex: ETag: W/"xyzzy").

약한 검증자: 엔터티의 의미가 바뀌면 바뀜.

ex: Last-Modified (1초에 2회 이상 변경 가능하기 때문)

하지만 상황에 따라 강한 것으로 볼 수도 있음.

 

강한 비교 요구는 모든 경우에 사용.

약한 비교 기능은 간단한 (하부 영역이 아닌) GET 요구에 사용 가능.

 

서버가 ETag를 제공하였으면 클라이언트는 어떠한 Cache-Conditional 요구에서든지 그 엔터티 태그를 반드시 사용(If-Match 또는 If-None-Match를 사용).

서버가 Last-Modified를 제공했을 때 클라이언트는 하부 영역이 아닌 Cache-Conditional 요구에 그 값을 사용 가능(If-Modified-Since를 사용).

Cache-Control 지시자 "max-age" 나 Expires 가 있으면,

해당 값으로 만기일 메커니즘을 수행.

모두 응답 헤더에 없으면 제약사항이 없으므로,

캐시가 Last-Modified 등을 참조하여 정할 수도 있음(Heuristic Expiration).

클라이언트나 프록시 캐시가 검증자를 포함해서 조건적인 요구를 하면 서버는 검증자를 점검하여 304와 비어있는 body를 응답.

(좌동)

 

RFC에 따르면 HTTP/1.1 원서버의 바람직한 행태는 강한 엔터티 태그와 Last-Modified 값 모두를 발송하는 것.

(좌동)

 

모든 요구를 검증하게 할려면 Cache-Control 지시자 "must-revalidate".

(좌동)

브라우저의 GET 동작의 예 (환경설정에 따라 캐시를 제외시킬 수 있음)

  1. 서버가 만기일과 검증자중 아무것도 제공하지 않았을 경우
  1. 서버가 만기일만 제공하였을 경우

header('Cache-Control: max-age=60');

  1. 서버가 검증자중 ETag 만 제공하였을 경우

header('ETag: "korea"');

  1. 서버가 검증자중 Last-Modified 만 제공하였을 경우

header('Last-Modified: Mon, 16 Aug 2010 10:30:00 GMT');

  1. 서버가 만기일과 검증자 두가지 모두 제공하였을 경우

header('Cache-Control: max-age=10');
header('ETag:
"korea"');
header('Last-Modified: Mon, 16 Aug 2010 10:32:12 GMT');

일반적으로 브라우저의 POST 동작에서는 캐시 메커니즘을 사용하지 않는다.

캐시 관련 헤더들

분류

헤더

설명

예제

지원버전

상용

Date

메시지가 생성되었을 때의 날짜와 시간.

캐시 시간 계산에 필요함.

Date: Tue, 15 Nov 1994 08:12:31 GMT

1.0 and 1.1

상용

Pragma

캐시 제어. HTTP/1.1의 no-cache cache-directive 와 동일한 의미.

HTTP/1.0과의 호환성 유지를 위해 규정.

Pragma: no-cache

1.0

상용

Cache-Control

캐시 제어(자세한 내용은 다음 단락에).

Cache-Control: max-age=7776000

1.1

상용

Expires

자원의 만기 날짜.

해당 날짜/시간이 지나지 않은 것은 유효하다고 볼 수 있다.

1.1 에서는 Expires보다 Cache-Control의 max-age 지시자가 우선권을 갖음.

Expires: Sun, 14 Nov 2010 04:09:33 GMT

1.0 and 1.1

상용

Last-Modified

가장 최근에 수정된 날짜.

Last-Modified: Thu, 01 Dec 1994 16:00:00 GMT

1.0 and 1.1

상용

ETag

캐시 업데이트 정보를 위한 임의의 식별자.

Entity-Tag 라고 불리며 If-Match,If-None-Match,If-Range 에서 사용됨.

L4로 묶여있을 경우 서버가 다르기 때문에 같은 URI,반환 내용이라도 항상 문자열이 다를 수 있다.

ETag: "0-556-343b9e36"

1.1

요청

If-Modified-Since

요청 필드. GET 메소드를 조건적으로 만듬.

헤더 필드에 지정된 날짜보다 나중 자원만 전달(캐시일자검색).

서버의 시간보다 미래면 무시, 200이 아니면 무시, 해당 시간 이후에 변경되었으면 무시.

그렇지 않으면 304 (Not Modified) 응답.

If-Modified-Since: Tue, 15 Nov 1994 12:45:26 GMT

1.0 and 1.1

요청

If-Match

ETag값을 비교하여 Method를 수행.

클라이언트에서 보낸 eTag가 리소스 업데이트를 위해 서버에서 보유하고 있는 eTag와 일치하면 작업 수행.

일치하지 않으면 402 에러.

서버는 엔터티 태그를 비교하기 위하여 반드시 강한 비교 기능 사용.

If-Match: "0-556-343b9e36"

If-None-Match: *

1.1

요청

If-None-Match

ETag값을 비교하여 다를때 Method를 수행(If-Match와 반대).

GET 요청의 경우 새 HTTP 응답에 이전 HTTP 응답과 동일한 eTag가 포함되어 있으면, 콘텐츠가 변경되지 않았다고 간주하고 추가 다운로드가 수행되지 않음.

GET 이나 HEAD Method일 경우 304 (Not Modified), 다른 Method일 경우 412 (Precondition Failed).

If-None-Match: "0-556-343b9e36","0-1e4-34367116"

If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"

If-None-Match: *

1.1

요청

If-Range

엔터티가 변경되지 않았다면 필요한 부분만을 발송하고, 그렇지 않다면 새로운 전체 엔터티를 발송.

엔터티 태그가 엔터티의 현재 엔터티 태그와 일치하면 서버는 206 (Partial content).

일치하지 않으면 200 (OK).

If-Range: "0-556-343b9e36"

If-Range: Sat, 29 Oct 1994 19:43:31 GMT

1.1

요청

If-Unmodified-Since

지정된 날짜 이후에 변경되지 않았다면 필요한 부분만을 발송하고, 그렇지 않다면 412 (Precondition Failed).

If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT

1.1

응답

Age

원서버가 응답(또는 이의 검증)을 생성한 이후 시간에 대한 발송자의 예상 값(초).

캐시된 응답은 경과 시간이 신선한 시간(freshness lifetime)을 초과하지 않았으면 "신선하다."고 볼 수 있음.

Cache-Control 헤더의 max-age 지시자를 통해 만기일을 구할 때 이 값을 빼서 계산하게 됨

Age: 166

1.1

응답

Warning

대개 캐시 작업에 발생할 수 있는 의미 투명성(semantic transparency)의 결여에 대한 경고를 나타냄.

Warning: 10 Response is stale

Warning: 11 Revalidation failed

1.1

Cache-Control 헤더의 주요 지시자들

분류

지시자

설명

상용

cache-directive

단방향을 나타냄.

HTTP request에 지정된 cache directive가 response에도 동일하게 있어야 하는 것은 아님을 의미.

상용

no-cache

응답의 전체 또는 부분을 캐시해서는 안된다는 것을 나타냄.

원서버가 클라이언트 요구에 낡은 응답(stale response)을 리턴하도록 설정된 캐시에 의해서도 캐시를 하지 못하도록 합니다.

상용

no-store

민감한 정보이니 캐시서버가 가지지말아달라 부탁.

상용

max-age = sec

유효시간을 지정. 지정한 시간보다 오래되지 않은 응답은 걍 씀.

헤더의 Age 값이 있으면 그 값을 뺀 값을 사용하게 됨.

max-stale 지시자가 지정되지 않으면 이보다 오래된 캐시를 쓰지 않음.

요청

max-stale [ = sec ]

유효 시간을 초과한 응답을 씀.

초가 지정되어 있으면 지정된 시간을 초과하지 않은 응답을 그냥 씀.

초가 지정되어 있지 않으면 오래된 것도 그냥 씀.

요청

min-fresh = sec

지정된 시간까지는 캐시를 사용. 초로 표시된 시간 이후에 변경된 캐시를 요구.

요청

only-if-cached

캐시가 있으면 검증하지 말고 캐시를 달라고 요청.

응답

public

모든 공유/비공유 캐시에서 응답을 캐시할 수 있도록 지정.

보통 HTTP authentication 같은 요청은 자동으로 private 응답됨.

응답

private [ = 이름 ]

응답 메시지의 전체 또는 일부분을 단일 사용자만이 사용하며, 공유 캐시(shared cache)에 의해 캐시해서는 안됨을 표시.

원서버가 응답의 특정 부분이 단일 사용자만을 위한 것이며 다른 사용자의 요구에 대한 유효한 응답은 아니라는 것을 명시.

응답

no-transform

응답이 no-transform 지시자를 포함하고 있으면 중간 캐시나 프록시는 데이타를 변경해서는 안됨.

특히 Content-Encoding, Content-Length, Content-Range, Content-Type와 같은 헤더 필드 값을 절대로 변경해서는 안됨을 나타냄.

응답

must-revalidate

클라이언트는 데이터를 재확인 해야한다고 알려줌.

요거는 캐시가 신선하지 않으면 max-stale 등으로 수작부리기 없기. 무조건 재검증!

응답

proxy-revalidate

개인적인 클라이언트 캐시를 제외한 캐시(프록시 캐시 등)는 데이터를 재확인 해야함.

요거는 must-revalidate와 같은 의미이나, 프록시에만 적용.

응답

s-maxage = sec

max-age 와 비슷하나, 공유 캐시(프록시 캐시 등)에만 적용.

응답 헤더 구현의 예

내용

코드

비고

항상 새로 받기

header('Pragma: no-cache');
header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
header('Cache-Control: max-age = 0, no-cache');

Pragma 와 Expires 는 1.0 과 호환을 위함.

만기일 메커니즘의 구현

header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
header('Cache-Control: max-age = 3600');

일반적인 경우 1시간 동안 재요청하지 않게됨.

검증 메커니즘의 구현

header('Content-Type: image/png');
$requestMTime = @$_SERVER['HTTP_IF_MODIFIED_SINCE'];
$fileMTime = gmdate('D, d M Y H:i:s', filemtime('./test.png')) . ' GMT';
if ($requestMTime == $fileMTime) {
        header('HTTP/1.1 304 Not Modified');
}
else {
        header('Last-Modified: ' . $fileMTime);
        readfile('./test.png');
}

받은 헤더의 If-Modified-Since 값과 파일의 수정 날짜가 같으면 파일 내용을 보내지 않음.

 

ETag도 비슷한 방식으로 구현가능하다(hash_file() 등 함수 이용).

참고 :

Caching Tutorial http://www.mnot.net/cache_docs/

Bypass your cache http://en.wikipedia.org/wiki/Wikipedia:Bypass_your_cache