Cache-Control 메커니즘
HTTP/1.1의 기본적인 캐시 메커니즘(서버설정 만기시간 및 검증자)은 캐시에 내장된 지시자입니다. 때에 따라서는 서버나 클라이언트에게 HTTP 캐시를 위해 명시된 지시자 제공할 필요가 있습니다. Cache-Control 헤더를 이 목적으로 사용합니다.
Cache-Control 헤더는 클라이언트나 서버가 요구나 응답의 다양한 지시자를 전달할 수 있도록 합니다. 이 지시자는 대개의 경우 기본 캐시 알고리즘을 무시합니다. 보편적인 원칙으로 만약 헤더값 사이에 분명한 충돌이 있으면 가장 엄격한 - 가장 의미투명한 동작을 할 수 있는 - 해석을 하여야 합니다.
원서버가 응답할 수 있는 캐시 지시자
Cache-Control 일반 헤더 필드는 요구/응답 체인에 따라 모든 캐시 메커니즘이 반드시 따라야 하는 지시자를 표시하는데 사용합니다. 여기서는 응답에서 사용되는 캐시지시자(cache-directive)에 대하여 알아봅니다. 요구에서 사용되는 캐시 지시자에 대하여는 관련 문서를 참조바랍니다.
Cache-Control: public
| private
| no-cache
| no-store
| no-transform
| must-revalidate
| proxy-revalidate
| max-age
| cache-extension |
캐시 제한자(public, private, no-cache)
Cache-Control 응답 지시자 중에서 public, private, no-cache는 원서버가 응답의 캐시 가능성을 무시할 수 있도록 합니다.
public
보통은 비공유 캐시 내에서만 캐시할 수 있거나(private) 캐시할 수 없지만(no-cache) public은 모든 공유/비공유 캐시에서 응답을 캐시할 수 있도록 지정합니다.
private
응답 메시지의 전체 또는 일부분을 단일 사용자만이 사용하며 절대로 공유 캐시(shared cache)에 의해 캐시해서는 안됨을 표시합니다. 원서버가 응답의 특정 부분이 단일 사용자만을 위한 것이며 다른 사용자의 요구에 대한 유효한 응답은 아니라는 것을 명시할 수 있도록 합니다.
no-cache
응답의 전체 또는 부분을 캐시해서는 안된다는 것을 나타냅니다. 원서버가 클라이언트 요구에 낡은 응답(stale response)을 리턴하도록 설정된 캐시에 의해서도 캐시를 하지 못하도록 합니다. 대부분의 HTTP/1.0 캐시는 이 지침을 인지하지 못하거나 따르지 않을 것입니다.
캐시 저장 금지(no-store)
no-store 지시자의 목적은 부주의하게 민감한 정보를 백업테이프와 같은 곳에 보유하거나 배포하는 것을 방지하는 것입니다. no-store 지시자는 요구/응답 모두에 발송할 수 있습니다. 요구에 포함하여 발송하게 되면 캐시는 요구의 어떤 부분 또는 이 요구에 대한 어떠한 응답도 캐시해서는 안됩니다. 응답에 발송하게 되면 캐시는 이 응답의 어떤 부분 또는 응답을 이끌어 낸 요구를 저장해서는 안됩니다. 이 지시자는 비공유 및 공유 캐시에 모두 적용됩니다.
만기일 메커니즘의 변경(max-age)
원서버는 expires 헤더를 이용하여 엔터티의 만기시간을 명시합니다. 대안으로 응답에 max-age 지시자를 사용하여 표시할 수도 있습니다.
응답에 expires 헤더 및 max-age 지시자가 모두 포함되어 있으면 max-age 지시자는 expires 헤더가 더 제한적이라 할지라도 이를 무시합니다. 이 원칙은 원서버가 HTTP/1.0 캐시에 HTTP/1.1 캐시(또는 이후 버전)보다 긴 만기시간을 응답에 부여할 수 있도록 합니다. HTTP/1.0 캐시가 동기화되지 않은(desynchronized) 시계때문에 부적절하게 경과시간이나 만기시간을 계산했을 때 유용합니다.
캐시된 사본을 원서버가 직접적으로 검증하도록 강요하여 응답을 명확히 하려면 아래와 같이 max-age 값을 0으로 지정합니다.
캐시의 재검증(must-revalidate)
규약은 원서버가 계속되는 캐시 사용에 대한 캐시 엔트리 검증을 요구할 수 있는 메커니즘을 포함하고 있습니다. must-revalidate 지시자가 캐시가 수신한 응답에 포함되어 있고 캐시가 계속되는 요구에 응답하기에는 낡아진 이후에 캐시는 먼저 원서버에 이를 재검증하기 전에는 엔트리를 사용해서는 안됩니다.
must-revalidate 지시자는 특정 규약 기능의 안정된 운영을 위해서 필요합니다. 어떠한 경우이든 HTTP/1.1 캐시는 must-revalidate 지시자를 반드시 따라야 합니다.
비변경 지시어(no-transform)
구현된 중간 캐시(프록시)에서 특정 엔터티 본문의 media type을 변환하는 것이 유용할 수 있습니다. 예를 들어 프록시는 캐시 공간을 절약하거나 느린 링크 상의 트래픽 양을 줄이기 위해 이미지의 포맷을 변환할 수 있습니다. 그러나 특정 종류의 애플리케이션에 사용할 엔터티 본문에 이러한 변환을 적용했을 때 심각한 운영 문제가 발생하게 됩니다. 예를 들어 의료 이미지 처리, 과학적 자료 분석 및 end-to-end 인증에 사용되는 애플리케이션은 모두 원서버의 엔터티 본문와 비트 단위까지 동일한 엔터티 본문을 수신하는 방식에 의존하고 있습니다.
따라서 응답이 no-transform 지시자를 포함하고 있으면 중간 캐시나 프록시는 Content-Encoding, Content-Length, Content-Range, Content-Type와 같은 헤더 필드 값을 절대로 변경해서는 안됩니다.
캐시 제어 확장(cache-extension)
Cache-Control 헤더 필드는 하나 또는 그 이상의 cache-extension 토큰을 이용하여 각각 선택적으로 부여된 값을 가지고 확장할 수 있습니다. 정보 확장(informational extensions - 캐시 동작에 변화를 요구하지 않는)은 다른 지시자의 의미를 변화시키지 않고도 추가할 수 있습니다 동작 확장(behavioral extensions)은 캐시 지시자의 기본 베이스에 대한 변경자의 역할을 수행하도록 디자인 되었습니다. 새로운 지시자 및 표준 지시자 모두가 제공되었을 때 새로운 지시자를 이해하지 못하는 애플리케이션은 표준 지시자가 명시한 동작에 기본적으로 따르며 새로운 지시자를 이해하는 애플리케이션은 이를 표준 지시자와 관련된 필요 조건의 변경으로 인식합니다. 이러한 방식으로 지시자를 기본 규약에 대한 변경을 요구하지 않고도 확장할 수 있습니다.
인지할 수 없는 캐시지시자는 무시해야 합니다. HTTP/1.1 캐시가 인지하지 못하는 모든 캐시지시자는 캐시가 확장을 이해하지 못하더라도 최소한도로 이러한 캐시 동작이 정학한 것으로 유지되도록 표준 지시자(또는 응답의 캐시 제한자)와 결합되어 있다고 가정합니다.
IE5에서의 캐시 제어 확장
post-check, pre-check 지시자는 익스플로러 5.0부터 제공되기 시작한 캐시 제어 메커니즘입니다. 이 헤더는 이전 버전의 익스플로러나 다른 브라우저에서는 무시됩니다. 이 2개의 헤더에 의해 문서는 캐시로부터 가져오기 때문에 문서를 빠르게 표시할 수 있습니다. 캐시는 웹서버의 최신의 문서를 기초로 갱신되므로, 다음에 사용자가 이 페이지를 방문헸을 때에는, 새로이 갱신된 문서가 표시됩니다.
post-check 및 pre-check에 대한 상세한 정보는 http://msdn.microsoft.com/workshop/author/perf/perftips.asp를 참조하세요.
post-check
post-check에 설정된 시간(초)이 지나고 나서부터는 사용자에게 캐시문서를 보낸 후 엔터티가 신선한 지 확인합니다. 문서를 보낸 후(post)에 엔터티가 신선한 지 확인하는 고로 post-check라고 합니다. 이와 같은 이유로 인하여 금번에 받은 문서는 낡은 문서일 수 있습니다. 그러나 다음 방문 때는 새로이 갱신된 캐시문서를 분명히 보게 됩니다.
pre-check
pre-check에 설정된 시간(초)이 지나고 나서부터는 엔터티가 신선한 지 먼저 확인한 후 사용자에게 문서를 보냅니다. 문서를 사용자에게 보내기 전(pre)에 엔터티가 신선한 지 확인하는 고로 pre-check라고 합니다.
post-check 및 pre-check에 의한 캐시 동작
| IE5 캐시 제어 메커니즘 |
|
브라우저가 캐시에 있는 문서를 가져오도록 요구할 때, HTTP 응답 헤더로 서버에서 클라이언트로 보내지는 캐시 엔트리에 캐시 제어 확장(cache-control extensions)가 포함되어 있으면, 브라우저는 서버로부터 가장 최신의 자료를 가져올 시기를 결정하기 위해 캐시 제어 확장과 다음 로직을 이용하게 됩니다.
- post-check 구간을 아직 지나지 않았다면, 간단하게 캐시로 부터 해당 페이지를 검색합니다.
- 마지막 요구가 있은 후 경과 시간이 post-check와 pre-check 구간 사이에 있다면 캐시로부터 해당 페이지를 보여주고, 갱신된 페이지를 가져와서 캐시에 저장합니다.
- 사용자가 해당 페이지를 재요구한 시간이 pre-check 구간을 지났다면, 우선 HTTP 서버에게 브라우저가 해당 페이지를 마지막으로 요구한 이래로 수정되었는지 확인합니다. 해당 페이지가 수정되었다면 가져와서 갱신된 페이지를 보여줍니다.
Refresh 버튼(F5 키를 포함하여)은 서버에게 항상 if-modified-since 요구를 보내기 때문에 위의 로직에 따라 동작하지는 않을 것입니다. 하이퍼링크(hyperlink)는 위의 로직에 따라 동작합니다.
IE5의 캐시 동작
post-check 및 pre-check 지시자를 지정하게 되면 검색 대상이 되고 있는 문서는 다음과 같은 순서로 캐시가 처리됩니다.
첫째, 사용자가 페이지를 처음으로 방문하면, 문서는 웹서버로부터 취득되어 캐시에 저장됩니다.
둘째, 사용자가 페이지를 2번째에 방문하면, 문서는 캐시로부터 표시되며, 캐시 내의 데이터는 웹서버를 기초로 갱신됩니다.
이후에 문서는 캐시로부터 취득되므로, 페이지는 단시간에 로드되어 그 후로 캐시가 서버의 문서를 기초로 갱신됩니다.
post-check, pre-check에 의한 캐시 제어 구조는 항상 변화를 계속하고 있는 주식 정보 등의 데이터에는 적합하지 않습니다만, 가끔 변경되는 따라서 매회 갱신할 필요가 없는 문서의 경우에는 잘 동작합니다. 예를 들어, MSN.com 사이트의 네비게이션 유저 인터페이스는 자주 바뀌지 않기 때문에, post-check 및 pre-check 설정으로 마크되어 있습니다.
다음은 각각의 캐시 제어 메커니즘에 적합한 조건을 나타내었습니다.
*** | 자주 갱신되는 컨텐트 | 가끔 갱신되는 컨텐트 | 비교적 정적인 컨텐트 |
---|
사용예 | 주식정보 | 사이트 네비게이션 | 회사로고 |
캐시 제어 설정의 예 | 컨텐츠를 즉시 기한 마감으로 한다. (예: Expires: 0) | post-check와 pre-check를 사용한다. (예: Cache-Control: post-check=50, pre-check=100) | 유효기간을 먼 미래에 설정한다. (예: Expires: Thu, 01 Dec 2002 16:00:00 GMT) |
Expires 헤더 필드
Expires 엔터티 헤더 필드에 지정된 시간이 지나면 응답이 낡았다고 간주해야 하는 날짜를 제공합니다. 캐시(프록시 캐시 또는 사용자 에이전트 캐시)는 대개 먼저 원서버(또는 엔터티의 신선한 복사본을 가지고 있는 중간 캐시)가 검증하지 않는 한 낡은 캐시 엔트리를 리턴하지 않습니다.
Expires 필드가 존재한다는 것이 그 시간 이전 또는 이후에 원래의 자원이 변경되거나 사라진다는 것을 의미하지는 않습니다.
Expires 필드는 RFC1123-date 포맷으로 작성된 절대 날짜와 시간입니다.
Expires: Thu, 01 Dec 1994 16:00:00 GMT |
앞에서도 언급하였듯이 응답이 max-age 지시자를 포함한 Cache-Control 필드를 포함하고 있으면 expires 필드는 무시됩니다.
HTTP/1.1 클라이언트와 캐시는 반드시 다른 유효하지 않는 날짜 포맷을, 특히 "0" 값을 포함하고 있는 날짜 포맷을 지나간 날짜로 취급해야 합니다.(예를 들면 "벌써 만료된(already expired)"으로)
응답을 "벌써 만료된(already expired)" 것으로 표시하기 위해서 원서버는 expires 날짜를 Date 헤더 필드와 동일한 것으로 사용해야 합니다.
응답을 "결코 만료되지 않는(never expires)" 것으로 표시하기 위해서 원서버는 expires 날짜를 대략 응답이 발송된 후 시점부터 1년 후를 지정합니다. HTTP/1.1 서버는 향후 1년 이상된 expires 날짜를 발송하지 말아야 합니다.
기본적으로 캐시할 수 없는 응답에 미래의 특정 시간의 시간값과 함께 expires 헤더 필드가 존재하면 Cache-Control 헤더 필드가 다른 식으로 표시하지 않는 한 응답을 캐시할 수 있다는 것을 표시합니다.
Last-Modified 헤더 필드
Last-Modified 엔터티 헤더 필드는 원서버가 변형자(variant)가 마지막으로 변경되었다고 믿는 날짜와 시간을 표시합니다.
Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT |
원서버는 절대 서버의 메시지 발생 시간보다 늦은 Last-Modified 날짜를 발송해서는 안됩니다. 이처럼 자원의 최근 변경이 미래의 특정 시간을 표시하는 경우 서버는 그 날짜를 메시지 발생 날짜로 대체해야 합니다.
기본 서버는 엔터티의 Last-Modified 값을 응답의 Date 값을 생성한 시간과 가능한 한 가까운 것을 얻어야 합니다. 이것은 수신측이 특히 엔터티가 응답이 생성된 시간에 가깝게 변경되었을 때 정확하게 엔터티의 변경 시간을 평가할 수 있도록 합니다.
HTTP/1.1 서버는 가능할 때 마다 반드시 Last-Modified를 발송해야 합니다.
Pragma 헤더 필드
Pragma 일반 헤더 필드는 요구/응답 체인을 따라 어떤 수신측에도 적용할 수 있는 구현 방식에 한정된 지시자(implementation-specfic)를 포함하는데 사용합니다.
no-cache 지시자는 요구 메시지에 존재하면 애플리케이션은 요구되고 있는 것으 캐시 사본을 가지고 있다 하더라도 요구를 원서버에 전달해야 합니다. 이 Pragma 지시자는 no-cache 캐시지시자와 동일한 의미를 가지며 여기서는 HTTP/1.0과의 호환성 유지를 위해 규정하였습니다. 클라이언트는 no-cache 요구가 HTTP/1.1을 따르지 않는 것으로 알려진 서버로 전달되었을 때 두 헤더 필드를 모두 포함해야 합니다.
HTTP/1.0에서 캐시 등을 제어하기 위해 사용되었으나 HTTP/1.1에서는 사용되지 않습니다. 따라서 HTTP/1.1 클라이언트는 Pragma 요구 헤더를 발송해서는 안됩니다. HTTP/1.1 캐시는 "Pragma: no-cache"를 클라이언트가 "Cache-Control: no-cache"를 발송한 것처럼 취급해야 합니다.