| 인터넷 엔지니어링 태스크 포스 (IETF) | M. Nottingham |
| 의견 요청: 9211 | Fastly |
| 카테고리: 표준 트랙 | 2022년 6월 |
| ISSN: 2070-1721 |
Cache-Status HTTP 응답 헤더 필드
초록
디버깅을 돕기 위해, HTTP 캐시는 종종 응답에 헤더 필드를 추가하여 요청을 어떻게 처리했는지 임시로 설명합니다. 이 명세는 HTTP의 캐싱 모델에 맞춘 표준 메커니즘을 정의합니다.
이 메모의 상태
이 문서는 인터넷 표준 트랙 문서입니다.
이 문서는 인터넷 엔지니어링 태스크 포스(IETF)의 산출물입니다. IETF 커뮤니티의 합의를 반영하며, 공개 검토를 거쳐 인터넷 엔지니어링 스티어링 그룹(IESG)에 의해 발행 승인을 받았습니다. 인터넷 표준에 대한 추가 정보는 RFC 7841 2절에서 확인할 수 있습니다.
이 문서의 최신 상태, 정오표, 피드백 방법 등은 https://www.rfc-editor.org/info/rfc9211에서 확인할 수 있습니다.
Copyright Notice
Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.
1. 소개
디버깅(사람과 자동화 도구 모두)을 돕기 위해, HTTP 캐시는 종종 요청을 어떻게 처리했는지를 설명하는 헤더 필드를 응답에 추가합니다. 안타깝게도 이러한 헤더 필드의 의미는 종종 불명확하며, 의미와 문법이 구현마다 다릅니다.
이 명세서는 이 목적을 위해 표준화된 문법과 의미를 가진 새로운 HTTP 응답 헤더 필드 "Cache-Status"를 정의합니다.
1.1. 표기 규약
이 문서에서 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", 및 "OPTIONAL"과 같은 핵심 용어는, 모두 대문자로 표기된 경우에 한해 BCP 14(RFC2119 및 RFC8174)에 따라 해석됩니다.
이 문서는 구문과 파싱을 명시하기 위해 Section 3의 용어인 List, String, Token, Integer, Boolean(STRUCTURED-FIELDS)을 사용합니다.
또한 이 문서는 HTTP 및 HTTP-CACHING의 용어를 사용합니다.
2. Cache-Status HTTP 응답 헤더 필드
Cache-Status HTTP 응답 헤더 필드는 캐시가 해당 응답과 관련 요청을 어떻게 처리했는지를 나타냅니다. 이 헤더 필드의 문법은 STRUCTURED-FIELDS를 따릅니다.
값은 List입니다. List의 각 항목은 요청을 처리한 캐시를 나타냅니다. 첫 번째 항목은 오리진 서버에 가장 가까운 캐시를, 마지막 항목은 사용자에 가장 가까운 캐시(사용자 에이전트의 캐시가 값을 추가한 경우 해당 캐시 포함)를 나타냅니다.
캐시는 언제 Cache-Status 헤더 필드를 응답에 추가할지 자체적으로 결정합니다. 어떤 캐시는 모든 응답에 추가할 수 있고, 다른 캐시는 특정 구성일 때나 요청에 디버그 모드를 활성화하는 헤더가 포함된 경우에만 추가할 수 있습니다. 관련 보안 고려사항은 Section 6을 참조하십시오.
중개자는 자신이 로컬에서 생성한 응답(예: 잘못된 요청으로 생성된 400 응답)에는 Cache-Status 멤버를 추가해서는 안됩니다. 단, 생성된 응답이 저장된 응답을 기반으로 하는 경우(예: 304 또는 206과 같이 저장된 응답을 기반으로 하는 경우)는 예외입니다. 예를 들어 프록시가 잘못된 요청으로 400 응답을 생성했다면, 이는 오리진이 아닌 프록시가 생성한 응답이므로 Cache-Status 값을 추가하지 않습니다.
캐시가 Cache-Status 헤더 필드에 값을 추가할 때는 기존 필드 값을 보존해야 하며, 이를 통해 요청을 처리한 전체 캐시 체인을 디버깅할 수 있습니다.
각 List 항목은 해당 항목을 삽입한 캐시를 식별하며, 이 식별자는 String 또는 Token이어야 합니다. 배포 환경에 따라 제품명 또는 서비스명(예: "ExampleCache" 또는 "Example CDN"), 호스트명("cache-3.example.com"), IP 주소 또는 생성된 문자열일 수 있습니다.
List의 각 항목은 해당 캐시의 요청 처리 방식을 설명하는 파라미터를 가질 수 있습니다. 이러한 파라미터는 선택 사항이지만, 캐시는 가능한 한 많은 정보를 제공하는 것이 권장됩니다.
이 명세서는 다음과 같은 파라미터들을 정의합니다.
2.1. hit 파라미터
"hit"의 값은 Boolean으로, true일 때 해당 요청이 캐시에서 만족되었음을 나타냅니다. 즉, 요청이 전달되지 않았고 응답이 캐시에서 얻어진 경우입니다.
원래 오리진에서 생성되었으나 캐시가 수정한 응답(예: 304 또는 206 상태 코드)도 검증 등으로 전달되지 않았다면 여전히 hit로 간주됩니다.
캐시에 있었지만 전달 없이는 사용할 수 없었던 응답(예: 만료되었거나 부분 응답)은 hit로 간주되지 않습니다. 단, 오리진 서버가 사용 불가하여 전달 없이 사용된 만료 응답은 hit로 간주될 수 있습니다.
"hit"와 "fwd"는 상호 배타적이며, 각 리스트 항목에는 둘 중 하나만 표시되어야 합니다.
2.2. fwd 파라미터
"fwd"가 있을 경우 요청이 오리진 쪽으로 전달되었음을 나타내며, 그 값은 전달된 이유를 나타내는 Token입니다.
요청이 전달된 이유를 설명하기 위해, 다음 값들이 가장 구체적인 것에서 덜 구체적인 것 순으로 정의되어 있습니다:
- bypass:
- 캐시가 이 요청을 처리하지 않도록 구성되었음.
- method:
- 요청 메서드의 의미상 요청을 전달해야 함.
- uri-miss:
- 캐시에 요청 URI와 일치하는 응답이 없음.
- vary-miss:
- 캐시에 요청 URI와 일치하는 응답은 있었으나, 요청의 헤더 필드와 저장된 Vary 헤더 필드에 따라 적절한 응답을 선택할 수 없었음.
- miss:
- 이 요청을 만족시킬 수 있는 응답이 캐시에 없었음(구현이 uri-miss와 vary-miss를 구분하지 못할 때 사용).
- request:
- 캐시는 요청에 대해 신선한 응답을 선택할 수 있었지만, 요청의 의미(예: Cache-Control 요청 지시어)가 그것의 사용을 허용하지 않았음.
- stale:
- 캐시는 요청에 대해 응답을 선택할 수 있었지만, 해당 응답이 만료되었음.
- partial:
- 캐시는 요청에 대해 부분 응답을 선택할 수 있었으나, 요청된 모든 범위를 포함하지 않았거나 요청이 전체 응답에 대한 것이었음.
캐시가 알 수 있는 가장 구체적인 이유를 가능한 한 사용해야 합니다. 관련 내용은 HTTP-CACHING 및 Section 4도 참조하십시오.
2.3. fwd-status 파라미터
"fwd-status"의 값은 Integer로, 전달된 요청에 대해 다음 홉 서버가 반환한 상태 코드를 나타냅니다(관련: HTTP, Section 15). fwd-status 파라미터는 fwd가 있을 때에만 의미가 있습니다. fwd가 있으나 fwd-status가 없으면, 응답에 포함된 상태 코드가 기본값으로 간주됩니다.
이 파라미터는 다음 홉 서버가 조건부 요청에 대해 304(수정 없음)를 반환했는지, 또는 범위 요청으로 인해 206(부분 콘텐츠)을 반환했는지를 구분하는 데 유용합니다.
2.4. ttl 파라미터
"ttl"의 값은 Integer로, 캐시가 계산한 응답의 남은 신선도 수명(초 단위)을 나타냅니다(측정 시점은 캐시가 응답 헤더 섹션을 전송하는 시점과 가능한 한 가깝게). 이 값에는 캐시의 휴리스틱, 로컬 구성 또는 기타 요인으로 할당된 신선도도 포함됩니다. 음수이면 만료(stale)를 의미합니다(관련: HTTP-CACHING, Section 4.2.1).
2.5. stored 파라미터
"stored"의 값은 Boolean으로, 캐시가 해당 응답을 저장했는지를 나타냅니다(관련: HTTP-CACHING, Section 3). true이면 저장되었음을 의미합니다. stored 파라미터는 fwd가 있을 때에만 의미가 있습니다.
2.6. collapsed 파라미터
"collapsed"의 값은 Boolean으로, 이 요청이 하나 이상의 다른 전달 요청과 합쳐졌는지를 나타냅니다(관련: HTTP-CACHING, Section 4). true이면 응답이 성공적으로 재사용되었음을 의미하고, 그렇지 않으면 새 요청을 만들어야 했음을 의미합니다. 해당 파라미터가 없으면 요청은 다른 요청과 합쳐지지 않은 것입니다. collapsed 파라미터는 fwd가 있을 때에만 의미가 있습니다.
2.7. key 파라미터
"key"의 값은 String으로, 해당 응답에 사용된 캐시 키의 표현을 전달합니다(관련: HTTP-CACHING, Section 2). 이 값은 구현에 따라 달라질 수 있습니다.
2.8. detail 파라미터
"detail"의 값은 String 또는 Token으로, 구현별 상태나 기타 캐싱 관련 지표처럼 다른 파라미터에 포착되지 않는 추가 정보를 전달할 수 있게 합니다.
예를 들면:
Cache-Status: ExampleCache; hit; detail=MEMORY
detail 파라미터의 의미는 그것을 보낸 캐시에 항상 특화되어 있습니다. 다른 캐시에서 동일한 detail 값을 보내더라도 그 의미가 같지 않을 수 있습니다.
이 파라미터는 의도적으로 제한되어 있습니다. 구현자나 운영자가 상호 운용 가능한 방식으로 추가 정보를 전달해야 한다면, 확장 파라미터를 등록(섹션 4 참조)하거나 다른 헤더 필드를 정의하는 것이 권장됩니다.
3. 예시
다음은 최소한의 캐시 히트 예시입니다:
Cache-Status: ExampleCache; hit
그러나 친절한 캐시는 더 많은 정보를 제공합니다. 예:
Cache-Status: ExampleCache; hit; ttl=376
만료된 히트는 단지 음수의 freshness 값을 갖습니다. 예:
Cache-Status: ExampleCache; hit; ttl=-412
반면, 다음은 완전한 미스의 예입니다:
Cache-Status: ExampleCache; fwd=uri-miss
다음은 백엔드 서버에서 성공적으로 검증된 미스의 예입니다:
Cache-Status: ExampleCache; fwd=stale; fwd-status=304
다음은 다른 요청과 병합(collapsed)된 미스의 예입니다:
Cache-Status: ExampleCache; fwd=uri-miss; collapsed
다음은 캐시가 병합을 시도했지만 실패한 미스의 예입니다:
Cache-Status: ExampleCache; fwd=uri-miss; collapsed=?0
다음은 두 계층의 캐시를 거친 예입니다. 오리진에 가장 가까운 캐시는 이전 요청에 대해 저장된 응답으로 응답했으며, 두 번째 캐시는 해당 응답을 저장하여 이후 요청을 처리할 때 재사용했습니다:
Cache-Status: OriginCache; hit; ttl=1100,
"CDN Company Here"; hit; ttl=545
다음은 세 계층 캐싱 시스템을 거친 예입니다. 오리진에 가장 가까운 것은 리버스 프록시로(응답이 캐시에서 제공됨), 다음은 네트워크에 개입한 전달 프록시로(요청이 URI에 일치하는 응답이 없어 전달되었고 요청이 다른 요청과 병합되었으며 결과 응답이 저장됨), 사용자에 가장 가까운 것은 브라우저 캐시로(요청 URI와 일치하는 응답이 없음) 구성된 경우입니다:
Cache-Status: ReverseProxyCache; hit Cache-Status: ForwardProxyCache; fwd=uri-miss; collapsed; stored Cache-Status: BrowserCache; fwd=uri-miss
4. 새로운 Cache-Status 파라미터 정의
새로운 Cache-Status 파라미터는 "HTTP Cache-Status" 레지스트리에 등록하여 정의할 수 있습니다.
등록 요청은 지정된 전문가가 검토하고 승인합니다(관련: RFC8126, Section 4.5). 명세 문서는 권장되지만 필수는 아닙니다.
전문가는 요청을 평가할 때 다음 요소들을 고려해야 합니다:
- 커뮤니티 피드백
- 값이 충분히 잘 정의되어 있는지 여부
- 일반적인 파라미터가 벤더 특정, 애플리케이션 특정 또는 배포 특정 값보다 선호됩니다. 커뮤니티에서 일반 값을 합의할 수 없다면, 파라미터 이름은 벤더나 애플리케이션 또는 배포를 식별하는 접두사를 포함하는 등 그에 맞게 구체적이어야 합니다.
등록 요청은 다음 템플릿을 사용해야 합니다:
- Name:
- [Cache-Status 파라미터 키의 이름; 구문 요구사항은 Section 3.1.2(STRUCTURED-FIELDS) 참조]
- Type:
- [파라미터 값의 Structured Type; Section 3.1.2 참조]
- Description:
- [파라미터의 의미에 대한 설명]
- Reference:
- [해당 파라미터를 정의하는 명세에 대한 참조(가능한 경우)]
등록 요청을 보낼 위치에 대한 세부사항은 레지스트리(<https://www.iana.org/assignments/http-cache-status>)를 참조하십시오.
5. IANA 고려사항
IANA는 <https://www.iana.org/assignments/http-cache-status>에 "HTTP Cache-Status" 레지스트리를 생성하고, 섹션 2에 정의된 타입들로 이를 채웠습니다. 관련 절차는 섹션 4를 참조하십시오.
IANA는 또한 HTTP의 "Hypertext Transfer Protocol (HTTP) Field Name Registry"(정의: Section 18.4)에 다음 항목을 추가했습니다:
- Field name:
- Cache-Status
- Status:
- permanent
- Reference:
- RFC 9211
6. 보안 고려사항
공격자는 Cache-Status에 포함된 정보를 사용해 캐시(및 기타 구성 요소)의 동작을 탐색하고, 캐시를 이용하는 이들의 활동을 추론할 수 있습니다. Cache-Status 헤더 필드 자체만으로 이러한 위험을 만들지는 않더라도, 공격자가 이를 악용하는 데 도움을 줄 수 있습니다.
예를 들어, 캐시가 응답을 저장했는지 여부를 알면 민감한 데이터에 대한 타이밍 공격을 수행하는 데 도움이 될 수 있습니다.
또한 캐시 키를 노출하면 공격자가 캐시 키의 변경을 이해하는 데 도움이 되어 캐시 포이즈닝 공격을 도울 수 있습니다. 자세한 내용은 ENTANGLE을 참조하십시오.
기본 위험은 암호화 및 인증 사용, 공격자가 제어하는 데이터를 캐시 키에 포함하지 않음 등 다양한 기법으로 완화할 수 있습니다. 단순한 키의 난독화는 이 위험을 완화하지 못합니다.
이러한 공격을 돕지 않기 위해 Cache-Status 헤더 필드는 생략하거나, 클라이언트가 수신 권한이 있을 때에만 전송하거나, 민감한 정보(예: key 파라미터)는 클라이언트가 권한이 있을 때에만 전송할 수 있습니다.
7. 참고문헌
7.1. 규범적 참고문헌
- [HTTP]
- Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “HTTP Semantics”, STD 97, RFC 9110, DOI 10.17487/RFC9110, June 2022, <https://www.rfc-editor.org/info/rfc9110>.
- [HTTP-CACHING]
- Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “HTTP Caching”, STD 98, RFC 9111, DOI 10.17487/RFC9111, June 2022, <https://www.rfc-editor.org/info/rfc9111>.
- [RFC2119]
- Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.
- [RFC8126]
- Cotton, M., Leiba, B., and T. Narten, “Guidelines for Writing an IANA Considerations Section in RFCs”, BCP 26, RFC 8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>.
- [RFC8174]
- Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.
- [STRUCTURED-FIELDS]
- Nottingham, M. and P-H. Kamp, “Structured Field Values for HTTP”, RFC 8941, February 2021, <https://www.rfc-editor.org/info/rfc8941>.
7.2. 참고 참고문헌
- [ENTANGLE]
- Kettle, J., “Web Cache Entanglement: Novel Pathways to Poisoning”, September 2020, <https://portswigger.net/research/web-cache-entanglement>.