| 인터넷 초안 | No-Vary-Search | 2026년 7월 |
| Denicola 외 | 2027년 1월 2일 만료 | [페이지] |
이 명세는 URI 쿼리 매개변수가 캐싱에 미치는 영향을 변경하는 HTTP 캐싱 확장을 정의한다.¶
이 참고 사항은 RFC로 게시되기 전에 제거된다.¶
이 초안의 최신 개정판은 https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html에서 확인할 수 있다. 이 문서의 상태 정보는 https://datatracker.ietf.org/doc/draft-ietf-httpbis-no-vary-search/에서 확인할 수 있다.¶
이 문서에 대한 논의는 HTTP 작업 그룹 메일링 리스트(mailto:ietf-http-wg@w3.org)에서 이루어지며, 그 보관 문서는 https://lists.w3.org/Archives/Public/ietf-http-wg/에 있다. 작업 그룹 정보는 https://httpwg.org/에서 확인할 수 있다.¶
이 초안의 소스와 이슈 추적기는 https://github.com/httpwg/http-extensions/labels/no-vary-search에서 확인할 수 있다.¶
이 인터넷 초안은 BCP 78 및 BCP 79의 조항을 완전히 준수하여 제출되었다.¶
인터넷 초안은 인터넷 엔지니어링 태스크 포스(IETF)의 작업 문서이다. 다른 그룹도 작업 문서를 인터넷 초안으로 배포할 수 있다는 점에 유의하라. 현재 인터넷 초안의 목록은 https://datatracker.ietf.org/drafts/current/에 있다.¶
인터넷 초안은 최대 6개월 동안 유효한 초안 문서이며, 언제든지 다른 문서에 의해 갱신, 대체 또는 폐기될 수 있다. 인터넷 초안을 참고 자료로 사용하거나 "진행 중인 작업" 이외의 방식으로 인용하는 것은 적절하지 않다.¶
이 인터넷 초안은 2027년 1월 2일에 만료된다.¶
Copyright (c) 2026 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.¶
HTTP 캐싱 [HTTP-CACHING]은 여러 캐시 키에서 일치하는 리소스를 재사용하는 것에 기반하며, 그중 가장 중요한 것은 제시된 대상 URI([HTTP]의 Section 7.1)입니다. 그러나 때때로 여러 URI가 같은 리소스를 나타낼 수 있습니다. 이로 인해 캐시가 항상 기대만큼 유용하지는 않게 됩니다. 캐시에 어떤 URI 아래의 응답이 들어 있지만, 그 응답이 다른 URI 아래에서 요청되면 캐시된 버전은 무시됩니다.¶
"No-Vary-Search" 응답 헤더 필드는 [HTTP-CACHING]의 Section 4에 설명된 캐싱 확장을 정의하며, 특정 쿼리 매개변수에서만 다른 여러 URI가 같은 리소스를 식별하는 경우라는 이 일반적인 문제의 특정 하위 집합을 다룹니다. 이는 리소스가 쿼리 컴포넌트의 일부 또는 전부가 제공되는 응답에 의미적으로 영향을 주지 않으므로 캐시 매칭 목적에서는 무시될 수 있음을 선언할 수 있게 합니다. 예를 들어, 쿼리 매개변수의 순서가 어떤 리소스가 식별되는지에 영향을 주지 않는다면 이는 다음을 사용하여 표시됩니다¶
특정 쿼리 매개변수(예: 분석용으로 무언가를 나타내는 것)가 제공되는 리소스에 의미적으로 영향을 주지 않는다면, 이는 다음을 사용하여 표시됩니다¶
그리고 리소스가 대신 허용 목록 기반 접근 방식을 원하여, 특정한 알려진 쿼리 매개변수만 제공되는 응답에 의미적으로 영향을 주는 경우에는 다음을 사용할 수 있습니다¶
고유한 쿼리 매개변수를 보내 캐시된 응답 검색을 피하는 "cache busting"은
No-Vary-Search 헤더 필드로 인해 효과가 없어질 수 있음에 유의하십시오.¶
Section 3은
[STRUCTURED-FIELDS] 프레임워크를 사용하여 새로운
응답 헤더 필드 No-Vary-Search를 정의합니다. Section
4와 Section
5는 필드 값을 명세에서 표현할 수 있는 방식에 대한 데이터 모델과,
구조화 필드 파서의 원시 출력을 그 데이터 모델로 파싱하는 과정을 설명합니다. Section
6은
헤더 필드의 영향을 받아 두 URL이 동등한지 비교하는 핵심 알고리즘을 제공합니다. 특히 이는
[WHATWG-URL]에 지정된
application/x-www-form-urlencoded 형식이
제공하는 쿼리 컴포넌트의 키와 값으로의 분해에 의존합니다. (따라서 이 헤더 필드는 쿼리
컴포넌트가 해당 형식을 따르지 않는 URL에는 유용하지 않습니다.) 마지막으로, Section
7은 이 새로운 동등성을 고려하도록
[HTTP-CACHING]의 Section 4를
확장하는 방법을 설명합니다.¶
이 문서의 핵심 단어 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", 및 "OPTIONAL"은 여기에 표시된 것처럼 모두 대문자로 나타날 때에만 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석됩니다.¶
이 문서에서 "URI"와 "URL"이라는 용어는 문맥에 따라 서로 바꾸어 사용됩니다. "URI"는 [URI], [HTTP], 및 [HTTP-CACHING]의 문맥에서 사용되는 반면, "URL"은 [WHATWG-URL]에 지정된 알고리즘의 문맥에서 사용됩니다.¶
이 문서는 또한 WHATWG 및 W3C 사용 방식에서 흔한 몇 가지 규약과 표기법을 채택하며, 특히 알고리즘과 관련된 부분에서 그렇습니다. [WHATWG-INFRA], 특히 다음을 참조하십시오.¶
(사용되는 다른 개념은 인라인 참조로 표시됩니다.)¶
No-Vary-Search HTTP 헤더 필드는 값이 dictionary([STRUCTURED-FIELDS]의 Section 3.2)이어야
하는
구조화 필드 [STRUCTURED-FIELDS]입니다.¶
이는 다음 작성 적합성 요구 사항을 가집니다.¶
존재하는 경우, key-order 항목의 값은 boolean([STRUCTURED-FIELDS]의 Section
3.3.6)이어야 합니다.¶
존재하는 경우, params 항목의 값은 문자열의 inner list([STRUCTURED-FIELDS]의 Section
3.1.1)이어야 합니다.¶
존재하는 경우, except 항목의 값은 문자열의 inner list([STRUCTURED-FIELDS]의 Section
3.1.1)이어야 합니다.¶
params 항목도 존재하는 경우 except 항목은
존재해서는 안 됩니다.¶
dictionary는 키가
key-order, params, 및 except 중 하나가 아닌 항목을 포함할 수 있지만,
그 의미는 이 명세에서 정의되지 않습니다. 이 명세의 구현은 그러한 항목을 무시합니다(그러나 미래의
문서가 그러한 항목에 의미를 부여할 수 있습니다).¶
URL variation config는 다음으로 구성됩니다.¶
특수 값 wildcard 또는 문자열 리스트¶
특수 값 wildcard 또는 문자열 리스트¶
boolean¶
기본 URL variation config는 no-vary params가 빈 리스트이고, vary params가 wildcard이며, vary on key order가 true인 URL variation config입니다.¶
URL variation config 얻기 알고리즘(Section 5.2)은 모든 URL variation config가 다음 제약 조건을 따르도록 보장합니다.¶
value가 주어졌을 때 URL variation config를 파싱하려면:¶
value가 null이면, 기본 URL variation config를 반환합니다.¶
result를 새 URL variation config로 둡니다.¶
result의 vary on key order를 true로 설정합니다.¶
value["key-order"]가 존재하면:¶
value["params"]와
value["except"]가 둘 다 존재하거나 둘 다 존재하지 않으면,
기본 URL variation
config를 반환합니다.¶
value["params"]가 존재하면:¶
value["params"]가
array가 아니면, 기본 URL variation config를 반환합니다.¶
value["params"]의 항목 중
어느 하나라도 string이 아니면, 기본 URL variation config를 반환합니다.¶
result의 no-vary params를
value["params"]의 각 항목에
키 파싱 (Section 5.3)을 적용한
결과로 설정합니다.¶
result의 no-vary params 안의 항목 중 어느 하나라도 error이면, 기본 URL variation config를 반환합니다.¶
result의 vary params를 wildcard로 설정합니다.¶
그렇지 않고, value["except"]가 존재하면:¶
value["except"]가
array가 아니면, 기본 URL variation config를 반환합니다.¶
value["except"]의 항목 중
어느 하나라도 string이 아니면, 기본 URL variation config를 반환합니다.¶
result의 vary params를
value["except"]의 각 항목에
키 파싱 (Section 5.3)을 적용한
결과로 설정합니다.¶
result의 vary params 안의 항목 중 어느 하나라도 error이면, 기본 URL variation config를 반환합니다.¶
result의 no-vary params를 wildcard로 설정합니다.¶
result를 반환합니다.¶
response response가 주어졌을 때 URL variation config를 얻으려면:¶
fieldValue를 response의 header list에서
`No-Vary-Search` 및
"dictionary"가 주어졌을 때 구조화
필드 값을 가져온 결과 [FETCH]로 둡니다.¶
fieldValue가 주어졌을 때 URL variation config를 파싱한 결과(Section 5.1)를 반환합니다. ¶
다음은 여러 입력이 결과 no-vary params 및 vary params에 미치는 영향 측면에서 어떻게 파싱되는지를 보여줍니다.¶
| 입력 | 결과 |
|---|---|
No-Vary-Search: params=("a")
|
no-vary params: « "a"
»vary params: wildcard |
No-Vary-Search: except=("x")
|
no-vary params:
wildcard vary params: « " x" »
|
No-Vary-Search: params=()
|
no-vary params: (빈
리스트) vary params: wildcard |
No-Vary-Search: except=()
|
no-vary params:
wildcard vary params: (빈 리스트) |
다음 입력은 모두 유효하지 않으며, 기본 URL variation config가 반환되도록 합니다.¶
No-Vary-Search: key-order="not a boolean"¶
No-Vary-Search: params="not an inner list"¶
No-Vary-Search: params=(not-a-string)¶
No-Vary-Search: params=?0¶
No-Vary-Search: params=?1¶
No-Vary-Search: params=?1, except=("x")¶
No-Vary-Search: params=("a"), except=("x")¶
No-Vary-Search: params=(), except=()¶
No-Vary-Search: except="not an inner list"¶
No-Vary-Search: except=(not-a-string)¶
No-Vary-Search: except=?1¶
다음 입력은 유효하지만 다소 관례적이지 않습니다. 더 관례적인 형식과 함께 표시되어 있습니다.¶
| 입력 | 관례적 형식 |
|---|---|
No-Vary-Search: key-order=?1
|
No-Vary-Search: key-order
|
No-Vary-Search: except=("x"), key-order
|
No-Vary-Search: key-order, except=("x")
|
No-Vary-Search: params=()
|
(헤더 필드를 생략) |
No-Vary-Search: key-order=?0
|
(헤더 필드를 생략) |
ASCII 문자열 keyString이 주어졌을 때 키를 파싱하려면:¶
keyBytes를 keyString의 isomorphic encoding [WHATWG-INFRA]으로 둡니다.¶
keyBytes 안의 모든 0x2B (+)를 0x20 (SP)로 바꿉니다.¶
keyBytesDecoded를 keyBytes의 percent-decoding [WHATWG-URL]으로 둡니다.¶
keyStringDecoded를 keyBytesDecoded의 BOM 없는 UTF-8 디코딩 [WHATWG-ENCODING]으로 둡니다.¶
keyStringDecoded를 반환합니다.¶
키 파싱 알고리즘은, application/x-www-form-urlencoded 형식 [WHATWG-URL]이 URI(ASCII 문자로 제한됨) 안에서 키와 값의 전체 entry list를 인코딩할 수 있게 하는 방식과 유사하게, ASCII 구조화 헤더 필드 형식 안에서 ASCII가 아닌 키 문자열을 인코딩할 수 있게 합니다. 예를 들어,¶
이는 vary params가 «
"é 気" »인 URL variation config를 결과로 만듭니다. 뒤의 예제에서 설명하듯이,
동등성 테스트 중의 정규화 과정은 다음과 같은 URI들을 동등한 것으로 취급한다는 것을
의미합니다.¶
https://example.com/?é 気=1¶
https://example.com/?é+気=2¶
https://example.com/?%C3%A9%20気=3¶
https://example.com/?%C3%A9+%E6%B0%97=4¶
그리고 계속해서, 이들은 모두 파싱 [WHATWG-URL]되어 같은
키 "é 気"를 갖기 때문입니다.¶
URL [WHATWG-URL] 두 개 urlA와 urlB는 URL variation config variationConfig가 주어졌을 때, 다음 알고리즘이 true를 반환하면 variation config를 모듈로 하여 동등합니다.¶
urlA와 urlB의 scheme, username, password, host, port, 또는 path가 다르면 false를 반환합니다.¶
variationConfig가 기본 URL variation config와 동등하면:¶
이 경우 https://example.com/a와 https://example.com/a?, 또는
https://example.com/foo?a=b&&&c와
https://example.com/foo?a=b&c=처럼, query에 application/x-www-form-urlencoded
parser [WHATWG-URL]를
실행한 뒤에는 같아 보일 수 있는 URL 쌍도 동등하지 않은 것으로 취급됩니다.¶
searchParamsA와 searchParamsB를 빈 리스트로 둡니다.¶
urlA의 query가 null이 아니면, searchParamsA를 urlA의 query의 isomorphic encoding [WHATWG-INFRA]이 주어졌을 때 application/x-www-form-urlencoded parser [WHATWG-URL]를 실행한 결과로 설정합니다.¶
urlB의 query가 null이 아니면, searchParamsB를 urlB의 query의 isomorphic encoding [WHATWG-INFRA]이 주어졌을 때 application/x-www-form-urlencoded parser [WHATWG-URL]를 실행한 결과로 설정합니다.¶
variationConfig의 no-vary params가 리스트이면:¶
그렇지 않고, variationConfig의 vary params가 리스트이면:¶
variationConfig의 vary on key order가 false이면:¶
keyLessThan을 두 쌍 (keyA, valueA)와 (keyB, valueB)를 입력으로 받아 keyA가 keyB보다 code unit less than [WHATWG-INFRA]인지 여부를 반환하는 알고리즘으로 둡니다.¶
searchParamsA를 keyLessThan을 사용하여 오름차순으로 정렬 [WHATWG-INFRA]한 searchParamsA의 결과로 설정합니다.¶
searchParamsB를 keyLessThan을 사용하여 오름차순으로 정렬 [WHATWG-INFRA]한 searchParamsB의 결과로 설정합니다.¶
searchParamsA의 size가 searchParamsB의 size와 같지 않으면 false를 반환합니다.¶
i를 0으로 둡니다.¶
i < searchParamsA의 size인 동안:¶
true를 반환합니다.¶
application/x-www-form-urlencoded parser가 query string을 정규화하는 방식 때문에, 명백히 동등해 보이지 않는 query string이 파싱 후에는 동등한 것으로 취급되는 일부 경우가 있습니다.¶
따라서 예를 들어 No-Vary-Search의 비기본 값,
예컨대 No-Vary-Search: key-order가 주어지면 다음 동등성이 성립합니다.¶
| 첫 번째 Query | 두 번째 Query | 설명 |
|---|---|---|
| null |
?
|
null query는 빈 문자열과 동일하게 파싱됩니다 |
?a=x
|
?%61=%78
|
파싱은 percent-decoding을 수행합니다 |
?a=é
|
?a=%C3%A9
|
파싱은 percent-decoding을 수행합니다 |
?a=%f6
|
?a=%ef%bf%bd
|
두 값 모두 U+FFFD (�)로 파싱됩니다 |
?a=x&&&&
|
?a=x
|
파싱은 &에서 분할하고
빈 문자열을 버립니다 |
?a=
|
?a
|
둘 다 a에 대해 빈 문자열 값을
갖는 것으로 파싱됩니다
|
?a=%20
|
?a= &
|
%20은 U+0020 SPACE로 파싱됩니다
|
?a=+
|
?a= &
|
+는 U+0020 SPACE로 파싱됩니다
|
캐시 [HTTP-CACHING]가 이 명세를 구현한다면, [HTTP-CACHING]의 Section 4에 있는 제시된 대상 URI 요구 사항:¶
는 다음으로 대체됩니다.¶
제시된 대상 URI([HTTP]의 Section 7.1)와 저장된 응답의 대상 URI가 일치하거나 URL variation config를 모듈로 하여 동등하고,¶
캐시 구현은 다음과 같은 응답을 더 최근에 저장한 경우, target URI가 URL variation config를 모듈로 해서만 일치하는 저장된 응답을 재사용하지 않을 수 있습니다.¶
query를 제외하고 제시된 대상 URI와 같은 target URI를 가지며,¶
No-Vary-Search 필드에 비어 있지 않은 값을 가지며,¶
재사용 대상으로 고려 중인 저장된 응답과 다른 No-Vary-Search
필드 값을 가집니다.¶
캐시 구현 효율성을 돕기 위해, 서버는 query component를 처리하는 방식을 업데이트할
필요가 있는 경우가 아니라면, 시간이 지나면서 주어진 pathname에 대한 응답에서
No-Vary-Search 필드에 서로 다른 비어 있지 않은 값을 보내지 않는 것이 좋습니다.
그렇게 하면 위와 같은 전략을 사용하는 캐시 구현이 재사용될 수 있었던 일부 저장된 응답을 놓치게
됩니다.¶
주의해야 할 주된 위험은 일치하지 않는 URL의 영향입니다. 특히 이는 사용자가 링크에 마우스를 올렸을 때 표시된 URL이나 URL 표시줄에 표시된 URL과 다른 URL에서 원래 가져온 응답을 보게 만들 수 있습니다.¶
그러나 영향이 query parameters로 제한되므로, 이는 관련 보안 경계인 origin [HTML]을 넘지 않습니다. (또는 웹 브라우저 보안 UI의 관점에서는 the perspective of web browser security UI에서의 host일 수도 있습니다. [WHATWG-URL]) 실제로 우리는 이미 origin에게 history.replaceState() 또는 service workers 같은 기술을 통해 클라이언트 측에서도 (URL, response body) 쌍을 어떻게 표시할지에 대한 완전한 제어권을 주었습니다.¶
이 제안은 사용자 식별자를 전달하기 위해 query parameters를 자주 사용하는 탐색 추적이라는 개인정보 보호와 매우 관련이 큰 영역에 인접해 있습니다. 그러나 우리는 이 제안 자체에는 개인정보 보호 영향이 없다고 봅니다. 이는 기존 탐색 추적 완화나 현재 검토 중인 알려진 미래의 완화책을 방해하지 않습니다. 실제로 어떤 페이지가 URI에 사용자 식별자를 인코딩한다면, 이 제안이 제공하는 유일한 능력은 서버가 캐시를 우회하지 않고 캐시가 서버를 대신하게 하여 그러한 사용자 ID의 서버 처리를 방지함으로써 사용자 추적을 줄이는 것입니다. [NAV-TRACKING-MITIGATIONS]¶
IANA는 다음을 Hypertext Transfer Protocol (HTTP) Field Name Registry(https://www.iana.org/assignments/http-fields/http-fields.xhtml)에 입력해 달라는 요청을 받습니다.¶
Section 4, Paragraph 3; Section 5.1, Paragraph 2.1.1; Section 5.1, Paragraph 2.4.2.1.1; Section 5.1, Paragraph 2.5.1; Section 5.1, Paragraph 2.6.2.1.1; Section 5.1, Paragraph 2.6.2.2.1; Section 5.1, Paragraph 2.6.2.4.1; Section 5.1, Paragraph 2.7.2.1.1; Section 5.1, Paragraph 2.7.2.2.1; Section 5.1, Paragraph 2.7.2.4.1; Section 5.1, Paragraph 3.1; Section 5.2.1, Paragraph 3; Section 6, Paragraph 2.2.1¶
Section 3, Paragraph 5.1; Section 4, Paragraph 4; Section 5.2, Paragraph 1¶