Internet Engineering Task Force (IETF) R. Fielding, Editor
Request for Comments: 9110 Adobe
Obsoletes: 2818, 7230, 7231, 7232, 7233, 7235, 7538, 7615, 7694 M. Nottingham, Editor
STD: 97 Fastly
Updates: 3864 J. Reschke, Editor
Category: Standards Track greenbytes
ISSN: 2070-1721 June 2022

HTTP 의미론


요약

하이퍼텍스트 전송 프로토콜(HTTP)은 분산형 협업 하이퍼텍스트 정보 시스템을 위한 상태 비저장 애플리케이션 레벨 프로토콜입니다. 이 문서는 HTTP의 전체 아키텍처를 설명하고, 공통 용어를 정립하며, 모든 버전에서 공통적으로 사용하는 프로토콜의 측면을 정의합니다. 이 정의에는 핵심 프로토콜 요소, 확장 메커니즘, 그리고 "http" 및 "https" 통합 자원 식별자(URI) 스킴이 포함되어 있습니다.

이 문서는 RFC 3864를 갱신하며 RFC 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694 및 7230의 일부를 폐지합니다.

이 메모의 상태

이 문서는 인터넷 표준 트랙 문서입니다.

이 문서는 인터넷 엔지니어링 태스크 포스(IETF)의 산출물입니다. IETF 커뮤니티의 합의를 반영하며, 공개 검토를 거쳐 인터넷 엔지니어링 운영 그룹(IESG)에 의해 출판 승인을 받았습니다. 인터넷 표준에 대한 추가 정보는 RFC 7841 2절에서 확인할 수 있습니다.

이 문서의 현재 상태, 오류 정정, 피드백 제공 방법 등은 https://www.rfc-editor.org/info/rfc9110에서 확인할 수 있습니다.

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.

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English.

1. 소개

1.1. 목적

하이퍼텍스트 전송 프로토콜(HTTP)은 상태를 저장하지 않는 애플리케이션 레벨의 요청/응답 프로토콜 계열로, 네트워크 기반 하이퍼텍스트 정보 시스템과의 유연한 상호작용을 가능하게 하는 공통 인터페이스, 확장 가능한 시맨틱스, 자기 기술적인 메시지를 공유합니다.

HTTP는 서비스가 어떻게 구현되는지의 세부 사항을 감추고, 제공되는 리소스의 종류와 무관하게 클라이언트에 일관된 인터페이스를 제공합니다. 마찬가지로 서버는 각 클라이언트의 목적을 알 필요가 없습니다. 요청은 특정 클라이언트 유형이나 미리 정해진 애플리케이션 단계와 연결되지 않고 독립적으로 고려될 수 있습니다. 이를 통해 범용 구현을 다양한 상황에 효과적으로 사용할 수 있으며, 상호작용의 복잡성을 줄이고, 시간이 지나면서 독립적으로 발전할 수 있습니다.

HTTP는 또한 프록시와 게이트웨이가 비-HTTP 정보 시스템을 보다 범용적인 인터페이스로 변환할 수 있도록 중간 프로토콜로 설계되었습니다.

이러한 유연성의 한 가지 결과는, 프로토콜이 인터페이스 뒤에서 일어나는 일을 기준으로 정의될 수 없다는 점입니다. 대신, 우리는 통신의 구문, 수신된 통신의 의도, 수신자가 기대하는 동작만을 정의할 수 있습니다. 통신을 독립적으로 고려한다면, 성공적인 동작은 서버가 제공하는 관찰 가능한 인터페이스의 변화로 반영되어야 합니다. 하지만 여러 클라이언트가 병렬로 또는 상충된 목적으로 동작할 수 있으므로, 이러한 변화가 단일 응답의 범위를 넘어 관찰될 것을 요구할 수는 없습니다.

1.2. 역사와 발전

HTTP는 1990년 도입 이래 월드 와이드 웹의 주된 정보 전송 프로토콜이었습니다. 처음에는 주어진 경로명으로 식별되는 하이퍼텍스트 문서의 전송을 요청하기 위한 단일 메서드(GET)를 갖춘 단순한 저지연 메커니즘으로 시작했습니다. 웹이 성장함에 따라, HTTP는 요청과 응답을 메시지로 감싸고, MIME과 유사한 미디어 타입으로 임의의 데이터 포맷을 전송하며, 중간자를 통한 요청 라우팅 등으로 확장되었습니다. 이러한 프로토콜은 결국 HTTP/0.9와 HTTP/1.0으로 정의되었습니다([HTTP/1.0] 참조).

HTTP/1.1은 기존의 텍스트 기반 메시지 구문과의 호환성을 유지하면서 프로토콜의 기능을 다듬기 위해 설계되었으며, 인터넷 전반에서 상호운용성, 확장성, 견고성을 개선했습니다. 여기에는 고정 및 동적(청크) 콘텐츠 모두에 대한 길이 기반 데이터 구분자, 일관된 콘텐츠 협상 프레임워크, 조건부 요청을 위한 불투명 검증자, 더 나은 캐시 일관성을 위한 캐시 제어, 부분 업데이트를 위한 범위 요청, 기본 지속 연결 등이 포함됩니다. HTTP/1.1은 1995년에 도입되어 1997년 표준 트랙으로 발표([RFC2068]), 1999년([RFC2616]) 그리고 2014년([RFC7230] ~ [RFC7235])에 개정되었습니다.

HTTP/2([HTTP/2])는 기존 TLS와 TCP 프로토콜 위에서 동시 HTTP 메시지 교환을 위한 멀티플렉싱 세션 계층을 도입하여 효율적인 필드 압축과 서버 푸시를 제공합니다. HTTP/3([HTTP/3])는 TCP 대신 UDP 위에서 QUIC을 사용해 동시 메시지의 독립성을 더 크게 보장합니다.

HTTP의 세 주요 버전 모두 이 문서에서 정의한 시맨틱스에 의존합니다. 각 버전은 사용 맥락에 따라 고유의 장점과 한계가 있기 때문에 서로를 폐지하지 않았습니다. 구현체는 자신이 사용하는 맥락에 가장 적합한 전송 방식과 메시지 구문을 선택해야 합니다.

이번 HTTP 개정판은 시맨틱스(본 문서)와 캐싱([CACHING])의 정의를 현재의 HTTP/1.1 메시징 구문([HTTP/1.1])과 분리해, 각 프로토콜 버전이 동일한 핵심 시맨틱스를 참조하면서도 독립적으로 발전할 수 있도록 했습니다.

1.3. 핵심 시맨틱스

HTTP는 리소스의 종류, 성격, 구현 방식과 관계없이, 메시지를 통해 표현을 조작하거나 전송함으로써(3.1절, 3.2절) 리소스와 상호작용할 수 있는 일관된 인터페이스를 제공합니다.

각 메시지는 요청이거나 응답입니다. 클라이언트는 자신의 의도를 전달하는 요청 메시지를 구성하고, 이를 식별된 오리진 서버로 라우팅합니다. 서버는 요청을 수신해 각 메시지를 파싱하고, 식별된 대상 리소스와 관련된 메시지 시맨틱스를 해석한 후 하나 이상의 응답 메시지로 응답합니다. 클라이언트는 받은 응답을 확인하여 자신의 의도가 수행되었는지 판단하고, 수신된 상태 코드와 콘텐츠에 따라 다음 동작을 결정합니다.

HTTP 시맨틱스에는 각 요청 메서드가 정의하는 의도(9절), 요청 헤더 필드를 통해 확장될 수 있는 시맨틱스, 응답을 설명하는 상태 코드(15절), 그리고 응답 필드에 포함될 수 있는 기타 제어 데이터 및 리소스 메타데이터가 포함됩니다.

시맨틱스에는 또한 콘텐츠가 수신자에 의해 어떻게 해석되어야 하는지 설명하는 표현 메타데이터, 콘텐츠 선택에 영향을 줄 수 있는 요청 헤더 필드, 그리고 콘텐츠 협상(12절)이라 불리는 다양한 선택 알고리즘이 포함됩니다.

1.4. 이 문서에 의해 폐지된 명세

표 1
제목 참조 참고
HTTP Over TLS [RFC2818] B.1
HTTP/1.1 메시지 구문 및 라우팅 [*] [RFC7230] B.2
HTTP/1.1 시맨틱스 및 콘텐츠 [RFC7231] B.3
HTTP/1.1 조건부 요청 [RFC7232] B.4
HTTP/1.1 범위 요청 [RFC7233] B.5
HTTP/1.1 인증 [RFC7235] B.6
HTTP 상태 코드 308 (영구 리다이렉트) [RFC7538] B.7
HTTP Authentication-Info 및 Proxy-Authentication-Info 응답 헤더 필드 [RFC7615] B.8
HTTP 클라이언트 시작 Content-Encoding [RFC7694] B.9

[*] 이 문서는 RFC 7230 중 HTTP/1.1 메시지 구문 및 연결 관리와 독립적인 부분만을 폐지하며, 남은 부분은 "HTTP/1.1" [HTTP/1.1]에 의해 폐지됩니다.

2. 적합성

2.1. 구문 표기법

본 명세서는 [RFC5234]의 확장된 백우스-나우어 형식(ABNF) 표기법을 사용하며, [RFC7405]에서 정의한 문자열 대소문자 구분 표기법이 추가되었습니다.

또한 5.6.1절에서 정의한 리스트 확장을 사용하여, "#" 연산자를 통해 쉼표로 구분된 리스트를 간결하게 정의할 수 있습니다(반복을 나타내는 "*" 연산자와 유사). 부록 A에는 모든 리스트 연산자가 표준 ABNF로 확장된 전체 문법이 나와 있습니다.

慣例상, "obs-"로 시작하는 ABNF 규칙 이름은 역사적인 이유로 등장하는 폐기된 문법 규칙을 나타냅니다.

다음의 핵심 규칙들은 RFC5234 부록 B.1[RFC5234]에 정의된 바와 같이 참조로 포함됩니다: ALPHA(문자), CR(캐리지 리턴), CRLF(CR LF), CTL(제어문자), DIGIT(10진수 0-9), DQUOTE(큰따옴표), HEXDIG(16진수 0-9/A-F/a-f), HTAB(수평 탭), LF(줄 바꿈), OCTET(임의의 8비트 데이터), SP(공백), VCHAR(표시 가능한 US-ASCII 문자).

5.6절에는 필드 값에 대한 몇 가지 일반 구문 구성요소가 정의되어 있습니다.

이 명세서는 "character", "character encoding scheme", "charset", "protocol element" 용어를 [RFC6365]에 정의된 대로 사용합니다.

2.2. 요구 사항 표기법

이 문서에서 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", "OPTIONAL" 등은 BCP 14 [RFC2119][RFC8174]에 설명된 대로 해석해야 하며, 오직 대문자로 표기된 경우에만 해당합니다.

이 명세서는 HTTP 통신 참여자의 역할에 따라 적합성 기준을 목표로 합니다. 따라서 요구 사항은 송신자, 수신자, 클라이언트, 서버, 사용자 에이전트, 중개자, 오리진 서버, 프록시, 게이트웨이, 캐시 등에 따라 부여되며, 요구 사항이 단일 통신의 범위를 넘어 적용될 때는 구현체, 리소스 소유자, 프로토콜 요소 등록에도 추가 요구 사항이 적용됩니다.

요구 사항이 프로토콜 요소를 생성하는 구현체에만 적용될 때는 "send" 대신 "generate" 동사를 사용합니다. 수신한 요소를 전달만 하는 구현체에는 해당되지 않습니다.

구현체가 자신이 맡은 HTTP 역할에 해당하는 모든 요구 사항을 준수하면, 해당 구현은 적합한 것으로 간주됩니다.

송신자는 해당하는 ABNF 규칙이 정의한 문법에 맞지 않는 프로토콜 요소를 생성해서는 안 됩니다(MUST NOT). 하나의 메시지 내에서, 송신자는 자신이 해당 메시지에 대해 갖지 않은 역할에서만 생성할 수 있는 프로토콜 요소나 구문 대안을 생성해서는 안 됩니다(MUST NOT).

HTTP 적합성에는 사용 중인 프로토콜 버전의 특정 메시징 구문 준수와 전송되는 프로토콜 요소의 시맨틱스 준수가 모두 포함됩니다. 예를 들어, HTTP/1.1을 준수한다고 주장하지만 HTTP/1.1 수신자에게 요구되는 기능을 인식하지 못하는 클라이언트는, 그러한 주장에 따라 응답을 조정하는 서버와 상호운용에 실패할 것입니다. 콘텐츠 협상, 사용자 선택 확장 등 사용자 선택을 반영하는 기능은 프로토콜 스트림을 넘어 애플리케이션 동작에 영향을 줄 수 있습니다. 사용자의 선택을 정확히 반영하지 않는 프로토콜 요소를 전송하면 사용자가 혼란을 겪고 선택권이 저해될 수 있습니다.

구현체가 시맨틱 적합성에 실패하면, 해당 구현에서 생성된 메시지를 수신하는 쪽은 결국 동작을 조정하기 위한 우회책을 마련하게 됩니다. 수신자는 이러한 우회책이 문제 구현체에 한정되는 경우에 한해, 이 프로토콜에 적합성을 유지하면서 사용할 수 있습니다(MAY). 예를 들어, 서버는 User-Agent 필드 값을 확인해 알려진 버그나 잘못된 기본값에 맞춰 동작을 조정하기도 하며, 사용자 에이전트 역시 Server 필드 값을 확인해 자신의 동작을 조정하는 경우가 많습니다.

2.3. 길이 요구 사항

수신자는 받은 프로토콜 요소의 ABNF 문법 준수와 합리적인 버퍼 크기에 들어맞는다는 점에 대해 최소한의 기대만 가지며, 방어적으로 구문 분석해야 합니다(SHOULD).

HTTP의 많은 프로토콜 요소에는 구체적인 길이 제한이 없습니다. 왜냐하면 적절한 길이는 구현 및 배치 맥락에 따라 매우 다르기 때문입니다. 따라서 송신자와 수신자 간에는 각 프로토콜 요소의 합리적 길이에 대한 공통 기대가 상호운용성의 핵심이 됩니다. 또한, 일부 프로토콜 요소에 대해 합리적이라 여겨지는 길이의 기준은 지난 30년 간 HTTP 사용 과정에서 계속 변해왔으며 앞으로도 바뀔 것으로 예상됩니다.

최소한, 수신자는 자신이 다른 메시지에서 해당 프로토콜 요소에 대해 생성하는 값만큼의 길이는 구문 분석 및 처리할 수 있어야 합니다(MUST). 예를 들어, 오리진 서버가 자신의 리소스에 아주 긴 URI 참조를 발행한다면, 대상 URI로서 그 참조를 수신했을 때도 이를 파싱 및 처리할 수 있어야 합니다.

많은 수신된 프로토콜 요소는 단지 그 요소를 하위로 전달하기 위해 필요한 정도까지만 파싱됩니다. 예를 들어, 중개자는 받은 필드를 필드 이름과 필드 값 구성요소로만 파싱하고, 필드 값 내부는 추가로 파싱하지 않은 채 그대로 전달할 수 있습니다.

2.4. 오류 처리

수신자는 Accept-Encoding 헤더 필드와 같이, 발신자가 해당 시맨틱스에서 암시하는 동작을 올바르게 구현하지 않는다는 점을 경험이나 설정을 통해 파악하지 않은 한, 이 명세서 및 그 확장에 정의된 시맨틱스에 따라 수신한 프로토콜 요소를 해석해야 합니다(MUST). 예를 들어, 오리진 서버는 User-Agent 헤더 필드를 검사해 특정 구현 버전이 특정 콘텐츠 코딩을 수신할 때 실패하는 것으로 알려진 경우, 수신된 Accept-Encoding 필드 내용을 무시할 수 있습니다.

별도로 명시되지 않은 한, 수신자는 잘못된 구문에서 쓸 수 있는 프로토콜 요소를 복구하려 시도할 수 있습니다(MAY). HTTP는 보안에 직접적인 영향을 주는 경우를 제외하면, 각기 다른 애플리케이션이 서로 다른 오류 처리 전략을 요구하므로 구체적인 오류 처리 메커니즘을 정의하지 않습니다. 예를 들어, 웹 브라우저는 Location 헤더 필드가 ABNF에 맞지 않을 때도 투명하게 복구를 시도할 수 있지만, 시스템 제어 클라이언트는 모든 오류 복구를 위험하다고 여길 수 있습니다.

일부 요청은 9.2.2절에 설명된 대로, 기본 연결 실패 시 클라이언트가 자동으로 재시도할 수 있습니다.

2.5. 프로토콜 버전

HTTP 버전 번호는 두 개의 10진수 사이에 "."(점)을 넣어 표기합니다. 첫 번째(주) 숫자는 메시징 구문을, 두 번째(부) 숫자는 해당 주 버전 내에서 송신자가 향후 통신까지 이해할 수 있는 최고 부 버전을 나타냅니다.

HTTP의 핵심 시맨틱스는 프로토콜 버전이 달라져도 변하지 않지만, "on the wire" 표현은 변할 수 있으며, 이 경우 호환되지 않는 변경이 있을 때 HTTP 버전 번호가 바뀝니다. 또한 HTTP는 16절에 정의된 확장 지점을 이용해 버전을 변경하지 않고도 점진적이고 하위 호환되는 변경을 허용합니다.

프로토콜 버전 전체는 해당 버전 명세에 명시된 요구 사항 집합에 대한 송신자의 적합성을 나타냅니다. 예를 들어, "HTTP/1.1"은 본 문서, "HTTP Caching" [CACHING], 그리고 "HTTP/1.1" [HTTP/1.1]로 정의됩니다.

호환되지 않는 메시지 구문이 도입될 때 HTTP의 주 버전 숫자가 증가됩니다. 부 번호는 프로토콜에 메시지 시맨틱스가 추가되거나 송신자의 추가 기능을 의미하게 될 때 증가합니다.

송신자가 프로토콜의 하위 호환성 부분만 사용하더라도, 부 버전은 송신자의 통신 기능을 광고하여 수신자(서버)는 응답에서, 클라이언트는 향후 요청에서 더 고급 기능을 사용할 수 있음을 알릴 수 있습니다.

HTTP의 주 버전이 부 버전을 정의하지 않는 경우 부 버전 "0"이 암시됩니다. 부 버전 식별자가 필요한 요소에서 프로토콜을 지칭할 때 "0"을 사용합니다.

3. 용어 및 핵심 개념

HTTP는 월드 와이드 웹(WWW) 아키텍처를 위해 만들어졌으며, 전 세계 하이퍼텍스트 시스템의 확장성 요구를 지원하기 위해 발전해왔습니다. 이러한 아키텍처의 많은 부분이 HTTP를 정의하는 데 사용되는 용어에 반영되어 있습니다.

3.1. 리소스

HTTP 요청의 대상은 리소스라고 부릅니다. HTTP는 리소스의 성격을 제한하지 않으며, 단지 리소스와 상호작용할 수 있는 인터페이스만 정의합니다. 대부분의 리소스는 4절에서 설명한 URI(통합 자원 식별자)로 식별됩니다.

HTTP의 설계 목표 중 하나는 리소스 식별과 요청 시맨틱스를 분리하는 것입니다. 이는 요청 시맨틱스를 요청 메서드(9절)와 일부 요청 수정 헤더 필드에 부여함으로써 가능합니다. 리소스는 요청의 메서드 시맨틱스와 일치하지 않는 방식으로 요청을 처리할 수 없습니다. 예를 들어, 리소스의 URI가 안전하지 않은 의미를 암시할 수 있지만, 클라이언트는 안전한 메서드로 요청을 처리할 때 리소스가 안전하지 않은 동작을 피할 것으로 기대할 수 있습니다(9.2.1절 참조).

HTTP는 URI 표준 [URI]에 의존하여 대상 리소스(7.1절)와 리소스 간의 관계를 나타냅니다.

3.2. 표현

표현이란 특정 리소스의 과거, 현재 또는 원하는 상태를 프로토콜을 통해 쉽게 전달할 수 있는 형식으로 반영하도록 의도된 정보를 의미합니다. 표현은 표현 메타데이터의 집합과, 잠재적으로 제한 없는 표현 데이터 스트림(8절)으로 구성됩니다.

HTTP는 리소스 자체를 전송하는 대신, 리소스 상태의 전달 가능한 표현을 통한 통신을 정의함으로써 "정보 은닉"을 허용합니다. 이를 통해 URI로 식별되는 리소스가 무엇이든 될 수 있으며, "라구나 비치의 현재 날씨"와 같은 시간 기반 함수도 포함할 수 있습니다. 메시지가 생성되는 시점의 리소스를 나타내는 정보를 제공할 수 있습니다 [REST].

일관된 인터페이스는 마치 창(window)처럼 작동하여, 메시지 통신을 통해서만 독립적인 상대편과 어떤 대상을 관찰하고 동작할 수 있게 합니다. 우리의 통신에서 그 대상의 현재 또는 원하는 상태를 나타내는(“대신하는”) 추상화가 필요합니다. 표현이 하이퍼텍스트인 경우, 리소스 상태의 표현과 수신자의 향후 상호작용을 안내하는 처리 지침 모두를 제공할 수 있습니다.

대상 리소스는 하나 이상의 표현을 제공하거나 생성할 수 있으며, 각 표현은 리소스의 현재 상태를 반영하도록 의도됩니다. 일반적으로 콘텐츠 협상(12절)에 기반한 알고리즘을 사용해 해당 요청에 가장 적합한 표현을 선택합니다. 이 선택된 표현은 조건부 요청 평가(13절)와 GET(9.3.1절)에 대한 200 (OK), 206 (Partial Content), 304 (Not Modified) 응답의 콘텐츠 구성에 사용되는 데이터와 메타데이터를 제공합니다.

3.3. 연결, 클라이언트, 서버

HTTP는 신뢰할 수 있는 전송 계층 또는 세션 계층 연결 위에서 동작하는 클라이언트/서버 프로토콜입니다.

HTTP 클라이언트는 서버에 하나 이상의 HTTP 요청을 보내기 위해 연결을 설정하는 프로그램입니다. HTTP 서버는 HTTP 요청을 처리하기 위해 연결을 수락하고, HTTP 응답을 보내는 프로그램입니다.

클라이언트와 서버라는 용어는 특정 연결에서 해당 프로그램이 수행하는 역할만을 의미합니다. 동일한 프로그램이 어떤 연결에서는 클라이언트로, 다른 연결에서는 서버로 동작할 수 있습니다.

HTTP는 상태 비저장 프로토콜로 정의되어 있습니다. 즉, 각 요청 메시지의 시맨틱스는 독립적으로 해석될 수 있으며, 연결과 그 위의 메시지 간의 관계는 메시지 해석에 영향을 주지 않습니다. 예를 들어, CONNECT 요청(9.3.6절)이나 Upgrade 헤더 필드가 있는 요청(7.8절)은 연결의 첫 번째 메시지뿐 아니라 언제든 발생할 수 있습니다. 많은 구현체는 프록시 연결 재사용 또는 요청을 여러 서버에 동적으로 분산하기 위해 HTTP의 상태 비저장 설계에 의존합니다.

따라서 서버는 동일한 연결의 두 요청이 동일한 사용자 에이전트로부터 온 것이라 가정해서는 안 됩니다(MUST NOT) 단, 연결이 보안되고 해당 에이전트에만 한정된 경우를 제외합니다. 일부 비표준 HTTP 확장(예: [RFC4559])은 이 요구 사항을 위반하여 보안 및 상호운용성 문제를 초래한 사례가 있습니다.

3.4. 메시지

HTTP는 연결을 통해 메시지를 교환하는 상태 비저장 요청/응답 프로토콜입니다. 송신자수신자는 각각 특정 메시지를 보내거나 받는 모든 구현을 의미합니다.

클라이언트는 메서드(9절)와 요청 대상(7.1절)이 포함된 요청 메시지 형태로 서버에 요청을 보냅니다. 요청에는 요청 수정자, 클라이언트 정보, 표현 메타데이터가 담긴 헤더 필드(6.3절), 메서드에 따라 처리될 콘텐츠(6.4절), 콘텐츠를 전송하면서 수집된 정보를 전달하는 트레일러 필드(6.5절) 등이 포함될 수 있습니다.

서버는 하나 이상의 응답 메시지를 보내 클라이언트의 요청에 응답합니다. 각 응답에는 상태 코드(15절)가 포함됩니다. 응답에는 서버 정보, 리소스 메타데이터, 표현 메타데이터용 헤더 필드, 상태 코드에 따라 해석될 콘텐츠, 콘텐츠 전송 중 수집된 정보를 전달하는 트레일러 필드도 포함될 수 있습니다.

3.5. 사용자 에이전트

사용자 에이전트란 요청을 시작하는 여러 클라이언트 프로그램을 의미합니다.

가장 익숙한 사용자 에이전트의 형태는 범용 웹 브라우저이지만, 이는 전체 구현의 일부에 불과합니다. 다른 일반적인 사용자 에이전트로는 스파이더(웹 탐색 로봇), 커맨드라인 도구, 광고판, 가전제품, 저울, 전구, 펌웨어 업데이트 스크립트, 모바일 앱, 다양한 형태와 크기의 통신 기기 등이 있습니다.

사용자 에이전트라는 것은 요청 시점에 반드시 사람이 소프트웨어 에이전트와 직접 상호작용한다는 의미는 아닙니다. 많은 경우, 사용자 에이전트는 백그라운드에서 실행되어 결과를 나중에 확인할 수 있도록 저장하기도 하며(또는 흥미롭거나 오류가 있는 결과의 일부만 저장), 예를 들어 스파이더는 시작 URI를 부여받아 웹을 하이퍼텍스트 그래프로 크롤링할 때 특정 동작을 따르도록 설정됩니다.

많은 사용자 에이전트는 사용자에게 상호작용 제안을 하거나, 보안·프라이버시 우려에 대해 충분한 경고를 하지 못하거나 하지 않기로 선택할 수 있습니다. 이 명세서에서 오류 보고를 사용자에게 요구하는 경우, 그러한 보고가 오류 콘솔이나 로그 파일에서만 관찰 가능해도 허용됩니다. 마찬가지로, 자동화된 동작이 진행되기 전에 사용자가 확인해야 한다는 요구는 사전 설정, 런타임 옵션, 또는 위험한 동작 자체를 피하는 방식 등으로 충족할 수 있으며, 사용자가 이미 선택한 경우라면 특정 UI나 처리 중단을 의미하지 않습니다.

3.6. 오리진 서버

오리진 서버란 특정 대상 리소스에 대한 권한 있는 응답을 생성할 수 있는 프로그램을 의미합니다.

가장 익숙한 오리진 서버의 형태는 대형 공용 웹사이트입니다. 하지만 사용자 에이전트가 브라우저로만 오해되듯, 모든 오리진 서버가 동일하다고 생각하기 쉽지만 실제로는 다릅니다. 일반적인 오리진 서버로는 홈 오토메이션 장치, 설정 가능한 네트워크 장치, 사무기기, 자율 로봇, 뉴스 피드, 교통 카메라, 실시간 광고 선택기, 주문형 비디오 플랫폼 등이 있습니다.

대부분의 HTTP 통신은 URI로 식별되는 리소스의 표현을 GET 요청으로 가져오는 것으로 이루어집니다. 가장 단순한 경우, 이는 사용자 에이전트(UA)와 오리진 서버(O) 사이의 단일 양방향 연결(===)로 달성될 수 있습니다.

         request   >
    UA ======================================= O
                                <   response

3.7. 중개자

HTTP는 중개자를 통해 연결 체인을 따라 요청을 처리할 수 있습니다. HTTP 중개자의 대표 유형으로는 프록시, 게이트웨이, 터널이 있습니다. 경우에 따라 하나의 중개자가 각 요청의 성격에 따라 오리진 서버, 프록시, 게이트웨이, 터널 역할을 전환할 수 있습니다.

         >             >             >             >
    UA =========== A =========== B =========== C =========== O
               <             <             <             <

위 그림은 사용자 에이전트와 오리진 서버 사이에 세 개의 중개자(A, B, C)가 있는 경우를 보여줍니다. 전체 체인을 따라 전달되는 요청 또는 응답 메시지는 네 개의 별도 연결을 거칩니다. 일부 HTTP 통신 옵션은 가장 가까운(터널이 아닌) 이웃과의 연결에만 적용될 수 있고, 체인의 양 끝점 또는 모든 연결에 적용될 수도 있습니다. 그림은 직선형이지만, 각 참가자는 동시에 여러 통신에 관여할 수 있습니다. 예를 들어, B는 A 이외의 여러 클라이언트로부터 요청을 받을 수 있고, C 이외의 여러 서버로 요청을 전달할 수도 있습니다. 마찬가지로 이후 요청은 동적 로드밸런싱 구성에 따라 다른 경로로 전송될 수 있습니다.

업스트림다운스트림이라는 용어는 메시지 흐름의 방향적 요구 사항을 설명할 때 사용합니다: 모든 메시지는 업스트림에서 다운스트림으로 흐릅니다. 인바운드아웃바운드는 요청 경로상의 방향을 설명하는데, 인바운드는 "오리진 서버 쪽", 아웃바운드는 "사용자 에이전트 쪽"을 의미합니다.

프록시는 클라이언트가(주로 로컬 설정 규칙을 통해) 선택하여 절대 URI 타입의 요청을 받아 HTTP 인터페이스를 통해 번역·처리하도록 하는 메시지 전달 에이전트입니다. 일부는 "http" URI에 대한 프록시 요청처럼 최소한의 변환만 하며, 다른 요청은 완전히 다른 애플리케이션 레벨 프로토콜로의 변환이 필요할 수 있습니다. 프록시는 보안, 주석, 공유 캐싱 등 목적으로 조직 내 HTTP 요청을 공통 중개자를 통해 그룹화하는 데 자주 사용됩니다. 일부 프록시는 7.7절에 설명된 대로 지정된 메시지나 콘텐츠에 변환을 적용하기도 합니다.

게이트웨이(또는 리버스 프록시)는 아웃바운드 연결에서는 오리진 서버로 동작하지만, 받은 요청을 인바운드로 다른 서버(들)에 전달하는 중개자입니다. 게이트웨이는 레거시나 신뢰할 수 없는 정보 서비스를 캡슐화하거나, 엑셀러레이터 캐싱을 통해 서버 성능을 높이거나, HTTP 서비스를 여러 머신에 분산·분할하는 데 자주 사용됩니다.

오리진 서버에 적용되는 모든 HTTP 요구 사항은 게이트웨이의 아웃바운드 통신에도 적용됩니다. 게이트웨이는 인바운드 서버와 어떤 프로토콜로든 통신할 수 있으며, HTTP의 사적 확장도 사용할 수 있습니다. 하지만, 타사 HTTP 서버와 상호운용하려는 HTTP-HTTP 게이트웨이는 인바운드 연결에서 사용자 에이전트 요구 사항을 준수해야 합니다.

터널은 두 연결 사이에서 메시지를 변경하지 않고 맹목적으로 중계하는 역할을 합니다. 일단 활성화되면 터널은 HTTP 통신의 당사자로 간주하지 않지만, 터널 자체는 HTTP 요청으로 시작될 수 있습니다. 양쪽 연결이 모두 닫히면 터널도 사라집니다. 터널은 TLS([TLS13]) 등 보안 통신을 공유 방화벽 프록시를 통해 확장할 때 사용됩니다.

위 중개자 유형은 HTTP 통신에 참여하는 경우만 고려합니다. 그 외에도 네트워크 프로토콜 스택의 하위 계층에서 동작하며, 메시지 송신자에게 알리지 않고 HTTP 트래픽을 필터링하거나 리디렉션하는 중개자가 있습니다. 네트워크 중개자는 프로토콜 수준에서 경로상의 공격자와 구별할 수 없으며, 종종 HTTP 시맨틱스를 위반하여 보안 취약점이나 상호운용성 문제를 초래합니다.

예를 들어, 인터셉션 프록시 [RFC3040](일명 투명 프록시 [RFC1919])는 HTTP 프록시와 달리 클라이언트가 선택하지 않습니다. 대신, 인터셉션 프록시는 나가는 TCP 80번 포트 패킷(및 기타 일반 포트 트래픽)을 필터링하거나 리디렉션합니다. 인터셉션 프록시는 공공 네트워크 접속 지점에서 비로컬 인터넷 서비스 이용 전에 계정 가입을 강제하거나, 기업 방화벽 내에서 네트워크 사용 정책을 적용하는 수단으로 흔히 사용됩니다.

3.8. 캐시

캐시란 이전 응답 메시지의 로컬 저장소이자, 메시지의 저장·검색·삭제를 제어하는 하위 시스템입니다. 캐시는 캐시 가능한 응답을 저장하여 이후 동일한 요청 시 응답 시간을 단축하고 네트워크 대역폭 소모를 줄입니다. 어떤 클라이언트나 서버도 캐시를 사용할 수 있습니다(MAY), 단 터널 역할을 하는 동안에는 사용할 수 없습니다.

캐시의 효과는 체인 상의 참가자 중 하나라도 해당 요청에 적용할 수 있는 캐시된 응답을 가지고 있다면 요청/응답 체인이 단축된다는 데 있습니다. 아래는 UA 또는 A에 캐시되지 않은 요청에 대해, B가 O로부터 받은 이전 응답(경유 C)을 캐싱한 경우의 체인을 보여줍니다.

            >             >
       UA =========== A =========== B - - - - - - C - - - - - - O
                  <             <

응답이 캐시 가능하다는 것은, 캐시가 이후 요청에 응답하기 위해 해당 응답 메시지의 사본을 저장할 수 있음을 의미합니다. 응답이 캐시 가능하더라도, 클라이언트 또는 오리진 서버가 특정 요청에 대해 캐시된 응답을 사용할 수 있는 시점에 추가 제약을 둘 수 있습니다. HTTP의 캐시 동작과 캐시 가능한 응답에 대한 요구 사항은 [CACHING]에 정의되어 있습니다.

전 세계 웹과 대규모 조직 내에는 다양한 구조와 구성을 가진 캐시가 배치되어 있습니다. 여기에는 대역폭 절감 및 지연 감소를 위한 국가 단위 프록시 캐시 계층, 인기 사이트의 지역·글로벌 배포 최적화를 위한 게이트웨이 캐싱 기반 콘텐츠 전송 네트워크, 캐시 항목을 브로드캐스트/멀티캐스트하는 협업 시스템, 오프라인이나 고지연 환경에서 사용할 사전 가져온 캐시 항목 아카이브 등이 포함됩니다.

3.9. 메시지 교환 예시

다음 예시는 URI "http://www.example.com/hello.txt"에 대한 GET 요청(9.3.1절)의 전형적인 HTTP/1.1 메시지 교환을 보여줍니다.

클라이언트 요청:

GET /hello.txt HTTP/1.1
User-Agent: curl/7.64.1
Host: www.example.com
Accept-Language: en, mi

서버 응답:

HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain

Hello World! My content includes a trailing CRLF.

4. HTTP의 식별자

통합 자원 식별자(URIs) [URI]는 리소스를 식별하는 수단으로 HTTP 전반에서 사용됩니다 (섹션 3.1).

4.1. URI 참조

URI 참조는 요청 대상 지정, 리디렉션 표시 및 관계 정의에 사용됩니다.

"URI-reference", "absolute-URI", "relative-part", "authority", "port", "host", "path-abempty", "segment", 및 "query"의 정의는 URI 일반 문법에서 채택됩니다. "absolute-path" 규칙은 비어 있지 않은 경로 구성요소를 포함할 수 있는 프로토콜 요소에 대해 정의됩니다. (이 규칙은 비어 있는 경로를 허용하는 RFC 3986의 path-abempty 규칙과 약간 다르며, "//"로 시작하는 경로를 허용하지 않는 path-absolute 규칙과도 다릅니다.) "partial-URI" 규칙은 단편(fragment) 구성요소를 포함하지 않는 상대 URI를 포함할 수 있는 프로토콜 요소에 대해 정의됩니다.

  URI-reference = <URI-reference, see [URI], Section 4.1>
  absolute-URI  = <absolute-URI, see [URI], Section 4.3>
  relative-part = <relative-part, see [URI], Section 4.2>
  authority     = <authority, see [URI], Section 3.2>
  uri-host      = <host, see [URI], Section 3.2.2>
  port          = <port, see [URI], Section 3.2.3>
  path-abempty  = <path-abempty, see [URI], Section 3.3>
  segment       = <segment, see [URI], Section 3.3>
  query         = <query, see [URI], Section 3.4>

  absolute-path = 1*( "/" segment )
  partial-URI   = relative-part [ "?" query ]

URI 참조를 허용하는 HTTP의 각 프로토콜 요소는 해당 ABNF 생성에서 해당 요소가 모든 형태의 참조(URI-reference)를 허용하는지, 절대 형식의 URI만 허용하는지(absolute-URI), 경로 및 선택적 쿼리 구성요소만 허용하는지(partial-URI), 또는 위의 조합을 허용하는지를 표시합니다. 달리 명시되지 않는 한, URI 참조는 대상 URI(섹션 7.1)에 상대적으로 구문 분석됩니다.

모든 발신자와 수신자가 최소한 프로토콜 요소에서 길이 8000 옥텟의 URI를 지원하는 것이 권고됨. 이는 일부 구조 및 전송 표현(예: HTTP/1.1의 요청 라인)이 경우에 따라 더 커질 수 있음을 의미합니다.

4.2. HTTP 관련 URI 스킴

IANA는 URI 스킴 등록부 [BCP35]https://www.iana.org/assignments/uri-schemes/에서 유지 관리합니다. 요청은 어떤 URI 스킴을 대상으로 할 수 있지만, 다음 스킴들은 HTTP 서버에 고유합니다:

표 2
URI 스킴 설명 섹션
http 하이퍼텍스트 전송 프로토콜 4.2.1
https 보안 하이퍼텍스트 전송 프로토콜 4.2.2

"http" 또는 "https" URI의 존재가 항상 식별된 출처(origin)에 HTTP 서버가 연결을 수신하고 있음을 의미하지는 않습니다. 누구나 URI를 만들 수 있으며, 서버의 존재 여부나 서버가 현재 해당 식별자를 리소스에 매핑하는지 여부와는 무관합니다. 등록된 이름과 IP 주소의 위임된 성격은 HTTP 서버의 존재 여부에 관계없이 연합된 네임스페이스를 만듭니다.

4.2.1. http URI 스킴

"http" URI 스킴은 주어진 포트의 TCP([TCP]) 연결을 수신하는 잠재적 HTTP 출처(origin) 서버에 의해 관리되는 계층적 네임스페이스 내에서 식별자를 생성하기 위해 정의됩니다.

  http-URI = "http" "://" authority path-abempty [ "?" query ]

"http" URI의 출처 서버는 호스트 식별자([URI], 섹션 3.2.2) 및 선택적 포트 번호([URI], 섹션 3.2.3)를 포함하는 authority 구성요소로 식별됩니다. 포트 하위 구성요소가 비어 있거나 주어지지 않으면 TCP 포트 80(WWW 서비스의 예약 포트)이 기본값입니다. 출처는 식별된 리소스를 대상으로 하는 요청에 대해 권한을 갖고 응답할 권한이 누구에게 있는지를 결정합니다(섹션 4.3.2 참조).

발신자는 호스트 식별자가 비어 있는 "http" URI를 생성해서는 반드시 해서는 안 됨. 그러한 URI 참조를 처리하는 수신자는 이를 잘못된 것으로 거부해야 한다.

계층적 경로 구성요소 및 선택적 쿼리 구성요소는 해당 출처 서버의 네임스페이스 내에서 대상 리소스를 식별합니다.

4.2.2. https URI 스킴

"https" URI 스킴은 주어진 포트에서 TCP 연결을 수신하고 HTTP 통신을 위해 보안된 TLS([TLS13]) 연결을 설정할 수 있는 잠재적 출처 서버에 의해 관리되는 계층적 네임스페이스 내에서 식별자를 생성하기 위해 정의됩니다. 여기서 보안됨은 특히 서버가 식별된 권한(authority)을 대신하여 행동하는 것으로 인증되었고, 해당 서버와의 모든 HTTP 통신이 클라이언트와 서버 모두에게 허용 가능한 기밀성 및 무결성 보호를 가진다는 것을 의미합니다.

  https-URI = "https" "://" authority path-abempty [ "?" query ]

"https" URI의 출처 서버는 authority 구성요소로 식별되며, 이는 호스트 식별자([URI], 섹션 3.2.2)와 선택적 포트 번호([URI], 섹션 3.2.3)를 포함합니다. 포트 하위 구성요소가 비어 있거나 주어지지 않으면 TCP 포트 443(HTTP over TLS의 예약 포트)이 기본값입니다. 출처는 식별된 리소스를 대상으로 하는 요청에 권한 있게 응답할 권한이 누구에게 있는지를 결정합니다(섹션 4.3.3 참조).

발신자는 호스트 식별자가 비어 있는 "https" URI를 생성해서는 반드시 해서는 안 됨. 그러한 URI 참조를 처리하는 수신자는 이를 잘못된 것으로 거부해야 한다.

계층적 경로 구성요소 및 선택적 쿼리 구성요소는 해당 출처 서버의 네임스페이스 내에서 대상 리소스를 식별합니다.

클라이언트는 "https" 리소스에 대한 HTTP 요청이 통신되기 전에 보안이 확보되었는지 반드시 확인하고, 해당 요청에 대한 응답도 보안된 응답만 수락해야 합니다. 어떤 암호화 메커니즘이 클라이언트와 서버에 허용되는지는 일반적으로 협상되어 시간이 지남에 따라 변경될 수 있습니다.

"https" 스킴을 통해 제공되는 리소스는 "http" 스킴과 정체성이 공유되지 않습니다. 이들은 별도의 네임스페이스를 갖는 서로 다른 출처입니다. 그러나 쿠키 프로토콜([COOKIE])과 같이 동일한 호스트에 대한 모든 출처에 적용되도록 정의된 HTTP의 확장들은 한 서비스에서 설정한 정보가 호스트 도메인 그룹 내의 다른 서비스와의 통신에 영향을 줄 수 있게 합니다. 이러한 확장들은 보안 연결에서 얻은 정보가 의도치 않게 보안되지 않은 컨텍스트에서 교환되지 않도록 매우 주의해서 설계되어야 합니다.

4.2.3. http(s) 정규화 및 비교

"http" 또는 "https" 스킴을 가진 URI는 섹션 6에 정의된 방법에 따라 정규화되고 비교됩니다. 여기서는 각 스킴에 대해 위에서 설명한 기본값을 사용합니다.

HTTP는 동등성 결정에 특정 방법의 사용을 요구하지 않습니다. 예를 들어, 캐시 키는 문법 기반 정규화 후 간단한 문자열로 비교되거나, 스킴 기반 정규화 후 비교될 수 있습니다.

스킴 기반 정규화(섹션 6.2.3)는 "http" 및 "https" URI에 대해 다음 추가 규칙들을 포함합니다:

  • 포트가 스킴의 기본 포트와 같으면 포트 하위 구성요소를 생략하는 것이 정규형입니다.
  • OPTIONS 요청의 대상이 아닌 경우, 빈 경로 구성요소는 "/"의 절대 경로와 동등하므로 정규형은 "/" 경로를 제공하는 것입니다.
  • 스킴과 호스트는 대소문자를 구분하지 않으며 일반적으로 소문자로 제공됩니다; 다른 모든 구성요소는 대소문자를 구분하여 비교됩니다.
  • "예약된" 집합에 속하지 않는 문자들은 해당 백분율 인코딩된 옥텟과 동등합니다: 정규형은 이를 인코딩하지 않는 것입니다(자세한 내용은 2.12.2 참조).

예를 들어, 다음 세 URI는 동등합니다:

   http://example.com:80/~smith/home.html
   http://EXAMPLE.com/%7Esmith/home.html
   http://EXAMPLE.com:/%7esmith/home.html

정규화 후(어떤 방법을 사용하든) 동등한 두 HTTP URI는 같은 리소스를 식별한다고 가정할 수 있으며, 어떤 HTTP 구성요소든 정규화할 수 있습니다. 결과적으로, 정규화 후 동등한 HTTP URI로 서로 다른 리소스를 식별해서는 안 됩니다 (rfc3986 섹션 6.2 참조).

4.2.4. http(s) URI에서 userinfo 사용 중단

권한(authority)에 대한 URI 일반 문법은 사용자 인증 정보를 URI에 포함하기 위한 userinfo 하위 구성요소([URI], 섹션 3.2.1)도 포함합니다. 해당 하위 구성요소에서 "user:password" 형식의 사용은 더 이상 권장되지 않습니다.

일부 구현은 명령 호출 옵션, 구성 파일 또는 북마크 목록 등 내부 구성의 인증 정보 저장을 위해 userinfo 구성요소를 사용하지만, 그러한 사용은 사용자 식별자나 비밀번호를 노출할 수 있습니다.

발신자는 메시지 내에서 대상 URI나 필드 값으로 "http" 또는 "https" URI 참조를 생성할 때 userinfo 하위 구성요소(및 해당 "@" 구분자)를 생성해서는 반드시 해서는 안 됩니다.

신뢰할 수 없는 출처에서 수신한 "http" 또는 "https" URI 참조를 사용하기 전에, 수신자는 userinfo를 파싱하고 그 존재를 오류로 처리하는 것이 권고됨; 이는 피싱 공격을 위해 권한을 숨기려고 사용되고 있을 가능성이 높습니다.

4.2.5. 프래그먼트 식별자가 포함된 http(s) 참조

프래그먼트 식별자는 섹션 3.5에 정의된 바와 같이, 스킴과 무관하게 부차적 리소스를 간접적으로 식별할 수 있게 합니다. 일부 프로토콜 요소는 프래그먼트를 포함할 수 있는 URI를 허용하는 반면, 다른 요소는 허용하지 않습니다. 허용되는 경우에는 해당 ABNF 규칙을 사용하여 구분하고, 그렇지 않은 경우에는 프래그먼트를 제외하는 특정 규칙을 사용합니다.

4.3. 권한 있는 접근

권한 있는 접근은 클라이언트가 권한이 있는 것으로 믿는 방식(리소스 소유자가 제어하는 방식)으로 주어진 식별자를 역참조하여 식별된 리소스에 접근하는 것을 말합니다. 접근 권한을 결정하는 과정은 URI 스킴에 의해 정의되며 일반적으로 authority 구성요소와 같은 URI 구성요소 내의 데이터를 사용합니다. 그러나 권한 있는 접근은 식별된 메커니즘에 국한되지 않습니다.

섹션 4.3.1은 이러한 사용을 돕기 위해 출처(origin)의 개념을 정의하며, 이어지는 하위 섹션들은 피어가 출처를 대표할 권한이 있는지를 확립하는 방법을 설명합니다.

권한 확립과 관련된 보안 고려사항은 섹션 17.1을 참조하십시오.

4.3.1. URI 출처(Origin)

주어진 URI의 출처는 스킴, 호스트 및 포트의 삼중으로, 스킴과 호스트는 소문자로 정규화하고 포트는 선행 0을 제거하여 정규화한 것입니다. URI에서 포트가 생략되면 해당 스킴의 기본 포트가 사용됩니다. 예를 들어, 다음 URI는

   https://Example.Com/happy.js

다음과 같은 출처를 가집니다

   { "https", "example.com", "443" }

이는 포트가 항상 포함된 정규화된 URI 접두사로도 설명할 수 있습니다:

   https://example.com:443

각 출처는 자체 네임스페이스를 정의하고 해당 네임스페이스 내의 식별자가 리소스에 어떻게 매핑되는지를 제어합니다. 결과적으로 출처가 유효한 요청에 일관되게 응답하는 방식이 URI와 연관된 의미를 결정하며, 그 의미의 유용성이 궁극적으로 사용자가 참조하고 접근할 수 있는 자원이 됩니다.

스킴, 호스트 또는 포트가 서로 다르면 두 출처는 구별됩니다. 동일한 주체가 두 개의 서로 다른 출처를 제어하는 것으로 확인되더라도, 그 출처들 아래의 두 네임스페이스는 서버가 명시적으로 별칭을 제공하지 않는 한 서로 구별됩니다.

출처는 이 문서의 범위를 벗어나 HTML 및 관련 웹 프로토콜 내에서도 사용되며, 이에 대해서는 [RFC6454]를 참조하십시오.

4.3.2. http 출처

HTTP는 전송 프로토콜과 독립적이지만, "http" 스킴(섹션 4.2.1 참조)은 표시된 호스트의 해당 포트에서 TCP 연결을 수신하는 출처 서버를 제어하는 주체와 권한을 연관시키는 데 특화되어 있습니다. 이는 클라이언트별 이름 해석 메커니즘과 경로상 공격자로부터 보안되지 않을 수 있는 통신에 의존하기 때문에 매우 약한 권한의 의미입니다. 그럼에도 불구하고 신뢰된 환경 내에서 "http" 식별자를 출처 서버에 바인딩하여 일관되게 해석하는 데 충분한 최소한의 기준입니다.

호스트 식별자가 IP 주소로 제공되면, 출처 서버는 해당 IP 주소의 표시된 TCP 포트에서 청취자(있는 경우)입니다. 호스트가 등록된 이름이면, 등록된 이름은 적절한 출처 서버의 주소를 찾기 위해 DNS와 같은 이름 해석 서비스와 함께 사용되는 간접 식별자입니다.

"http" URI가 표시된 리소스에 접근해야 하는 컨텍스트에서 사용될 때, 클라이언트는 호스트 식별자를 IP 주소로 해석하고, 해당 주소의 표시된 포트로 TCP 연결을 설정한 다음, 해당 연결을 통해 클라이언트의 대상 URI와 일치하는 요청 대상을 포함한 HTTP 요청 메시지를 전송하여 접근을 시도할 수 있습니다 (섹션 7.1 참조).

서버가 그러한 요청에 대해 비중간 응답(non-interim HTTP response message)을 반환하면(섹션 15 참조), 그 응답은 클라이언트 요청에 대한 권한 있는 응답으로 간주됩니다.

그러나 위의 방법이 권한 있는 응답을 얻는 유일한 수단은 아니며, 권한 있는 응답이 항상 필요하다는 것을 의미하지는 않습니다(캐싱 참조). 예를 들어, Alt-Svc 헤더 필드는 출처가 해당 출처에 대해 또한 권한이 있는 다른 서비스를 식별하도록 허용합니다. "http"로 식별된 리소스에 대한 접근은 이 문서의 범위를 벗어난 프로토콜에 의해서도 제공될 수 있습니다.

4.3.3. https 출처

"https" 스킴(섹션 4.2.2 참조)은 서버가 식별된 출처 서버에 대해 신뢰할 수 있는 것으로 클라이언트가 간주하는 인증서에 대응하는 개인 키를 사용할 수 있는 능력에 기반하여 권한을 연관시킵니다. 클라이언트는 일반적으로 신뢰 앵커에서 전달되는 신뢰 체인을 통해 인증서를 신뢰 가능한 것으로 간주합니다(섹션 4.3.4 참조).

HTTP/1.1 및 이전 버전에서는, 클라이언트는 URI 출처의 호스트에 대해 성공적으로 설정되고 보안된 연결을 통해 통신할 때에만 서버에 권한을 부여합니다. 연결 설정 및 인증서 확인은 권한의 증명으로 사용됩니다.

HTTP/2 및 HTTP/3에서는 클라이언트가 서버의 인증서에 포함된 호스트 중 하나와 URI 출처의 호스트가 일치하고, 클라이언트가 해당 호스트에 대해 연결을 열 수 있다고 믿는 경우, 성공적으로 설정되고 보안된 연결을 통해 통신하고 있을 때 서버에 권한을 부여합니다. 실제로 클라이언트는 기 설정된 연결과 동일한 서버 IP 주소를 가지는지 확인하기 위해 DNS 쿼리를 수행합니다. 이 제한은 출처 서버가 동등한 ORIGIN 프레임을 전송하면 제거될 수 있습니다.

요청 대상의 호스트 및 포트 값은 각 HTTP 요청에 전달되어 출처를 식별하고 동일 서버가 제어할 수 있는 다른 네임스페이스와 구별합니다(섹션 7.2 참조). 출처는 인증서의 개인 키에 대한 제어를 가진 모든 서비스가 동일하게 해당 "https" 네임스페이스를 관리하도록 하거나, 잘못 전달된 것으로 보이는 요청을 거부할 준비가 되어 있어야 합니다(섹션 7.4 참조).

출처 서버는 권한이 있어도 특정 대상 URI에 대한 요청을 처리하기를 꺼릴 수 있습니다. 예를 들어, 호스트가 서로 다른 포트(예: 443 및 8000)에서 별개의 서비스를 운영하는 경우, 연결이 확보된 후에도 대상 URI를 출처 서버에서 확인하는 것이 필요합니다. 네트워크 공격자가 한 포트의 연결을 다른 포트로 전달하게 할 수 있기 때문입니다. 대상 URI를 확인하지 않으면 공격자가 한 대상 URI의 응답을 다른 포트의 것으로 대체할 수 있습니다.

"https" 스킴은 권한을 연관시키기 위해 TCP 및 연결된 포트 번호에 의존하지 않습니다. 이는 둘 다 보안된 통신의 범위를 벗어나므로 최종적으로 신뢰할 수 없기 때문입니다. 따라서 HTTP 통신은 TCP를 사용하지 않는 프로토콜을 포함하여 섹션 4.2.2에 정의된 바와 같이 보안이 확보된 어떤 채널에서든 발생할 수 있습니다.

"https" URI가 표시된 리소스에 접근해야 하는 컨텍스트에서 사용될 때, 클라이언트는 호스트 식별자를 IP 주소로 해석하고, 해당 주소의 표시된 포트로 TCP 연결을 설정하며, TCP 위에서 TLS를 성공적으로 시작하여 종단 간 보안(기밀성 및 무결성 보호)을 확보한 다음, 해당 연결을 통해 클라이언트의 대상 URI와 일치하는 요청 대상을 포함한 HTTP 요청 메시지를 전송하여 접근을 시도할 수 있습니다 (섹션 7.1 참조).

서버가 그러한 요청에 대해 비중간 응답을 반환하면(섹션 15 참조), 그 응답은 클라이언트 요청에 대한 권한 있는 응답으로 간주됩니다.

그러나 위의 방법이 권한 있는 응답을 얻는 유일한 수단은 아니며, 권한 있는 응답이 항상 필요하다는 것을 의미하지는 않습니다(캐싱 참조).

4.3.4. https 인증서 검증

URI를 역참조하기 위해 보안된 연결을 설정하려면, 클라이언트는 서비스의 식별이 URI의 출처 서버에 대해 허용 가능한 일치인지 반드시 검증해야 합니다. 인증서 검증은 경로상 공격자나 이름 해석을 제어하는 공격자가 서버를 사칭하는 것을 방지하는 데 사용됩니다. 이 과정은 클라이언트가 신뢰 앵커 집합으로 구성되어 있어야 합니다.

일반적으로 클라이언트는 섹션 6에 정의된 검증 절차를 사용하여 서비스 식별을 검증해야 합니다. 클라이언트는 서비스의 호스트에서 참조 식별자를 구성해야 합니다: 호스트가 리터럴 IP 주소인 경우(섹션 4.3.5), 참조 식별자는 IP-ID이고, 그렇지 않으면 호스트는 이름이고 참조 식별자는 DNS-ID입니다.

CN-ID 유형의 참조 식별자는 클라이언트에 의해 사용되어서는 안 됩니다. RFC6125 섹션 6.2.1에 언급된 바와 같이, CN-ID 유형의 참조 식별자는 오래된 클라이언트에 의해 사용될 수 있습니다.

클라이언트는 특별히 구성되어 대체 형태의 서버 식별 검증을 허용할 수 있습니다. 예를 들어, 클라이언트가 주소와 호스트 이름이 동적인 서버에 연결하고, 서비스가 대상 URI의 출처와 일치하는 인증서 대신 특정 인증서(또는 외부에서 정의된 참조 식별자와 일치하는 인증서)를 제시할 것으로 기대할 수 있습니다.

특수한 경우에 클라이언트가 단순히 서버의 식별을 무시하는 것이 적절할 수 있지만, 이는 연결을 능동적 공격에 취약하게 남겨둔다는 것을 이해해야 합니다.

인증서가 대상 URI의 출처에 대해 유효하지 않으면, 사용자 에이전트는 진행하기 전에 사용자로부터 확인을 얻어야 한다 (섹션 3.5 참조) 또는 잘못된 인증서 오류로 연결을 종료해야 합니다. 자동화된 클라이언트는 오류를 적절한 감사 로그에 기록해야 하며 (가능한 경우) 연결을 종료하는 것이 권고됨. 자동화된 클라이언트는 이 검사를 비활성화하는 구성 설정을 제공할 수 있지만, 이를 활성화하는 설정을 제공해야 합니다.

4.3.5. IP-ID 참조 식별자

"https" URI의 "host" 필드에 IP 주소 리터럴이 사용된 서버는 IP-ID 유형의 참조 식별자를 가집니다. IPv4 주소는 "IPv4address" ABNF 규칙을 사용하고, IPv6 주소는 "IP-literal" 생산 규칙에서 "IPv6address" 옵션을 사용합니다(섹션 3.2.2 참조). IP-ID 유형의 참조 식별자는 IP 주소의 디코드된 바이트를 포함합니다.

IPv4 주소는 4 옥텟이고, IPv6 주소는 16 옥텟입니다. 다른 IP 버전에 대해 IP-ID 사용은 정의되지 않습니다. 인증서 subjectAltName 확장의 iPAddress 선택은 IP 버전을 명시적으로 포함하지 않으므로 주소의 길이에 의존하여 버전을 구별합니다(섹션 4.2.1.6 참조).

IP-ID 유형의 참조 식별자는 주소가 인증서의 subjectAltName 확장의 iPAddress 값과 동일한 경우 일치합니다.

5. 필드

HTTP는 확장 가능한 이름/값 쌍의 형태로 등록된 키 네임스페이스를 가진 데이터를 제공하기 위해 fields를 사용합니다. 필드는 메시지의 헤더 및 트레일러 섹션(섹션 6) 내에서 전송되고 수신됩니다.

5.1. 필드 이름

필드 이름은 해당 이름으로 정의된 의미를 갖는 대응 필드 값을 표지합니다. 예를 들어, Date 헤더 필드는 섹션 6.6.1에서 그 메시지가 생성된 시각을 포함하는 것으로 정의됩니다.

필드 이름은 대소문자를 구분하지 않으며 "Hypertext Transfer Protocol (HTTP) Field Name Registry"에 등록되는 것이 바람직합니다. 자세한 내용은 섹션 16.3.1을 보십시오.

필드의 해석은 동일한 주(major) HTTP 버전의 부( minor) 버전 간에 변경되지 않지만, 해당 필드가 없는 경우 수신자의 기본 동작은 변경될 수 있습니다. 별도로 명시되지 않는 한, 필드는 모든 버전의 HTTP에 대해 정의됩니다. 특히 요청에서의 HostConnection 필드는 HTTP/1.1 준수를 광고하든 그렇지 않든 모든 HTTP 구현에서 인식되어야 합니다.

정의된 의미가 인식하지 못하는 수신자가 안전하게 무시할 수 있게 허용하는 경우, 프로토콜 버전을 변경하지 않고 새로운 필드를 도입할 수 있습니다. 자세한 내용은 섹션 16.3을 보십시오.

프록시는 MUST 알 수 없는 헤더 필드를 전달해야 하지만, 해당 필드 이름이 Connection 헤더 필드(섹션 7.6.1)에 나열되어 있거나 프록시가 그러한 필드를 차단하거나 달리 변형하도록 명시적으로 구성된 경우는 예외입니다. 다른 수신자는 알 수 없는 헤더 및 트레일러 필드를 SHOULD 무시해야 합니다. 이러한 요구사항을 따르면 배포된 중간자(intermediaries)를 업데이트하거나 제거하지 않고도 HTTP의 기능을 확장할 수 있습니다.

5.2. 필드 라인 및 결합된 필드 값

필드 섹션은 여러 개의 field lines로 구성되며, 각 라인은 필드를 식별하는 field name (섹션 5.1 참조)과 그 필드 인스턴스의 데이터를 전달하는 field line value를 포함합니다.

섹션에 필드 이름이 한 번만 존재하는 경우, 해당 필드의 결합된 field value는 대응하는 field line value로 구성됩니다. 섹션 내에서 필드 이름이 반복되는 경우, 결합된 필드 값은 해당 섹션 내의 대응 field line value들의 목록을 순서대로 연결한 것이며, 각 field line value는 쉼표로 구분됩니다.

예를 들어, 다음 섹션:

Example-Field: Foo, Bar
Example-Field: Baz

는 필드 이름이 "Example-Field"인 두 개의 필드 라인을 포함합니다. 첫 번째 필드 라인의 값은 "Foo, Bar"이고, 두 번째는 "Baz"입니다. "Example-Field"의 필드 값은 리스트 "Foo, Bar, Baz"입니다.

5.3. 필드 순서

수신자는 동일한 필드 이름을 가진 필드 섹션 내의 여러 필드 라인을 메시지의 의미를 변경하지 않으면서 하나의 필드 라인으로 결합할 수 MAY 있습니다. 이는 초기 필드 라인 값에 후속 각 필드 라인 값을 순서대로 쉼표(",")와 선택적 공백(OWS, 섹션 5.6.3 정의)으로 구분하여 추가하는 방식으로 수행됩니다. 일관성을 위해 comma SP를 사용하는 것이 좋습니다.

따라서 동일한 이름을 가진 필드 라인들이 수신되는 순서는 필드 값의 해석에 중요합니다; 프록시는 메시지를 전달할 때 이러한 필드 라인 값의 순서를 변경해서는 안 됩니다.

이는 잘 알려진 예외를 제외하고, 발신자가 메시지(헤더나 트레일러)에 동일한 이름의 여러 필드 라인을 생성하거나 동일한 이름의 필드 라인이 이미 존재하는 경우에 필드 라인을 추가해서는 안 됩니다는 것을 의미합니다. 단, 해당 필드의 정의가 쉼표로 구분된 리스트로 다시 결합될 수 있도록 허용하는 경우(예: ABNF 규칙 #(values)처럼 섹션 5.6.1에 정의된 대안이 하나 이상 있는 경우)는 예외입니다.

섹션에서 서로 다른 필드 이름을 가진 필드 라인들이 수신되는 순서는 중요하지 않습니다. 그러나 요청에서는 Host, 응답에서는 Date와 같이 추가 제어 데이터를 포함하는 헤더 필드를 먼저 보내는 것이 구현체가 가능한 한 빨리 메시지를 처리하지 않기로 결정할 수 있게 해주므로 좋은 관행입니다.

서버는 조건부 헤더, 인증 자격 증명 또는 의도적으로 오해의 소지가 있는 중복 헤더 필드가 이후에 포함될 수 있으므로 전체 요청 헤더 섹션을 수신할 때까지 요청을 대상 리소스에 적용해서는 안 됩니다.

5.4. 필드 한계

HTTP는 각 필드 라인, 필드 값 또는 전체 헤더/트레일러 섹션의 길이에 대해 사전 정의된 제한을 두지 않습니다(섹션 2 참조). 실제로는 특정 필드의 의미에 따라 개별 길이에 대한 다양한 임시 제한이 존재합니다.

서버가 처리하기를 원하지 않는 크기의 요청 헤더 필드 라인, 필드 값 또는 필드 집합을 수신하면, 서버는 적절한 4xx (클라이언트 오류) 상태 코드로 응답해야 MUST 합니다. 이러한 헤더 필드를 무시하면 요청 스머글링 공격에 대한 서버의 취약성이 커집니다(자세한 내용은 섹션 11.2 참조).

클라이언트는 처리하기를 원하지 않는 크기의 수신된 필드 라인을 폐기하거나 잘라낼 수 MAY 있으며, 그 필드의 의미상 잘라내거나 버려도 메시지의 프레이밍 또는 응답 의미가 변경되지 않는 경우에 한합니다.

5.5. 필드 값

HTTP 필드 값은 해당 필드의 문법으로 정의된 형식의 문자 시퀀스로 구성됩니다. 각 필드의 문법은 보통 ABNF([RFC5234])를 사용하여 정의됩니다.

필드 값에는 선행 또는 후행 공백이 포함되지 않습니다. 특정 HTTP 버전에서 메시지에 이러한 공백이 나타나는 것을 허용하는 경우, 필드 파싱 구현체는 필드 값을 평가하기 전에 그러한 공백을 제외해야 MUST 합니다.

필드 값은 보통 US-ASCII 문자 범위로 제한됩니다([USASCII]). 더 넓은 문자 범위가 필요한 필드는 [RFC8187]에 정의된 인코딩과 같은 방식을 사용할 수 있습니다. 역사적으로 HTTP는 ISO-8859-1 문자셋의 텍스트가 포함된 필드 콘텐츠를 허용했으며([ISO-8859-1]), 다른 문자셋은 [RFC2047] 인코딩을 통해서만 지원되었습니다. 새로 정의되는 필드의 명세는 값들을 가시적 US-ASCII 옥텟(VCHAR), SP 및 HTAB로 제한하는 것이 좋습니다. 수신자는 필드 콘텐츠의 다른 허용 옥텟(예: obs-text)을 불투명한 데이터로 처리하는 것이 SHOULD 합니다.

필드 값에 CR, LF 또는 NUL 문자가 포함된 것은 잘못되었고 위험합니다. 구현체들이 이러한 문자를 구문 분석하고 해석하는 방식이 다양하기 때문입니다. 필드 값 내에 CR, LF 또는 NUL이 포함된 경우, 수신자는 메시지를 거부하거나 해당 문자들을 SP로 교체한 후에만 추가 처리 또는 전달을 해야 MUST 합니다. 다른 CTL 문자가 포함된 필드 값도 잘못된 것으로 간주되지만, 수신자는 그러한 문자가 안전한 문맥(예: 다운스트림 HTTP 파서가 처리하지 않을 애플리케이션 특정 인용 문자열) 내에 나타나는 경우 강인성을 위해 이를 보존할 수 MAY 합니다.

하나의 멤버만을 필드 값으로 예상하는 필드는 singleton fields라고 합니다.

여러 멤버를 필드 값으로 허용하는 필드는 list-based fields라고 합니다. 리스트 연산자 확장(섹션 5.6.1)은 여러 멤버를 포함할 수 있는 필드 값을 정의할 때 공통 표기법으로 사용됩니다.

쉼표(",")가 멤버 간 구분자로 사용되기 때문에, 멤버 내부 데이터로 쉼표가 허용되는 경우에는 주의가 필요합니다. 이는 리스트 기반 필드와 싱글턴 필드 모두에게 해당됩니다. 왜냐하면 싱글턴 필드가 실수로 여러 멤버로 전송될 수 있고, 이러한 오류를 감지하면 상호 운용성이 향상되기 때문입니다. 멤버 내부에 쉼표를 포함할 것으로 예상되는 필드(예: HTTP-date 또는 URI-reference 요소 포함)는 그 요소 주위에 구분자를 두어 해당 데이터 내의 쉼표를 잠재적 리스트 구분자와 구별해야 합니다.

예를 들어, 텍스트형 날짜와 URI(둘 다 쉼표를 포함할 수 있음)는 다음과 같이 리스트 기반 필드 값에 안전하게 포함될 수 있습니다:

Example-URIs: "http://example.com/a.html,foo",
              "http://without-a-comma.example.com/"
Example-Dates: "Sat, 04 May 1996", "Wed, 14 Sep 2005"

쌍따옴표 구분자는 거의 항상 인용 문자열(섹션 5.6.4) 생산 규칙과 함께 사용됨에 유의하십시오; 쌍따옴표 내부에서 다른 문법을 사용하면 불필요한 혼동을 초래할 가능성이 높습니다.

많은 필드(예: 섹션 Content-Type, 섹션 8.3에서 정의)는 매개변수에 대해 토큰(unquoted)과 인용된 문자열(quoted-string) 둘 다 허용하는 공통 구문을 사용합니다(섹션 5.6.6). 공통 구문을 사용하면 수신자가 기존 파서 구성요소를 재사용할 수 있습니다. 두 형태를 모두 허용할 때 매개변수 값의 의미는 토큰으로 수신되었든 인용 문자열로 수신되었든 동일해야 합니다.

5.6. 필드 값 정의를 위한 공통 규칙

5.6.1. 리스트 (#rule ABNF 확장)

RFC 5234의 ABNF 규칙에 대한 #rule 확장은 일부 리스트 기반 필드 값의 정의에서 가독성을 향상시키기 위해 사용됩니다.

"#" 구성은 요소들의 쉼표로 구분된 목록을 정의하기 위해 "*"와 유사하게 정의됩니다. 전체 형태는 "<n>#<m>element"로, 각 요소는 단일 쉼표(",")와 선택적 공백(OWS, 섹션 5.6.3 정의)으로 구분되며 최소 <n>개, 최대 <m>개 요소를 의미합니다.

5.6.1.1. 발신자 요구사항

리스트 구성(construct)을 사용하는 어떤 생성에서도, 발신자는 빈 리스트 요소를 생성해서는 MUST NOT 합니다. 다시 말해, 발신자는 다음 문법을 만족하는 리스트를 생성해야 합니다:

  1#element => element *( OWS "," OWS element )

그리고:

  #element => [ 1#element ]

그리고 n >= 1 및 m > 1인 경우:

  <n>#<m>element => element <n-1>*<m-1>( OWS "," OWS element )

부록 A는 리스트 구성들이 확장된 후 발신자를 위한 수집된 ABNF를 보여줍니다.

5.6.1.2. 수신자 요구사항

빈 요소는 존재하는 요소 수에 기여하지 않습니다. 수신자는 발신자가 값을 병합하면서 범하는 일반적인 실수를 처리할 만큼 합리적인 수의 빈 리스트 요소를 파싱하고 무시해야 MUST 합니다. 단, 서비스 거부(DoS) 메커니즘으로 악용될 만큼 많아서는 안 됩니다. 다시 말해, 수신자는 다음 문법을 만족하는 리스트를 수락해야 합니다:

  #element => [ element ] *( OWS "," OWS [ element ] )

빈 리스트 요소의 잠재적 존재 때문에 RFC 5234 ABNF는 리스트 요소의 개수를 강제할 수 없으며, 결과적으로 모든 경우는 마치 기수성이 지정되지 않은 것처럼 매핑됩니다.

예를 들어, 다음 ABNF 생산 규칙이 주어진다면:

  example-list      = 1#example-list-elmt
  example-list-elmt = token ; see Section 5.6.2

그렇다면 example-list에 대한 다음 값들은 유효합니다(구분을 위한 쌍따옴표 제외):

  "foo,bar"
  "foo ,bar,"
  "foo , ,bar,charlie"

대조적으로, 다음 값들은 유효하지 않습니다. example-list 생산 규칙은 적어도 하나의 비어있지 않은 요소를 요구하기 때문입니다:

  ""
  ","
  ",   ,"

5.6.2. 토큰

토큰은 공백 또는 구분 문자를 포함하지 않는 짧은 텍스트 식별자입니다.

  token          = 1*tchar

  tchar          = "!" / "#" / "$" / "%" / "&" / "'" / "*"
                 / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
                 / DIGIT / ALPHA
                 ; any VCHAR, except delimiters

많은 HTTP 필드 값은 공통 구문 구성요소를 사용하여 정의되며, 이는 공백 또는 특정 구분 문자로 구분됩니다. 구분자는 토큰에서 허용되지 않는 US-ASCII 시각 문자 집합에서 선택됩니다(DQUOTE 및 "(),/:;<=>?@[\]{}").

5.6.3. 공백

이 명세서는 선형 공백의 사용을 나타내기 위해 OWS(선택적 공백), RWS(필수 공백) 및 BWS("나쁜" 공백)의 세 규칙을 사용합니다.

OWS 규칙은 0개 이상의 선형 공백 옥텟이 나타날 수 있는 곳에 사용됩니다. 가독성을 높이기 위해 선택적 공백을 생성하는 것이 선호되는 프로토콜 요소의 경우, 발신자는 선택적 공백을 단일 SP로 생성하는 것이 SHOULD 합니다. 그렇지 않으면 발신자는 제자리(in-place) 메시지 필터링 중에 잘못되었거나 원치 않는 프로토콜 요소를 덮어쓰는 데 필요한 경우를 제외하고 선택적 공백을 생성해서는 SHOULD NOT 합니다.

RWS 규칙은 필드 토큰을 구분하기 위해 적어도 하나의 선형 공백 옥텟이 필요한 경우에 사용됩니다. 발신자는 RWS를 단일 SP로 생성하는 것이 SHOULD 합니다.

OWS와 RWS는 단일 SP와 동일한 의미를 갖습니다. OWS 또는 RWS로 정의된 것으로 알려진 모든 내용은 해석하거나 메시지를 하류로 전달하기 전에 단일 SP로 대체될 수 MAY 있습니다.

BWS 규칙은 문법이 역사적 이유로 선택적 공백만 허용하는 곳에 사용됩니다. 발신자는 메시지에서 BWS를 생성해서는 MUST NOT 합니다. 수신자는 그러한 잘못된 공백을 파싱하여 프로토콜 요소를 해석하기 전에 제거해야 MUST 합니다.

BWS는 의미를 갖지 않습니다. BWS로 정의된 것으로 알려진 모든 내용은 해석하거나 메시지를 전달하기 전에 제거될 수 MAY 있습니다.

  OWS            = *( SP / HTAB )
                 ; optional whitespace
  RWS            = 1*( SP / HTAB )
                 ; required whitespace
  BWS            = OWS
                 ; "bad" whitespace

5.6.4. 인용 문자열

쌍따옴표로 감싸인 경우 텍스트 스트링은 단일 값으로 구문 분석됩니다.

  quoted-string  = DQUOTE *( qdtext / quoted-pair ) DQUOTE
  qdtext         = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text

백슬래시 옥텟("\")은 quoted-string 및 comment 구성 내에서 단일 옥텟 인용 메커니즘으로 사용될 수 있습니다. quoted-string의 값을 처리하는 수신자는 quoted-pair를 백슬래시 다음의 옥텟으로 대체된 것으로 처리해야 MUST 합니다.

  quoted-pair    = "\" ( HTAB / SP / VCHAR / obs-text )

발신자는 DQUOTE 및 백슬래시 옥텟을 인용하기 위해 필요한 경우를 제외하고 quoted-string 내에서 quoted-pair를 생성해서는 SHOULD NOT 합니다. 발신자는 코멘트 내에서 괄호 "(" 및 ")" 및 백슬래시 옥텟을 인용하기 위해 필요한 경우를 제외하고 quoted-pair를 생성해서는 SHOULD NOT 합니다.

5.6.5. 코멘트

코멘트는 코멘트 텍스트를 괄호로 둘러싸서 일부 HTTP 필드에 포함될 수 있습니다. 코멘트는 필드 값 정의에 "comment"가 해당 필드 값의 일부로 포함된 필드에서만 허용됩니다.

  comment        = "(" *( ctext / quoted-pair / comment ) ")"
  ctext          = HTAB / SP / %x21-27 / %x2A-5B / %x5D-7E / obs-text

5.6.6. 매개변수

매개변수는 이름/값 쌍의 인스턴스입니다; 종종 항목에 보조 정보를 덧붙이기 위한 공통 구문으로 필드 값에서 사용됩니다. 각 매개변수는 보통 바로 앞에 오는 세미콜론으로 구분됩니다.

매개변수 이름은 대소문자를 구분하지 않습니다. 매개변수 값은 매개변수 이름의 의미에 따라 대소문자를 구분할 수도 있고 그렇지 않을 수도 있습니다. 매개변수의 예와 몇 가지 동등한 형태는 미디어 타입(섹션 8.3.1) 및 Accept 헤더 필드(섹션 12.5.1)에서 볼 수 있습니다.

token 생산 규칙과 일치하는 매개변수 값은 토큰으로 전송되거나 인용 문자열로 전송될 수 있습니다. 인용된 값과 인용되지 않은 값은 동등합니다.

5.6.7. 날짜/시간 형식

1995년 이전에는 서버들이 타임스탬프를 전달하기 위해 일반적으로 사용하던 세 가지 형식이 있었습니다. 오래된 구현체와의 호환성을 위해 세 가지 형식 모두가 여기에서 정의됩니다. 선호되는 형식은 Internet Message Format([RFC5322])에서 사용되는 날짜 및 시간 명세의 고정 길이 단일 영역(zone) 부분집합입니다.

선호되는 형식의 예는 다음과 같습니다

Sun, 06 Nov 1994 08:49:37 GMT    ; IMF-fixdate

두 가지 오래된 형식의 예는 다음과 같습니다

Sunday, 06-Nov-94 08:49:37 GMT   ; obsolete RFC 850 format
Sun Nov  6 08:49:37 1994         ; ANSI C's asctime() format

HTTP 필드에서 타임스탬프 값을 파싱하는 수신자는 세 가지 HTTP-date 형식 모두를 수용해야 MUST 합니다. 발신자가 하나 이상의 HTTP-date로 정의된 타임스탬프를 포함하는 필드를 생성할 때, 발신자는 해당 타임스탬프를 IMF-fixdate 형식으로 생성해야 MUST 합니다.

HTTP-date 값은 협정 세계시(UTC)의 인스턴스로 시간을 나타냅니다. 처음 두 형식은 "GMT"라는 세 글자 약어로 UTC를 나타내며, asctime 형식의 값은 UTC로 가정됩니다.

시계(clock)는 UTC의 현재 순간을 합리적으로 근사할 수 있는 구현체입니다. 시계 구현체는 NTP([RFC5905]) 또는 유사한 프로토콜을 사용하여 UTC와 동기화하는 것이 바람직합니다.

선호 형식:

  IMF-fixdate  = day-name "," SP date1 SP time-of-day SP GMT
  ; fixed length/zone/capitalization subset of the format
  ; see Section 3.3 of [RFC5322]

  day-name     = %s"Mon" / %s"Tue" / %s"Wed"
               / %s"Thu" / %s"Fri" / %s"Sat" / %s"Sun"

  date1        = day SP month SP year
               ; e.g., 02 Jun 1982

  day          = 2DIGIT
  month        = %s"Jan" / %s"Feb" / %s"Mar" / %s"Apr"
               / %s"May" / %s"Jun" / %s"Jul" / %s"Aug"
               / %s"Sep" / %s"Oct" / %s"Nov" / %s"Dec"
  year         = 4DIGIT

  GMT          = %s"GMT"

  time-of-day  = hour ":" minute ":" second
               ; 00:00:00 - 23:59:60 (leap second)

  hour         = 2DIGIT
  minute       = 2DIGIT
  second       = 2DIGIT

오래된 형식:

  rfc850-date  = day-name-l "," SP date2 SP time-of-day SP GMT
  date2        = day "-" month "-" 2DIGIT
               ; e.g., 02-Jun-82

  day-name-l   = %s"Monday" / %s"Tuesday" / %s"Wednesday"
               / %s"Thursday" / %s"Friday" / %s"Saturday"
               / %s"Sunday"

HTTP-date는 대소문자를 구분합니다. 캐시 수신자에 대해서는 섹션 4.2가 이를 완화한다는 점에 유의하십시오(참조: [CACHING]).

발신자는 문법에서 명시적으로 포함된 SP 이외의 추가 공백을 HTTP-date에 생성해서는 MUST NOT 합니다. day-name, day, month, year, 및 time-of-day의 의미는 해당 이름을 가진 Internet Message Format 구성과 동일합니다([RFC5322], Section 3.3 참조).

두 자리 연도를 사용하는 rfc850-date 형식의 타임스탬프 값을 수신하는 수신자는, 해당 값이 향후 50년보다 더 미래로 보이는 경우 가장 최근 과거 중 동일한 마지막 두 숫자를 가진 연도로 해석해야 MUST 합니다.

타임스탬프 값을 수신하는 수신자는 필드 정의에서 달리 제한하지 않는 한 파싱에 있어 강인성을 유지하도록 권장됩니다. 예를 들어, 메시지는 가끔 비-HTTP 원본에서 HTTP로 전달되며, 그 원본은 Internet Message Format에서 정의된 어떤 날짜 및 시간 표기법도 생성할 수 있습니다.

6. 메시지 추상화

HTTP의 각 주요 버전은 메시지를 전달하기 위한 고유한 구문을 정의합니다. 이 섹션은 이러한 메시지 특성, 공통 구조 및 의미 전달 능력을 일반화하여 HTTP 메시지에 대한 추상 데이터 타입을 정의합니다. 이 추상화는 한 버전의 메시지가 의미를 변경하지 않고 다른 버전을 통해 중계될 수 있도록, 버전에 독립적인 송신자와 수신자에 대한 요구사항을 정의하는 데 사용됩니다.

message는 다음으로 구성됩니다:

  • 메시지를 설명하고 라우팅하기 위한 제어 데이터,
  • 제어 데이터를 확장하고 송신자, 메시지, 콘텐츠 또는 컨텍스트에 대한 추가 정보를 전달하기 위한 이름/값 쌍의 headers lookup table,
  • 잠재적으로 무제한 스트림의 콘텐츠, 및
  • 콘텐츠 전송 중에 얻어진 정보를 전달하기 위한 이름/값 쌍의 trailers lookup table.

프레이밍과 제어 데이터가 먼저 전송되며, 그 다음 headers table을 위한 필드가 포함된 헤더 섹션이 전송됩니다. 메시지에 콘텐츠가 포함된 경우, 콘텐츠는 헤더 섹션 다음에 전송되고 그 뒤에 트레일러 섹션이 따라올 수 있으며 그 섹션에는 trailers table을 위한 필드가 포함될 수 있습니다.

메시지는 스트림으로 처리되는 것이 기대되며, 그 스트림의 목적과 계속되는 처리는 읽는 동안에 드러납니다. 따라서 제어 데이터는 수신자가 즉시 알아야 할 것을 설명하고, 헤더 필드는 콘텐츠를 받기 전에 알아야 할 것을 설명하며, 콘텐츠(존재하는 경우)는 수신자가 메시지 의미를 충족하기 위해 원하거나 필요로 하는 것을 포함하고, 트레일러 필드는 콘텐츠 전송 전에 알려지지 않았던 선택적 메타데이터를 제공합니다.

메시지는 자기 설명적(self-descriptive)이 되도록 의도됩니다: 수신자가 메시지에 대해 알아야 할 모든 것은 전송 중에 압축되거나 생략된 부분을 디코딩하거나 재구성한 후 메시지 자체를 살펴봄으로써 결정할 수 있어야 하며, 발신자의 현재 애플리케이션 상태(이전 메시지를 통해 수립된)를 이해할 필요가 없어야 합니다. 다만 클라이언트는 대응하는 응답을 파싱, 해석 또는 캐싱할 때 요청에 대한 지식을 보유해야 MUST 합니다. 예를 들어, HEAD 메서드에 대한 응답은 GET에 대한 응답의 시작과 비슷하게 보이지만 동일한 방식으로 파싱할 수는 없습니다.

이 메시지 추상화는 HTTP의 여러 버전 전반에 걸친 일반화임을 유의하십시오. 일부 버전에서는 찾을 수 없는 기능도 포함될 수 있습니다. 예를 들어, 트레일러는 HTTP/1.1의 chunked 전송 인코딩에서 콘텐츠 이후의 트레일러 섹션으로 도입되었습니다. 동등한 기능이 각 스트림을 종료하는 헤더 블록 내에 HTTP/2 및 HTTP/3에 존재합니다.

6.1. 프레이밍 및 완전성

메시지 프레이밍은 각 메시지가 어떻게 시작되고 끝나는지를 나타내어 동일한 연결의 다른 메시지나 잡음과 구별할 수 있도록 합니다. HTTP의 각 주요 버전은 자체 프레이밍 메커니즘을 정의합니다.

HTTP/0.9 및 초기 HTTP/1.0 배포에서는 응답을 종료하기 위해 기본 연결의 종료를 사용했습니다. 하위 호환성을 위해 이 암묵적 프레이밍은 HTTP/1.1에서도 허용됩니다. 그러나 암묵적 프레이밍은 연결이 조기에 닫히면 불완전한 응답을 구별하지 못할 수 있습니다. 이러한 이유로 대부분의 최신 구현체는 메시지 데이터의 길이 한정 시퀀스 형태의 명시적 프레이밍을 사용합니다.

메시지는 프레이밍으로 표시된 모든 옥텟이 이용 가능할 때 완전한(complete) 것으로 간주됩니다. 명시적 프레이밍이 사용되지 않을 때는, 기본 연결의 종료로 끝나는 응답 메시지는 전송 과정의 오류로 완료되지 않았다는 표시가 없는 한 완전한 것으로 간주됩니다.

6.2. 제어 데이터

메시지는 그 주요 목적을 설명하는 제어 데이터로 시작합니다. 요청 메시지의 제어 데이터에는 요청 메서드(섹션 9), 요청 대상(섹션 7.1) 및 프로토콜 버전(섹션 2.5)이 포함됩니다. 응답 메시지의 제어 데이터에는 상태 코드(섹션 15), 선택적 이유 구문, 및 프로토콜 버전이 포함됩니다.

HTTP/1.1([HTTP/1.1]) 및 이전에서는 제어 데이터가 메시지의 첫 줄로 전송됩니다. HTTP/2([HTTP/2])와 HTTP/3([HTTP/3])에서는 제어 데이터가 예약된 이름 접두사(예: ":authority")를 가진 의사-헤더(pseudo-header) 필드로 전송됩니다.

모든 HTTP 메시지는 프로토콜 버전을 가집니다. 사용 중인 버전에 따라, 메시지 내에서 명시적으로 식별되거나 메시지가 수신되는 연결에 의해 추론될 수 있습니다. 수신자는 해당 버전 정보를 사용하여 송신자와 이후 통신할 때의 제한사항이나 가능성을 판단합니다.

메시지가 중개자(intermediary)에 의해 전달될 때, 중개자가 사용하는 버전을 반영하도록 프로토콜 버전이 업데이트됩니다. 전달된 메시지 내에서 상류 프로토콜 정보를 전달하기 위해 Via 헤더 필드(섹션 7.6.3)가 사용됩니다.

클라이언트는 서버가 지원하는 것보다 높은 주요 버전을 넘지 않는 범위에서, 클라이언트가 준수하는 가장 높은 버전과 서버가 지원하는 가장 높은 버전의 주요 버전이 같을 때 그 버전과 동일한 요청 버전을 전송하는 것이 SHOULD 합니다. 클라이언트는 자신이 준수하지 않는 버전을 전송해서는 MUST NOT 합니다.

클라이언트는 서버가 HTTP 명세를 잘못 구현하는 것이 알려진 경우 더 낮은 요청 버전을 전송할 수 MAY 있지만, 이는 클라이언트가 적어도 한 번 정상 요청을 시도하고 응답 상태 코드나 헤더 필드(예: Server)로부터 서버가 더 높은 요청 버전을 잘못 처리함을 확인한 이후에만 허용됩니다.

서버는 요청에서 받은 것과 같은 주요 버전 이하의 범위에서 자신이 준수하는 가장 높은 버전과 동일한 응답 버전을 전송하는 것이 SHOULD 합니다. 서버는 자신이 준수하지 않는 버전을 전송해서는 MUST NOT 합니다. 서버는 어떤 이유로든 클라이언트의 주요 프로토콜 버전의 서비스를 거부하려는 경우 505 (HTTP Version Not Supported) 응답을 보낼 수 있습니다.

자신이 구현하는 주요 버전 번호는 같지만 구현하는 것보다 더 높은 부(마이너) 버전 번호를 가진 메시지를 수신한 수신자는 그 메시지를 자신이 준수하는 해당 주요 버전 내의 가장 높은 부 버전인 것처럼 처리하는 것이 SHOULD 합니다. 수신자는 지원을 아직 표시하지 않은 수신자에게 발송된 더 높은 부 버전의 메시지가 동일한 주요 버전의 구현이라면 충분히 하위 호환성이 있어 어떤 구현으로도 안전하게 처리될 것이라고 가정할 수 있습니다.

6.3. 헤더 필드

콘텐츠 이전에 전송되거나 수신되는 필드(섹션 5)는 "헤더 필드"(또는 구어체로는 단순히 "헤더")라고 부릅니다.

메시지의 헤더 섹션은 일련의 헤더 필드 라인으로 구성됩니다. 각 헤더 필드는 메시지 의미를 수정하거나 확장할 수 있고, 송신자를 설명하거나 콘텐츠를 정의하거나 추가 컨텍스트를 제공할 수 있습니다.

6.4. 콘텐츠

HTTP 메시지는 종종 메시지의 콘텐츠로서 완전하거나 부분적인 표현을 전송합니다: 헤더 섹션 이후, 메시지 프레이밍으로 구분된 옥텟 스트림입니다.

이 추상적 정의의 콘텐츠는 메시지 프레이밍에서 추출된 후의 데이터를 반영합니다. 예를 들어, HTTP/1.1 메시지 본문(Section 6 of [HTTP/1.1])은 chunked 전송 인코딩으로 인코딩된 데이터 스트림(데이터 청크의 시퀀스, 하나의 제로 길이 청크, 그리고 트레일러 섹션)으로 구성될 수 있지만, 동일한 메시지의 콘텐츠는 전송 인코딩이 디코딩된 이후의 데이터 스트림만 포함하며 청크 길이, chunked 프레이밍 구문, 또는 트레일러 필드는 포함하지 않습니다(섹션 6.5).

6.4.1. 콘텐츠 의미

요청의 콘텐츠 목적은 메서드 의미(섹션 9)에 의해 정의됩니다.

예를 들어, PUT 요청의 콘텐츠에 있는 표현(섹션 9.3.4)은 요청이 성공적으로 적용된 이후의 대상 리소스의 원하는 상태를 나타내고, POST 요청의 콘텐츠에 있는 표현(섹션 9.3.3)은 대상 리소스가 처리할 정보를 나타냅니다.

응답에서 콘텐츠의 목적은 요청 메서드, 응답 상태 코드(섹션 15) 및 그 콘텐츠를 설명하는 응답 필드에 의해 정의됩니다. 예를 들어, GET에 대한 200 (OK) 응답의 콘텐츠는 메시지 생성 시점(섹션 6.6.1)에 관찰된 대상 리소스의 현재 상태를 나타내는 반면, 동일한 상태 코드의 POST에 대한 응답에서의 콘텐츠는 처리 결과 또는 처리를 적용한 이후의 대상 리소스의 새 상태를 나타낼 수 있습니다.

206 (Partial Content) 응답의 콘텐츠는 GET에 대해 선택된 표현의 단일 부분이거나 그 표현의 여러 부분을 포함하는 multipart 메시지 본문을 포함합니다(섹션 15.3.7 참조).

오류 상태 코드를 가진 응답 메시지는 일반적으로 오류 상태를 나타내는 콘텐츠를 포함하며, 그 콘텐츠는 오류 상태와 이를 해결하기 위해 권장되는 단계를 설명합니다.

HEAD 요청 메서드에 대한 응답은 결코 콘텐츠를 포함하지 않습니다; 관련 응답 헤더 필드는 요청 메서드가 GET이었다면 그 값이 무엇이 되었을지를 나타내기만 합니다(섹션 9.3.1).

2xx (Successful) 응답 중 CONNECT 요청 메서드(섹션 9.3.6에 대한 응답)는 콘텐츠 대신 연결을 터널 모드로 전환합니다.

모든 1xx (Informational), 204 (No Content), 및 304 (Not Modified) 응답은 콘텐츠를 포함하지 않습니다.

그 외의 모든 응답은 콘텐츠를 포함하지만, 그 콘텐츠의 길이가 0일 수 있습니다.

6.4.2. 콘텐츠 식별

완전하거나 부분적인 표현이 메시지 콘텐츠로 전송될 때, 송신자가 해당 특정 표현에 해당하는 리소스의 식별자를 제공하거나 수신자가 이를 결정하는 것이 종종 바람직합니다. 예를 들어, "현재 기상 보고" 리소스에 대해 GET 요청을 하는 클라이언트는 반환된 콘텐츠에 특정한 식별자(예: "20210720T1711의 Laguna Beach 기상 보고")를 원할 수 있습니다. 이는 시간이 지남에 따라 표현이 변경될 것으로 예상되는 리소스에서 콘텐츠를 공유하거나 북마크하는 데 유용할 수 있습니다.

요청 메시지의 경우:

  • 요청에 Content-Location 헤더 필드가 있는 경우, 송신자는 콘텐츠가 Content-Location 필드 값으로 식별된 리소스의 표현임을 주장합니다. 다만 그러한 주장은 이 명세서에서 정의하지 않는 다른 수단으로 검증되지 않는 한 신뢰할 수 없습니다. 그 정보는 개정 이력 링크에 유용할 수 있습니다.
  • 그렇지 않으면 콘텐츠는 HTTP에 의해 식별되지 않으며, 더 구체적인 식별자는 콘텐츠 자체 내에 제공될 수 있습니다.

응답 메시지의 경우, 다음 규칙들이 일치하는 항목이 발견될 때까지 순서대로 적용됩니다:

  1. 요청 메서드가 HEAD이거나 응답 상태 코드가 204 (No Content) 또는 304 (Not Modified)이면 응답에 콘텐츠가 없습니다.
  2. 요청 메서드가 GET이고 응답 상태 코드가 200 (OK)이면, 콘텐츠는 대상 리소스의 표현입니다(섹션 7.1 참조).
  3. 요청 메서드가 GET이고 응답 상태 코드가 203 (Non-Authoritative Information)이면, 콘텐츠는 중개자가 제공하는 대상 리소스의 잠재적으로 수정되거나 향상된 표현일 수 있습니다.
  4. 요청 메서드가 GET이고 응답 상태 코드가 206 (Partial Content)이면, 콘텐츠는 대상 리소스의 표현의 하나 이상의 부분입니다.
  5. 응답에 Content-Location 헤더 필드가 있고 그 필드 값이 대상 URI와 동일한 URI에 대한 참조이면, 콘텐츠는 대상 리소스의 표현입니다.
  6. 응답에 Content-Location 헤더 필드가 있고 그 필드 값이 대상 URI와 다른 URI에 대한 참조이면, 송신자는 콘텐츠가 Content-Location 필드 값으로 식별된 리소스의 표현임을 주장합니다. 다만 그러한 주장은 이 명세서에서 정의하지 않는 다른 수단으로 검증되지 않는 한 신뢰할 수 없습니다.
  7. 그렇지 않으면 콘텐츠는 HTTP에 의해 식별되지 않지만, 더 구체적인 식별자가 콘텐츠 자체 내에 제공될 수 있습니다.

6.5. 트레일러 필드

트레일러 섹션에 위치한 필드(섹션 5)는 "트레일러 필드"(또는 구어체로는 "트레일러")라고 불립니다. 트레일러 필드는 메시지 무결성 검사, 디지털 서명, 전달 메트릭 또는 후처리 상태 정보를 제공하는 데 유용할 수 있습니다.

트레일러 필드는 헤더 섹션의 필드와 모순되는 메시지 의미를 피하기 위해 헤더 섹션의 필드와 별도로 처리되고 저장되어야 합니다. 특정 헤더 필드의 존재 여부는 트레일러가 수신되기 전에 메시지 전체의 라우팅 또는 처리 선택에 영향을 미칠 수 있으며, 이러한 선택은 이후 트레일러 필드의 발견으로 되돌릴 수 없습니다.

6.5.1. 트레일러 사용의 제한

트레일러 섹션은 사용 중인 HTTP 버전이 이를 지원하고 명시적 프레이밍 메커니즘으로 활성화된 경우에만 가능합니다. 예를 들어, HTTP/1.1의 chunked 전송 인코딩은 콘텐츠 이후에 트레일러 섹션을 보낼 수 있게 합니다(Section 7.1.2 of [HTTP/1.1]).

많은 필드는 프레이밍, 라우팅, 인증, 요청 수정자, 응답 제어 또는 콘텐츠 형식을 설명하는 등 콘텐츠를 받기 전에 평가되어야 하기 때문에 헤더 섹션 외부에서 처리될 수 없습니다. 송신자는 해당 헤더 필드 이름의 정의가 트레일러에서 전송되는 것을 허용하지 않는 한 트레일러 필드를 생성해서는 MUST NOT 합니다.

트레일러 필드는 한 프로토콜 버전에서 다른 버전으로 메시지를 전달하는 중개자에 의해 처리하기 어려울 수 있습니다. 전체 메시지를 전송 중에 버퍼링할 수 있다면 일부 중개자는 트레일러 필드를 적절한 경우 헤더 섹션에 병합한 다음 전달할 수 있습니다. 그러나 대부분의 경우 트레일러는 단순히 폐기됩니다. 수신자는 해당 헤더 필드 정의를 이해하고 그 정의가 명시적으로 트레일러 필드 값을 안전하게 병합하는 방법을 허용하고 정의하지 않는 한 트레일러 필드를 헤더 섹션에 병합해서는 MUST NOT 합니다.

요청의 TE 헤더 필드(섹션 10.1.4)에 "trailers" 키워드가 있는 것은 클라이언트가 자신과 모든 하류 클라이언트를 대신하여 트레일러 필드를 수락할 의사가 있음을 나타냅니다. 중개자로부터 오는 요청의 경우, 이는 모든 하류 클라이언트가 전달된 응답에서 트레일러 필드를 수락할 의사가 있음을 의미합니다. "trailers"의 존재가 클라이언트가 응답의 특정 트레일러 필드를 처리할 것임을 의미하지는 않습니다; 단지 트레일러 섹션이 어떤 클라이언트에 의해서도 삭제되지 않을 것임을 의미합니다.

트레일러 필드가 전송 중에 폐기될 가능성 때문에, 서버는 사용자 에이전트가 수신해야 한다고 믿는 트레일러 필드를 생성해서는 SHOULD NOT 합니다.

6.5.2. 트레일러 필드 처리

송신자가 트레일러 섹션에서 보낼 가능성이 있는 필드 이름의 목록을 나타내기 위해 "Trailer" 헤더 필드(섹션 6.6.2)를 보낼 수 있으며, 이는 수신자가 콘텐츠를 처리하기 전에 해당 메타데이터 수신을 준비할 수 있게 합니다. 예를 들어, 필드 이름이 동적 체크섬이 콘텐츠를 수신하는 동안 계산되어 트레일러 필드 값이 수신되면 즉시 확인되어야 함을 나타낼 수 있습니다.

헤더 필드와 마찬가지로 동일한 이름을 가진 트레일러 필드는 수신된 순서대로 처리됩니다; 동일한 이름을 가진 여러 트레일러 필드 라인은 여러 값을 멤버 목록으로 추가하는 것과 동등한 의미를 가집니다. 메시지 도중 여러 번 생성될 수 있는 트레일러 필드는 각 필드 라인당 멤버 값이 한 번만 처리되더라도 리스트 기반 필드로 정의되어야 MUST 합니다.

메시지 끝에서 수신자는 수신된 트레일러 필드 집합을 헤더 필드와 유사한(그러나 별개의) 이름/값 쌍의 자료 구조로 처리할 수 MAY 있습니다. 트레일러에 사용하기 위한 필드의 명세 내에서 추가 처리 기대사항이 정의될 수 있습니다.

6.6. 메시지 메타데이터

메시지 자체를 설명하는 필드(예: 메시지가 언제 어떻게 생성되었는지)는 요청과 응답 모두에 나타날 수 있습니다.

6.6.1. Date

"Date" 헤더 필드는 메시지가 생성된 날짜와 시간을 나타내며, Internet Message Format의 Origination Date Field(orig-date)와 동일한 의미를 가집니다(관련 내용은 Section 3.6.1 참조). 필드 값은 섹션 5.6.7에 정의된 HTTP-date입니다.

예시는 다음과 같습니다

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

Date 헤더 필드를 생성하는 송신자는 메시지 생성 시각의 가능한 최선의 근사값을 필드 값으로 생성하는 것이 SHOULD 합니다. 이론적으로 날짜는 메시지 콘텐츠를 생성하기 직전의 순간을 나타내야 합니다. 실무에서는 송신자가 메시지 생성 중 어느 시점에서든 날짜 값을 생성할 수 있습니다.

시계(clock)가 있는(origin server with a clock) 출처 서버는 모든 2xx (Successful), 3xx (Redirection)4xx (Client Error) 응답에서 Date 헤더 필드를 생성해야 MUST 하며, 1xx (Informational)5xx (Server Error) 응답에서는 선택적으로(Date 헤더를) 생성할 수 MAY 있습니다.

시계가 없는 출처 서버(origin server without a clock)는 Date 헤더 필드를 생성해서는 MUST NOT 합니다.

시계가 있는 수신자는 Date 헤더 필드가 없는 응답 메시지를 수신하면 수신된 시간을 기록하고 그 메시지가 캐시되거나 하류로 전달되는 경우 해당 메시지의 헤더 섹션에 상응하는 Date 헤더 필드를 추가해야 MUST 합니다.

시계가 있는 수신자가 잘못된 Date 헤더 필드 값을 가진 응답을 수신하면, 그 수신자는 해당 값을 응답이 수신된 시간으로 대체할 수 MAY 있습니다.

사용자 에이전트는 요청에 Date 헤더 필드를 보낼 수 MAY 있지만, 일반적으로 서버에 유용한 정보를 전달한다고 판단되지 않는 한 그러지 않습니다. 예를 들어, 맞춤형 HTTP 애플리케이션은 사용자 에이전트와 서버 시계 간의 차이에 따라 서버가 사용자의 요청 해석을 조정할 것으로 예상되는 경우 Date를 전달할 수 있습니다.

6.6.2. Trailer

"Trailer" 헤더 필드는 송신자가 해당 메시지의 트레일러 필드로 보낼 것으로 예상하는 필드 이름의 목록을 제공합니다. 이는 수신자가 콘텐츠 처리를 시작하기 전에 표시된 메타데이터의 수신을 준비할 수 있게 합니다.

예를 들어, 송신자가 콘텐츠를 스트리밍하는 동안 서명을 계산하고 최종 서명을 트레일러 필드로 제공할 수 있음을 나타낼 수 있습니다. 이는 수신자가 콘텐츠를 수신하는 동안 동일한 검사를 즉시 수행할 수 있게 합니다.

메시지에 하나 이상의 트레일러 필드를 생성하려는 송신자는 그 메시지의 헤더 섹션에 Trailer 헤더 필드를 생성하여 트레일러에 어떤 필드가 있을 수 있는지를 표시하는 것이 SHOULD 합니다.

중개자가 전송 중에 트레일러 섹션을 폐기하는 경우, Trailer 필드는 어떤 메타데이터가 손실되었는지에 대한 힌트를 제공할 수 있지만, Trailer를 보낸 송신자가 항상 명시된 필드를 전송할 것이라고 보장되지는 않습니다.

7. HTTP 메시지 라우팅

HTTP 요청 메시지의 라우팅은 대상 리소스, 클라이언트의 프록시 구성 및 수신(인바운드) 연결의 설정 또는 재사용을 기반으로 각 클라이언트가 결정합니다. 이에 상응하는 응답 라우팅은 동일한 연결 체인을 따라 클라이언트로 반환됩니다.

7.1. 대상 리소스 결정

HTTP는 다양한 응용에서 사용되지만, 대부분의 클라이언트는 범용 웹 브라우저와 동일한 리소스 식별 메커니즘과 구성 기법에 의존합니다. 통신 옵션이 클라이언트 구성에 하드코딩되어 있을 때조차, 그 결합된 효과는 URI 참조(섹션 4.1)로 생각할 수 있습니다.

URI 참조는 대상 URI를 얻기 위해 절대형으로 해석됩니다. 대상 URI는 참조의 fragment 구성요소(있다면)를 제외합니다. 프래그먼트 식별자는 클라이언트 측 처리를 위해 예약되어 있기 때문입니다 ([URI], 섹션 3.5).

대상 리소스에 대해 작업을 수행하려면, 클라이언트는 수신자가 동일한 리소스를 식별할 수 있도록 구문 분석된 대상 URI의 충분한 구성요소를 포함하는 요청 메시지를 전송합니다. 역사적 이유로, 구문 분석된 대상 URI 구성요소들은 합쳐서 요청 대상(request target)이라고 불리며, 메시지 제어 데이터와 Host 헤더 필드(섹션 7.2) 내에서 전송됩니다.

요청 대상 구성요소가 메서드별 형식인 두 가지 특이한 경우가 있습니다:

  • CONNECT(섹션 9.3.6)의 경우, 요청 대상은 콜론으로 구분된 터널 목적지의 호스트 이름과 포트 번호입니다.
  • OPTIONS(섹션 9.3.7)의 경우, 요청 대상은 단일 별표("*")일 수 있습니다.

자세한 내용은 해당 메서드 정의를 참조하십시오. 이러한 형식은 다른 메서드와 함께 사용해서는 안 됩니다.

클라이언트의 요청을 수신하면, 서버는 수신된 구성요소들과 로컬 구성 및 수신된 연결 컨텍스트에 따라 대상 URI를 재구성합니다. 이 재구성은 각 주요 프로토콜 버전에 특화되어 있습니다. 예를 들어, 섹션 3.3[HTTP/1.1]은 HTTP/1.1 요청의 대상 URI를 서버가 어떻게 결정하는지 정의합니다.

7.2. Host 및 :authority

요청의 "Host" 헤더 필드는 대상 URI에서 호스트 및 포트 정보를 제공하여, 동일한 서버에서 여러 호스트 이름에 대한 요청을 서비스할 때 출처 서버가 리소스를 구별할 수 있게 합니다.

HTTP/2([HTTP/2]) 및 HTTP/3([HTTP/3])에서는 경우에 따라 Host 헤더 필드가 요청 제어 데이터의 ":authority" 의사-헤더 필드로 대체됩니다.

  Host = uri-host [ ":" port ] ; Section 4

대상 URI의 authority 정보는 요청 처리에 매우 중요합니다. 사용자 에이전트는 ":authority" 의사-헤더 필드로 해당 정보를 전송하지 않는 한 요청에 Host 헤더 필드를 생성해야 MUST 합니다. Host를 전송하는 사용자 에이전트는 요청의 헤더 섹션에서 이를 첫 번째 필드로 전송하는 것이 권장됩니다.

예를 들어, <http://www.example.org/pub/WWW/>의 출처 서버에 대한 GET 요청은 다음과 같이 시작됩니다:

GET /pub/WWW/ HTTP/1.1
Host: www.example.org

호스트 및 포트 정보는 애플리케이션 수준의 라우팅 메커니즘으로 작동하므로, 공유 캐시를 오염시키거나 요청을 의도하지 않은 서버로 리디렉션하려는 악성 소프트웨어의 표적이 되는 경우가 많습니다. 특히 가로채기 프록시는 연결이 해당 호스트의 유효한 IP 주소를 대상으로 하는지 먼저 확인하지 않고 호스트 및 포트 정보를 내부 서버로의 리디렉션이나 공유 캐시의 캐시 키로 사용하는 경우에 취약합니다.

7.3. 인바운드 요청 라우팅

대상 URI와 그 출처가 결정되면, 클라이언트는 원하는 의미를 달성하기 위해 네트워크 요청이 필요한지 여부와, 필요한 경우 그 요청을 어디로 전송할지를 결정합니다.

7.3.1. 캐시로

클라이언트에 캐시([CACHING])가 있고 요청이 캐시로 만족될 수 있다면, 일반적으로 요청은 먼저 캐시로 향합니다.

7.3.2. 프록시로

요청이 캐시로 만족되지 않으면, 일반적인 클라이언트는 요청을 만족시키기 위해 프록시를 사용해야 하는지 구성에서 확인합니다. 프록시 구성은 구현에 따라 다르지만, 종종 URI 접두사 매칭, 선택적 권한(authority) 매칭 또는 둘 모두에 기반하며, 프록시는 보통 "http" 또는 "https" URI로 식별됩니다.

"http" 또는 "https" 프록시가 적용 가능한 경우, 클라이언트는 해당 프록시에 대한 연결을 설정(또는 재사용)한 다음 클라이언트의 대상 URI와 일치하는 요청 대상을 포함한 HTTP 요청 메시지를 그 프록시로 전송합니다.

7.3.3. 출처로

적용 가능한 프록시가 없으면, 일반적인 클라이언트는 대상 URI의 스킴에 특화된 핸들러 루틴을 호출하여 식별된 리소스에 접근합니다. 해당 방식은 대상 URI 스킴에 따라 달라지며 관련 명세에서 정의됩니다.

섹션 4.3.2는 식별된 출처의 origin 서버에 대한(또는 재사용된) 인바운드 연결을 설정한 다음, 클라이언트의 대상 URI와 일치하는 요청 대상을 포함한 HTTP 요청 메시지를 전송함으로써 "http" 리소스에 접근하는 방법을 정의합니다.

섹션 4.3.3은 식별된 출처에 권한이 있는 origin 서버와의 인바운드 보안 연결을 설정(또는 재사용)한 다음, 클라이언트의 대상 URI와 일치하는 요청 대상을 포함한 HTTP 요청 메시지를 전송함으로써 "https" 리소스에 접근하는 방법을 정의합니다.

7.4. 잘못 전달된 요청 거부

서버가 요청을 수신하고 대상 URI를 결정할 수 있을 만큼 파싱되면, 서버는 해당 요청을 스스로 처리할지, 다른 서버로 전달할지, 클라이언트를 다른 리소스로 리디렉션할지, 오류로 응답할지, 또는 연결을 끊을지 결정합니다. 이 결정은 요청 또는 연결 컨텍스트의 어떤 정보에 의해든 영향을 받을 수 있지만, 특히 서버가 해당 대상 URI에 대한 요청을 처리하도록 구성되었는지와 연결 컨텍스트가 해당 요청에 적합한지 여부에 초점이 맞춰집니다.

예를 들어, 받은 Host 헤더 필드의 정보가 연결의 호스트나 포트와 다르다면(의도적이거나 우발적으로) 요청이 잘못 전달되었을 수 있습니다. 연결이 신뢰할 수 있는 게이트웨이에서 온 것이라면 이러한 불일치는 예상될 수 있지만, 그렇지 않다면 보안 필터를 우회하려 하거나 비공개 콘텐츠를 제공하도록 서버를 속이거나 캐시를 오염시키려는 시도를 나타낼 수 있습니다. 메시지 라우팅과 관련된 보안 고려사항은 섹션 17을 참조하십시오.

연결이 신뢰할 수 있는 게이트웨이에서 온 것이 아닌 한, 출처 서버는 대상 URI에 대한 스킴별 요구사항이 충족되지 않으면 요청을 거부해야 MUST 합니다. 특히 "https" 리소스에 대한 요청은 해당 대상 URI의 출처에 대해 유효한 인증서로 보안된 연결을 통해 수신되지 않았다면 거부되어야 MUST 합니다(섹션 4.2.2 참조).

응답의 421 (Misdirected Request) 상태 코드는 출처 서버가 요청을 잘못 전달된 것으로 판단하여 거부했음을 나타냅니다(섹션 15.5.20).

7.5. 응답 상호 연관

하나의 연결은 여러 요청/응답 교환에 사용될 수 있습니다. 요청과 응답 메시지 간의 연관을 위한 메커니즘은 버전별로 다릅니다; 일부 HTTP 버전은 메시지의 암묵적 순서를 사용하고, 다른 버전은 명시적 식별자를 사용합니다.

모든 응답은 상태 코드에 관계없이(중간 응답 포함) 요청이 수신된 후 언제든지 전송될 수 있습니다. 응답이 그에 해당하는 요청이 완전하지 않아도 응답이 먼저 완료될 수 있습니다(섹션 6.1). 마찬가지로, 클라이언트는 응답을 기다리기 위해 특정 시간을 기다려야 할 것으로 기대되지 않습니다. 클라이언트(중개자 포함)는 응답을 합리적 기간 내에 받지 못하면 요청을 포기할 수 있습니다.

연관된 요청을 여전히 전송 중인 상태에서 응답을 받은 클라이언트는 특별한 반대 지시를 받지 않는 한 해당 요청 전송을 계속해야 SHOULD 합니다(예: 섹션 9.5 of [HTTP/1.1]Section 6.4 of [HTTP/2] 참조).

7.6. 메시지 전달

섹션 3.7에서 설명한 바와 같이, 중개자는 HTTP 요청 및 응답 처리에서 다양한 역할을 수행할 수 있습니다. 일부 중개자는 성능 또는 가용성을 향상시키기 위해 사용되며, 다른 중개자는 접근 제어나 콘텐츠 필터링을 위해 사용됩니다. HTTP 스트림은 파이프-앤-필터 아키텍처와 유사한 특성을 가지므로, 중개자가 스트림의 어느 방향이든 향상시키거나 간섭할 수 있는 정도에는 본질적 제한이 없습니다.

중개자는 다운스트림 수신자의 확장성을 보존하기 위해 프로토콜 요소(예: 새로운 메서드, 상태 코드 또는 필드 이름)를 인식하지 않더라도 메시지를 전달할 것으로 기대됩니다.

터널로 동작하지 않는 중개자는 MUST Connection 헤더 필드를 구현해야 하며(섹션 7.6.1 참조), 들어오는 연결에만 적용되는 필드를 전달하지 않도록 제외해야 합니다.

중개자는 메시지를 무한 요청 루프로부터 보호하지 않는 한 자신에게 메시지를 전달해서는 안 됩니다. 일반적으로 중개자는 자신의 서버 이름(별칭, 로컬 변형 또는 리터럴 IP 주소 포함)을 인식하고 그러한 요청에 대해서는 직접 응답해야 합니다.

HTTP 메시지는 하위 처리나 하류 전달을 위해 스트림으로 파싱될 수 있습니다. 그러나 일부 구현체는 네트워크 효율성, 보안 검사 또는 콘텐츠 변환을 위해 메시지 전달을 버퍼링하거나 지연할 수 있으므로, 송신자와 수신자는 부분 메시지의 점진적 전달에 의존할 수 없습니다.

7.6.1. Connection

"Connection" 헤더 필드는 송신자가 현재 연결에 대해 원하는 제어 옵션을 나열할 수 있게 합니다.

Connection 옵션은 대소문자를 구분하지 않습니다.

Connection 이외의 필드가 현재 연결에 대한 제어 정보를 제공하는 데 사용될 때, 송신자는 해당 필드 이름을 Connection 헤더 필드에 나열해야 MUST 합니다. 일부 HTTP 버전은 그러한 정보를 위한 필드 사용을 금지하므로 Connection 필드를 허용하지 않는다는 점에 유의하십시오.

중개자는 메시지를 전달하기 전에 수신된 Connection 헤더 필드를 파싱해야 하며, 이 필드의 각 connection-option에 대해 해당 connection-option과 동일한 이름을 가진 모든 헤더 또는 트레일러 필드를 메시지에서 제거한 다음 Connection 헤더 필드 자체를 제거해야 MUST 합니다(또는 전달된 메시지에 대한 중개자의 자체 제어 옵션으로 대체할 수 있습니다).

따라서 Connection 헤더 필드는 즉시 수신자("hop-by-hop")에만 의도된 필드와 체인상의 모든 수신자("end-to-end")를 위한 필드를 선언적으로 구분하는 방법을 제공하여, 메시지가 자기 설명적이 되게 하고 향후 연결 특정 확장이 오래된 중개자에 의해 맹목적으로 전달될 것이라는 두려움 없이 배포될 수 있게 합니다.

또한 중개자는 connection-option으로 나타나든 아니든 전달 전에 제거가 필요한 것으로 알려진 필드를 적용한 후 제거하거나 교체해야 SHOULD 합니다. 여기에는 다음이 포함되지만 이에 국한되지는 않습니다:

송신자는 콘텐츠의 모든 수신자에게 의도된 필드에 해당하는 connection option을 전송해서는 안 됩니다. 예를 들어 Cache-Control은 connection option으로 절대 적절하지 않습니다(자세한 내용은 섹션 5.2 of [CACHING] 참조).

Connection 옵션은 연결 특정 필드에 매개변수가 없으면 메시지에 존재하는 필드에 항상 해당하지 않을 수 있습니다. 반대로, 연결 옵션에 해당하는 항목 없이 수신된 연결 특정 필드는 보통 중개자가 잘못 전달했음을 나타내며 수신자는 해당 필드를 무시해야 합니다.

필드에 해당하지 않는 새로운 connection option을 정의할 때, 명세 작성자는 이후 충돌을 피하기 위해 해당 필드 이름을 어쨌든 예약해야 합니다. 이러한 예약된 필드 이름은 "Hypertext Transfer Protocol (HTTP) Field Name Registry"(섹션 16.3.1)에 등록됩니다.

7.6.2. Max-Forwards

"Max-Forwards" 헤더 필드는 TRACE(섹션 9.3.8) 및 OPTIONS(섹션 9.3.7) 요청 메서드와 함께 프록시가 요청을 전달하는 횟수를 제한하는 메커니즘을 제공합니다. 이는 클라이언트가 중간 체인에서 실패하거나 루프하는 것처럼 보이는 요청을 추적하려 할 때 유용할 수 있습니다.

Max-Forwards 값은 이 요청 메시지가 남은 전달 가능 횟수를 나타내는 10진 정수입니다.

TRACE 또는 OPTIONS 요청을 수신한 각 중개자는 전달하기 전에 Max-Forwards 값을 확인하고 업데이트해야 MUST 합니다. 수신된 값이 0이면 중개자는 요청을 전달해서는 안 됩니다; 대신 중개자는 최종 수신자로서 응답해야 MUST 합니다. 수신된 Max-Forwards 값이 0보다 크면, 중개자는 전달된 메시지에서 업데이트된 Max-Forwards 필드를 생성해야 하며 그 필드 값은 a) 수신된 값에서 1을 뺀 값 또는 b) 수신자의 Max-Forwards에 대한 최대 지원 값 중 더 작은 값입니다.

수신자는 다른 요청 메서드로 수신된 Max-Forwards 헤더 필드를 무시할 수 MAY 있습니다.

7.6.3. Via

"Via" 헤더 필드는 이메일의 "Received" 헤더 필드와 유사하게(섹션 3.6.7 of [RFC5322]), 사용자 에이전트와 서버 사이(요청의 경우) 또는 출처 서버와 클라이언트 사이(응답의 경우)에 존재하는 중간 프로토콜 및 수신자를 나타냅니다. Via는 메시지 전달 추적, 요청 루프 회피 및 요청/응답 체인상의 송신자 프로토콜 능력 식별에 사용될 수 있습니다.

Via 필드 값의 각 멤버는 메시지를 전달한 프록시나 게이트웨이를 나타냅니다. 각 중개자는 메시지를 수신한 방식에 대한 자신의 정보를 덧붙이며, 최종 결과는 전달 수신자의 순서에 따라 정렬됩니다.

프록시는 전달하는 각 메시지에 대해 아래에 설명된 적절한 Via 헤더 필드를 전송해야 MUST 합니다. HTTP-대-HTTP 게이트웨이는 수신된 각 요청 메시지에 대해 적절한 Via 헤더 필드를 전송해야 MUST 하며, 전달된 응답 메시지에 대해서는 Via 헤더 필드를 전송할 수 MAY 있습니다.

각 중개자에 대해 received-protocol은 상류 송신자가 사용한 프로토콜 및 프로토콜 버전을 나타냅니다. 따라서 Via 필드 값은 요청/응답 체인이 광고한 프로토콜 능력을 기록하여 하류 수신자가 이를 볼 수 있게 하며, 이는 응답에서 또는 이후 요청 내에서 어떤 하위 호환성 없는 기능을 사용하는 것이 안전한지 결정하는 데 유용할 수 있습니다. 간결함을 위해 received-protocol이 HTTP일 때 protocol-name은 생략됩니다.

received-by 부분은 일반적으로 메시지를 이후에 전달한 수신자 서버 또는 클라이언트의 호스트와 선택적 포트 번호입니다. 그러나 실제 호스트가 민감한 정보로 간주되면, 송신자는 이를 의사명(pseudonym)으로 대체할 수 MAY 있습니다. 포트가 제공되지 않은 경우, 수신자는 (있다면) received-protocol의 기본 포트에서 수신되었다고 해석할 수 MAY 있습니다.

송신자는 각 수신자의 소프트웨어를 식별하기 위한 주석을 생성할 수 MAY 있습니다. 이는 User-AgentServer 헤더 필드와 유사합니다. 그러나 Via의 주석은 선택 사항이며, 수신자는 전달하기 전에 이를 제거할 수 MAY 있습니다.

예를 들어, HTTP/1.0 사용자 에이전트가 내부 프록시 코드명 "fred"로 요청을 보내고, 그 프록시가 HTTP/1.1을 사용하여 p.example.net의 공용 프록시로 요청을 전달하며, 그 공용 프록시가 www.example.com의 출처 서버로 요청을 전달하여 완료하는 경우, www.example.com이 수신한 요청에는 다음과 같은 Via 헤더 필드가 포함됩니다:

Via: 1.0 fred, 1.1 p.example.net

네트워크 방화벽을 통한 포털로 사용되는 중개자는 방화벽 내부의 호스트 이름 및 포트를 전달해서는 안 됩니다 (명시적으로 허용된 경우 제외). 허용되지 않은 경우, 그러한 중개자는 방화벽 뒤의 호스트들에 대해 수신된 각 received-by 호스트를 적절한 의사명으로 대체해야 SHOULD 합니다.

중개자는 동일한 received-protocol 값을 가진 Via 헤더 필드 목록의 정렬된 부분 시퀀스를 단일 멤버로 결합할 수 MAY 있습니다. 예를 들어,

Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy

는 다음과 같이 축약될 수 있습니다

Via: 1.0 ricky, 1.1 mertz, 1.0 lucy

송신자는 모든 리스트 멤버가 동일한 조직적 통제 하에 있고 호스트들이 이미 의사명으로 교체된 경우를 제외하고는 멤버들을 결합해서는 안 됩니다. 송신자는 received-protocol 값이 다른 멤버들을 결합해서는 안 됩니다.

7.7. 메시지 변환

일부 중개자는 메시지 및 그 콘텐츠를 변환하는 기능을 포함합니다. 예를 들어, 프록시는 캐시 공간을 절약하거나 느린 링크에서 트래픽 양을 줄이기 위해 이미지 형식을 변환할 수 있습니다. 그러나 이러한 변환이 의료 영상이나 과학 데이터 분석과 같이 중요한 응용을 위한 콘텐츠에 적용될 때, 무결성 검사나 디지털 서명이 수신된 콘텐츠가 원본과 동일하다는 것을 보장하는 데 사용된다면 운영상 문제가 발생할 수 있습니다.

HTTP-대-HTTP 프록시가 의미적으로 유의미한 방식으로(즉, 정상적인 HTTP 처리로 요구되는 것을 넘어 원래 송신자에게 중요하거나 하류 수신자에게 잠재적으로 중요하게 메시지를 변경하는) 메시지들을 수정하도록 설계되거나 구성된 경우, 이를 transforming proxy라고 합니다. 예를 들어, transforming proxy는 공유 주석 서버(응답을 수정하여 로컬 주석 데이터베이스에 대한 참조를 포함), 악성코드 필터, 형식 변환기 또는 개인정보 보호 필터로 동작할 수 있습니다. 이러한 변환은 해당 프록시를 선택한 클라이언트(또는 클라이언트 조직)에 의해 원해지는 것으로 간주됩니다.

프록시는 대상 URI에 완전 자격을 갖춘 도메인 이름이 아닌 호스트 이름이 포함된 대상 URI를 수신하면, 요청을 전달할 때 받은 호스트 이름에 자체 도메인을 추가할 수 MAY 있습니다. 대상 URI가 완전 자격 도메인 이름을 포함하는 경우, 프록시는 호스트 이름을 변경해서는 안 됩니다.

프록시는 전달 프로토콜에서 요구하는 경우를 제외하고는 수신된 대상 URI의 "absolute-path" 및 "query" 부분을 다음 인바운드 서버로 전달할 때 변경해서는 안 됩니다. 예를 들어, HTTP/1.1을 통해 요청을 원본 서버로 전달하는 프록시는 빈 경로를 "/"(섹션 3.2.1 of [HTTP/1.1]) 또는 "*"(섹션 3.2.4 of [HTTP/1.1])로 대체할 수 있으며, 이는 요청 메서드에 따라 달라집니다.

응답 메시지의 콘텐츠(섹션 6.4)에 no-transform 캐시 지시자(섹션 5.2.2.6 of [CACHING])가 포함된 경우, 프록시는 그 콘텐츠를 변환해서는 안 됩니다. 단, 이는 전송 코딩의 추가 또는 제거와 같이 콘텐츠를 변경하지 않는 메시지 변환에는 적용되지 않습니다(섹션 7 of [HTTP/1.1] 참조).

프록시는 no-transform 캐시 지시자가 포함되지 않은 메시지의 콘텐츠를 변환할 수 MAY 있습니다. 200 (OK) 응답의 콘텐츠를 변환한 프록시는 응답 상태 코드를 203 (Non-Authoritative Information)으로 변경하여 변환이 적용되었음을 하류 수신자에게 알릴 수 있습니다(섹션 15.3.4).

프록시는 통신 체인의 끝점, 리소스 상태 또는 선택된 표현(selected representation)에 대한 정보를 제공하는 헤더 필드를 해당 필드의 정의가 그러한 수정을 명시적으로 허용하거나 개인 정보 보호 또는 보안을 위해 필요하다고 판단되는 경우를 제외하고는 수정해서는 안 됩니다.

7.8. Upgrade

"Upgrade" 헤더 필드는 동일한 연결에서 HTTP/1.1에서 다른 프로토콜로 전환하기 위한 간단한 메커니즘을 제공하도록 의도되었습니다.

클라이언트는 요청의 Upgrade 헤더 필드에 프로토콜 이름 목록을 보내어 서버에게 명시된 프로토콜들 중 하나 이상으로 최종 응답을 보내기 전에(우선순위 내림차순으로) 전환을 권유할 수 MAY 있습니다. 서버는 해당 연결에서 현재 프로토콜을 계속 사용하려면 수신된 Upgrade 헤더 필드를 무시할 수 MAY 있습니다. Upgrade는 프로토콜 변경을 강제하는 데 사용할 수 없습니다.

프로토콜 이름은 권장 대소문자 표기가 등록되어 있지만, 수신자는 각 protocol-name을 지원되는 프로토콜과 일치시킬 때 대소문자 구분 없는 비교를 사용해야 SHOULD 합니다.

101 (Switching Protocols) 응답을 보내는 서버는 전환되는 새 프로토콜을 나타내기 위해 반드시 Upgrade 헤더 필드를 전송해야 MUST 합니다; 다중 프로토콜 레이어가 전환되는 경우, 전송자는 프로토콜을 레이어 상승 순서로 나열해야 MUST 합니다. 서버는 클라이언트가 해당 요청의 Upgrade 헤더 필드에서 표시하지 않은 프로토콜로 전환해서는 안 됩니다. 서버는 클라이언트가 표시한 선호 순서를 무시하고 요청의 성격이나 현재 서버 부하와 같은 다른 요소에 따라 새 프로토콜을 선택할 수 MAY 합니다.

426 (Upgrade Required) 응답을 보내는 서버는 허용 가능한 프로토콜을 내림차순 선호도로 나타내는 Upgrade 헤더 필드를 반드시 전송해야 MUST 합니다.

서버는 향후 요청에 대해 나열된 프로토콜로 업그레이드 지원을 구현함을 광고하기 위해 다른 응답에서도 Upgrade 헤더 필드를 전송할 수 MAY 있습니다.

다음은 클라이언트가 보낸 가상의 예입니다:

GET /hello HTTP/1.1
Host: www.example.com
Connection: upgrade
Upgrade: websocket, IRC/6.9, RTA/x11

프로토콜 변경 후의 애플리케이션 수준 통신의 능력과 성격은 선택된 새 프로토콜에 전적으로 의존합니다. 그러나 101 (Switching Protocols) 응답을 보낸 직후 서버는 새 프로토콜 내에서 동등한 요청을 받은 것처럼 원래 요청에 계속 응답할 것으로 예상됩니다(즉, 프로토콜이 변경된 후에도 서버는 여전히 완료해야 할 요청을 가지고 있으며, 요청을 반복하도록 요구하지 않고 이를 수행할 것으로 기대됩니다).

예를 들어, Upgrade 헤더 필드가 포함된 GET 요청을 수신하고 서버가 프로토콜 전환을 결정하면, 먼저 HTTP/1.1에서 101 (Switching Protocols) 메시지로 응답한 다음 즉시 새 프로토콜에서 해당 대상 리소스에 대한 GET에 상응하는 응답을 전송합니다. 이렇게 하면 추가 왕복 지연 없이 HTTP와 동일한 의미를 갖는 프로토콜로 연결을 업그레이드할 수 있습니다. 서버는 수신된 메시지 의미가 새 프로토콜로 존중될 수 있는 경우에만 프로토콜을 전환해야 MUST NOT 합니다; OPTIONS 요청은 어떤 프로토콜로도 존중될 수 있습니다.

다음은 위의 가상 요청에 대한 예시 응답입니다:

HTTP/1.1 101 Switching Protocols
Connection: upgrade
Upgrade: websocket

[... data stream switches to websocket with an appropriate response
(as defined by new protocol) to the "GET /hello" request ...]

Upgrade를 전송하는 송신자는 또한 중개자에게 이 필드를 전달하지 않도록 알리기 위해 Connection 헤더 필드에 "Upgrade" connection option을 전송해야 MUST 합니다(섹션 7.6.1 참조). HTTP/1.0 요청에서 Upgrade 헤더 필드를 수신한 서버는 해당 Upgrade 필드를 무시해야 MUST 합니다.

클라이언트는 요청 메시지를 완전히 전송하기 전까지는 해당 연결에서 업그레이드된 프로토콜을 사용하기 시작할 수 없습니다(즉, 메시지 중간에 전송 중인 프로토콜을 변경할 수 없습니다). 서버가 "100-continue" 기대를 가진 Expect 헤더 필드와 Upgrade를 모두 수신하는 경우, 서버는 100 (Continue) 응답을 보낸 후에야 101 (Switching Protocols) 응답을 보내야 MUST 합니다.

Upgrade 헤더 필드는 기존 연결 위에서의 프로토콜 전환에만 적용되며, 기본 연결(전송) 프로토콜을 전환하거나 기존 통신을 다른 연결로 전환하는 데 사용할 수 없습니다. 그런 목적에는 3xx (Redirection) 응답(섹션 15.4)을 사용하는 것이 더 적절합니다.

이 명세서는 프로토콜 이름 "HTTP"만 Hypertext Transfer Protocols 계열에서 사용하기 위해 정의합니다(프로토콜 버전 규칙은 섹션 2.5 및 이 명세의 향후 업데이트에 따름). 추가 프로토콜 이름은 섹션 16.7에 정의된 등록 절차를 통해 등록되어야 합니다.

8. 표현 데이터 및 메타데이터

8.1. 표현 데이터 (Representation Data)

HTTP 메시지와 연관된 표현 데이터는 메시지의 콘텐츠로 제공되거나 메시지 의미와 대상 URI에 의해 참조됩니다. 표현 데이터는 표현 메타데이터 헤더 필드에 의해 정의된 형식과 인코딩으로 되어 있습니다.

표현 데이터의 데이터 형식은 Content-TypeContent-Encoding 헤더 필드를 통해 결정됩니다. 이들은 다음과 같은 2계층의 순서가 있는 인코딩 모델을 정의합니다:

  representation-data := Content-Encoding( Content-Type( data ) )

8.2. 표현 메타데이터

표현 헤더 필드는 표현에 대한 메타데이터를 제공합니다. 메시지에 콘텐츠가 포함된 경우, 표현 헤더 필드는 해당 데이터를 해석하는 방법을 설명합니다. HEAD 요청에 대한 응답에서는, 표현 헤더 필드는 동일한 요청이 GET이었다면 콘텐츠에 포함되었을 표현 데이터를 설명합니다.

8.3. Content-Type

"Content-Type" 헤더 필드는 연관된 표현의 미디어 타입을 나타냅니다: 메시지 콘텐츠에 포함된 표현이거나, 메시지 의미에 따라 결정된 selected representation입니다. 지정된 미디어 타입은 데이터 형식과, Content-Encoding으로 표시된 모든 콘텐츠 코딩이 디코딩된 이후에 수신자가 해당 수신된 메시지 의미 범위 내에서 그 데이터를 어떻게 처리해야 하는지를 정의합니다.

미디어 타입은 섹션 8.3.1에서 정의됩니다. 필드의 예시는

Content-Type: text/html; charset=ISO-8859-4

콘텐츠를 포함하는 메시지를 생성하는 발신자는 포함된 표현의 의도된 미디어 타입을 알지 못하는 경우를 제외하고, 해당 메시지에 Content-Type 헤더 필드를 생성하는 것이 SHOULD 합니다. Content-Type 헤더 필드가 없으면, 수신자는 "application/octet-stream"을 가정하거나 데이터를 검사하여 타입을 결정할 수 있습니다.

현실에서는 리소스 소유자가 항상 출처 서버를 올바르게 구성하여 특정 표현에 대해 정확한 Content-Type을 제공하지 않는 경우가 있습니다. 일부 사용자 에이전트는 콘텐츠를 검사하고 특정 경우 받은 타입을 재정의합니다(예: Sniffing 참조). 이러한 "MIME sniffing"은 데이터에 대해 잘못된 결론을 도출할 위험이 있으며(예: 권한 상승과 같은 추가 보안 위험), 서로 다른 미디어 타입이 동일한 데이터 형식을 공유하고 처리 방식만 다른 경우가 있어 데이터만으로는 구분할 수 없는 경우가 있습니다. 스니핑을 구현할 때는 사용자가 이를 비활성화할 수 있는 수단을 제공하는 것이 권장됩니다.

Content-Type은 단일필드(singleton)로 정의되지만, 때때로 잘못해서 여러 번 생성되어 결합된 필드 값이 리스트처럼 보이는 경우가 있습니다. 수신자는 이 오류를 처리하기 위해 리스트의 마지막으로 구문적으로 유효한 멤버를 사용하는 등의 시도를 하기도 하는데, 구현마다 오류 처리 동작이 달라 상호운용성 및 보안 문제가 발생할 수 있습니다.

8.3.1. 미디어 타입 (Media Type)

HTTP는 [RFC2046]에 정의된 미디어 타입을 Content-TypeAccept 헤더 필드에서 사용하여 개방적이고 확장 가능한 데이터 타입 및 타입 협상 기능을 제공합니다. 미디어 타입은 데이터 형식과 다양한 처리 모델, 즉 메시지 문맥에 따라 해당 데이터를 어떻게 처리할지를 정의합니다.

type과 subtype 토큰은 대소문자 구분이 없습니다.

type/subtype 뒤에 세미콜론으로 구분된 파라미터(섹션 5.6.6)가 name/value 쌍의 형태로 올 수 있습니다. 파라미터의 존재 여부는 미디어 타입 레지스트리 내 정의에 따라 처리에 중요할 수 있습니다. 파라미터 값은 그 이름의 의미에 따라 대소문자 구분이 있을 수도 있고 없을 수도 있습니다.

예를 들어, 다음 미디어 타입들은 UTF-8 문자 인코딩으로 인코딩된 HTML 텍스트 데이터를 설명하는 데 동등하지만, 일관성을 위해 첫 번째 형태가 선호됩니다(아래 "charset" 파라미터 값은 RFC2046에서 대소문자 구분이 없는 것으로 정의됨):

  text/html;charset=utf-8
  Text/HTML;Charset="utf-8"
  text/html; charset="utf-8"
  text/html;charset=UTF-8

미디어 타입은 IANA에 등록되어야 하며 그 절차는 [BCP13]에 정의되어 있습니다.

8.3.2. 문자셋 (Charset)

HTTP는 텍스트 표현의 문자 인코딩 체계를 지시하거나 협상하기 위해 charset 이름을 사용합니다. 이 문서에서 정의된 필드들에서는 charset 이름이 파라미터(Content-Type)로 나타나거나, 혹은 Accept-Encoding의 경우 평범한 token 형식으로 나타납니다. 두 경우 모두 charset 이름은 대소문자 구분 없이 매치됩니다.

Charset 이름은 IANA의 "Character Sets" 레지스트리에 등록되어야 하며 관련 절차는 [RFC2978]에 정의되어 있습니다.

8.3.3. 멀티파트 타입 (Multipart Types)

MIME은 하나의 메시지 본문 내에 하나 이상의 표현을 캡슐화하는 여러 "multipart" 타입을 제공합니다. 모든 multipart 타입은 공통 문법을 공유하며(Section 5.1.1 참조), 미디어 타입 값의 일부로 boundary 파라미터를 포함합니다. 메시지 본문은 자체적으로 프로토콜 요소이며; 발신자는 바디 파트 사이의 줄바꿈을 나타내기 위해 CRLF만 생성해야 MUST 합니다.

HTTP 메시지 프레이밍은 multipart 경계(boundary)를 메시지 본문 길이의 표시로 사용하지 않지만, 콘텐츠를 생성하거나 처리하는 구현에서 이를 사용할 수 있습니다. 예를 들어, "multipart/form-data" 타입은 요청에서 폼 데이터를 전송하는 데 자주 사용되며([RFC7578] 참조), "multipart/byteranges" 타입은 일부 206 (Partial Content) 응답에서 사용하기 위해 이 명세에서 정의되어 있습니다.

8.4. Content-Encoding

"Content-Encoding" 헤더 필드는 표현에 미디어 타입에 내재된 것 이외에 어떤 콘텐츠 코딩이 적용되었는지를 나타내며, 따라서 Content-Type 헤더 필드로 참조되는 미디어 타입의 데이터를 얻기 위해 어떤 디코딩 메커니즘을 적용해야 하는지를 알려줍니다. Content-Encoding은 표현의 데이터를 압축하되 그 기본 미디어 타입의 정체성을 잃지 않도록 허용하는 데 주로 사용됩니다.

사용 예:

Content-Encoding: gzip

표현에 하나 이상 인코딩이 적용된 경우, 그 인코딩을 적용한 발신자는 적용된 순서대로 콘텐츠 코딩을 나열하는 Content-Encoding 헤더 필드를 생성해야 MUST 합니다. "identity"라는 코딩 이름은 Accept-Encoding에서의 특수한 역할을 위해 예약되어 있으므로 포함해서는 안 됩니다(SHOULD NOT).

인코딩 파라미터에 대한 추가 정보는 이 명세에서 정의하지 않은 다른 헤더 필드로 제공될 수 있습니다.

Transfer-Encoding(Section 6.1 of [HTTP/1.1])과 달리, Content-Encoding에 나열된 코딩은 표현의 특성입니다; 표현은 코딩된 형태로 정의되며, 해당 표현에 대한 다른 모든 메타데이터는 특별히 명시되지 않는 한 코딩된 형태에 대한 것입니다. 일반적으로 표현은 렌더링 또는 유사한 사용 직전에 디코딩됩니다.

미디어 타입에 고유한 인코딩(예: 항상 압축된 데이터 형식)이 포함된 경우, 그 인코딩은 Content-Encoding에서 다시 명시하지 않습니다. 동일한 알고리즘이 콘텐츠 코딩 중 하나와 같더라도 그 인코딩은 표현의 일부로 간주되기 때문입니다. 또한 출처 서버는 동일한 데이터를 Content-Type이나 Content-Encoding 중 어느 쪽에 인코딩을 정의하느냐에 따라 다르게 제공할 수 있으며, 일부 사용자 에이전트는 각 응답 처리 방식이 달라질 수 있습니다(예: "다른 이름으로 저장" 대 자동 압축 해제 및 렌더링).

출처 서버는 요청 메시지의 표현에 수용할 수 없는 콘텐츠 코딩이 포함된 경우 415 (Unsupported Media Type) 상태 코드로 응답할 수 MAY 있습니다.

8.4.1. 콘텐츠 코딩 (Content Codings)

Content coding 값은 표현에 적용되었거나 적용될 수 있는 인코딩 변환을 나타냅니다. 콘텐츠 코딩은 표현을 압축하거나 유용하게 변환하여 기본 미디어 타입의 정체성을 잃지 않도록 하는 데 주로 사용됩니다. 종종 표현은 코딩된 형태로 저장되고 전송되며 최종 수신자만이 디코딩합니다.

모든 콘텐츠 코딩은 대소문자 구분이 없으며 "HTTP Content Coding Registry"에 등록되어야 합니다(섹션 16.6 참조).

Content-coding 값은 Accept-EncodingContent-Encoding 헤더 필드에서 사용됩니다.

8.4.1.1. compress 코딩

"compress" 코딩은 Lempel-Ziv-Welch (LZW) 기반의 적응형 코딩으로, UNIX의 "compress" 프로그램에서 흔히 생성됩니다. 수신자는 "x-compress"를 "compress"와 동등한 것으로 간주해야 SHOULD 합니다.

8.4.1.2. deflate 코딩

"deflate" 코딩은 "zlib" 데이터 형식([RFC1950])으로, "deflate" 압축 데이터 스트림([RFC1951])을 포함하며, 이는 LZ77 및 허프만 코딩을 결합하여 압축합니다.

8.4.1.3. gzip 코딩

"gzip" 코딩은 32비트 CRC를 갖는 LZ77 코딩으로, gzip 프로그램에서 흔히 생성됩니다. 수신자는 "x-gzip"을 "gzip"과 동등한 것으로 간주해야 SHOULD 합니다.

8.5. Content-Language

"Content-Language" 헤더 필드는 표현의 의도된 수신자 대상의 자연어를 설명합니다. 이는 표현 내에서 사용된 모든 언어와 같지 않을 수 있음을 유의하십시오.

언어 태그는 섹션 8.5.1에서 정의됩니다. Content-Language의 주요 목적은 사용자가 선호하는 언어에 따라 표현을 식별 및 구분할 수 있게 하는 것입니다. 따라서 콘텐츠가 덴마크어 독자만을 위한 것이라면 적절한 필드는

Content-Language: da

Content-Language가 지정되지 않으면, 기본적으로 해당 콘텐츠는 모든 언어 대상에게 의도된 것으로 간주됩니다. 이는 발신자가 특정 자연어에 국한되지 않거나 의도된 언어를 모르는 경우일 수 있습니다.

여러 언어가 의도된 여러 청중을 위해 표시될 수 있으며 예를 들어 다음과 같습니다:

Content-Language: mi, en

그러나 표현 내에 여러 언어가 포함되어 있다고 해서 반드시 여러 언어 대상에게 의도되었다는 뜻은 아닙니다. 예를 들어, 초급용 언어 교재는 영어 독자용일 수 있으며 이 경우 Content-Language는 "en"만 포함하는 것이 적절합니다.

Content-Language는 텍스트 문서에 국한되지 않으며 모든 미디어 타입에 적용될 수 있습니다.

8.5.1. 언어 태그 (Language Tags)

언어 태그는 [RFC5646]에 정의된 대로, 인간이 정보를 전달하기 위해 사용하는 자연어를 식별합니다. 컴퓨터 언어는 명시적으로 제외됩니다.

HTTP는 Accept-LanguageContent-Language 헤더 필드 내에서 언어 태그를 사용합니다. Accept-Language는 더 넓은 language-range 생산을 사용하고, Content-Language는 아래에 정의된 language-tag 생산을 사용합니다.

  language-tag = <Language-Tag, see [RFC5646], Section 2.1>

언어 태그는 하이픈("-")으로 구분된 하나 이상의 대소문자 구분 없는 서브태그의 시퀀스입니다. 대부분의 경우 언어 태그는 관련 언어의 넓은 군을 식별하는 기본 언어 서브태그(예: "en"=영어)를 가지며, 선택적으로 그 범위를 좁히는 일련의 서브태그가 뒤따를 수 있습니다(예: "en-CA"=캐나다식 영어). 언어 태그 내에는 공백이 허용되지 않습니다. 예시 태그:

  fr, en-US, es-419, az-Arab, x-pig-latin, man-Nkoo-GN

자세한 정보는 [RFC5646]을 참조하십시오.

8.6. Content-Length

"Content-Length" 헤더 필드는 연관된 표현의 데이터 길이를 10진수의 비음수 정수 옥텟 수로 나타냅니다. 표현을 콘텐츠로 전송할 때 Content-Length는 포함된 데이터의 양을 가리키며 프레이밍을 구분하는 데 사용됩니다. 다른 경우에는 Content-Length가 선택된 표현의 현재 길이를 나타내어 수신자가 전송 시간을 추정하거나 이전에 저장된 표현과 비교하는 데 사용할 수 있습니다.

예시:

Content-Length: 3495

사용자 에이전트는 메서드가 포함된 콘텐츠에 대한 의미를 정의하고 Transfer-Encoding을 사용하지 않는 경우 요청에 Content-Length를 보내는 것이 SHOULD 합니다. 예를 들어, 사용자 에이전트는 값이 0인 경우에도 POST 요청에 Content-Length를 보냅니다(빈 콘텐츠를 나타냄). 메서드 의미가 콘텐츠를 예상하지 않는 경우에는 Content-Length 헤더 필드를 보내서는 SHOULD NOT 합니다.

서버는 HEAD 요청에 대한 응답에서 Content-Length 헤더 필드를 보낼 수 MAY 있으며; 다만 그 값은 동일한 요청이 GET 메서드를 사용했을 때 콘텐츠로 보냈을 옥텟 수와 같아야 합니다(MUST NOT 아님).

서버는 조건부 GET 요청에 대한 304 (Not Modified) 응답에 Content-Length를 보낼 수 MAY 있으나; 그 값은 동일한 요청에 대해 200 (OK) 응답에서 보냈을 콘텐츠의 옥텟 수와 같아야 합니다(MUST NOT).

서버는 1xx 또는 204 (No Content) 상태 코드의 응답에서 Content-Length 헤더 필드를 보내서는 MUST NOT 합니다. 또한 CONNECT 요청에 대한 2xx 응답에서는 Content-Length를 보내서는 MUST NOT 합니다.

위에 정의된 경우를 제외하고, Transfer-Encoding이 없을 때 출처 서버는 콘텐츠 크기를 전체 헤더 섹션을 보내기 전에 알 수 있다면 Content-Length 헤더 필드를 보내는 것이 SHOULD 합니다. 이는 하류 수신자가 전송 진행을 측정하고 메시지 완료 시점을 알며 연결을 재사용할 수 있게 해줍니다.

0 이상인 모든 Content-Length 값은 유효합니다. 콘텐츠 길이에 대한 사전 정의된 제한이 없으므로, 수신자는 잠재적으로 큰 10진 숫자를 처리할 수 있어야 하며 정수 변환 오버플로우나 정밀도 손실을 방지해야 합니다.

Content-Length는 HTTP/1.1에서 메시지 구분에 사용되므로, 그 값은 즉시 연결이 HTTP/1.1을 사용하지 않더라도 하류 수신자의 메시지 파싱 방식에 영향을 줄 수 있습니다. 중개자가 메시지를 전달하는 경우, 수신된 메시지 프레이밍과 일치하지 않는 Content-Length 값은 요청 스머글링이나 응답 분할과 같은 보안 실패를 초래할 수 있습니다.

따라서 발신자는 알려진 잘못된 Content-Length 값으로 메시지를 전달해서는 MUST NOT 합니다.

마찬가지로, 발신자는 위 ABNF와 일치하지 않는 Content-Length 필드 값을 가진 메시지를 전달해서는 MUST NOT 합니다. 단 하나의 예외는 동일한 10진 값이 쉼표로 구분된 리스트로 반복된 경우(예: "Content-Length: 42, 42")에는 수신자가 메시지를 잘못된 것으로 거부하거나 그 잘못된 필드 값을 단일 인스턴스의 10진 값으로 교체할 수 MAY 있다는 것입니다.

8.7. Content-Location

"Content-Location" 헤더 필드는 이 메시지의 콘텐츠에 있는 표현에 해당하는 특정 리소스의 식별자로 사용할 수 있는 URI를 참조합니다. 즉, 메시지 생성 시점에 이 URI로 GET 요청을 하면 응답(200 OK)이 이 메시지에 포함된 것과 동일한 표현을 포함할 것이라는 의미입니다.

필드 값은 absolute-URI 또는 partial-URI입니다. 후자의 경우(섹션 4 참조), 참조된 URI는 대상 URI를 기준으로 한 상대적 참조입니다.

Content-Location 값은 대상 URI의 대체물이 아닙니다(섹션 7.1). 이는 표현 메타데이터입니다. MIME 본문 파트에서 동일한 이름의 헤더 필드에 대해 정의된 문법 및 의미와 동일한 문법을 가지지만, HTTP 메시지에 표시될 때는 HTTP 수신자에 대해 몇 가지 특별한 함의를 갖습니다.

Content-Location이 2xx (Successful) 응답 메시지에 포함되고, 그 값이 절대형으로 변환했을 때 대상 URI와 동일한 URI를 참조하면, 수신자는 그 콘텐츠를 메시지 생성 시점에 해당 리소스의 최신 표현으로 간주할 수 MAY 있습니다. GET 또는 HEAD 요청에 대한 응답의 경우, 이는 서버가 Content-Location을 제공하지 않은 기본 의미와 같습니다. PUT 또는 POST와 같은 상태 변환 요청의 경우, 이는 서버의 응답이 그 리소스의 새로운 표현을 포함함을 의미할 수 있으며, 이는 후속 GET 요청 없이도 작성 도구가 로컬 사본을 업데이트할 수 있게 합니다.

Content-Location이 2xx 응답에 포함되고 그 값이 대상 URI와 다른 URI를 참조하면, 출처 서버는 그 URI가 이 메시지에 포함된 표현에 해당하는 다른 리소스의 식별자라고 주장하는 것입니다. 이러한 주장은 양 식별자가 동일한 리소스 소유자를 공유할 때만 신뢰할 수 있으며, 이는 HTTP를 통해 프로그램적으로 결정할 수 없습니다.

  • GET 또는 HEAD 요청에 대한 응답의 경우, 이는 대상 URI가 콘텐츠 협상에 종속되는 리소스를 가리키며 Content-Location 값이 선택된 표현에 대한 더 구체적 식별자임을 나타냅니다.
  • 상태 변경 메서드에 대한 201 (Created) 응답에서, Content-Location 필드 값이 Location 필드 값과 동일하면 이 콘텐츠가 새로 생성된 리소스의 현재 표현임을 나타냅니다.
  • 그렇지 않으면, 해당 Content-Location은 이 콘텐츠가 요청된 작업의 상태를 보고하는 표현이며 동일한 보고서를 향후 GET으로 접근할 수 있음을 나타냅니다. 예를 들어 POST 요청으로 수행된 구매 거래의 영수증 문서를 200 응답의 콘텐츠로 포함할 수 있으며, Content-Location은 향후 동일한 영수증을 검색하기 위한 식별자를 제공합니다.

요청 메시지에 Content-Location을 담아 보내는 사용자 에이전트는 그 값이 자신이 원래 얻은(수정 전) 표현의 출처를 가리킨다고 진술하는 것입니다. 즉, 사용자 에이전트는 원래 표현의 소스로의 백링크를 제공하고 있습니다.

출처 서버는 요청 메시지에서 Content-Location 필드를 수신하면 그 정보를 표현의 일부로 그대로 저장할 메타데이터가 아니라 일시적인 요청 문맥으로 처리해야 MUST 합니다. 출처 서버는 그 문맥을 처리 안내나 소스 링크 또는 버전 관리 메타데이터 같은 다른 용도로 저장할 수 MAY 있지만, 요청 의미를 변경하는 데 사용해서는 MUST NOT 합니다.

예를 들어, 클라이언트가 협상된 리소스에 대해 PUT 요청을 하고 출처 서버가 그 PUT을 수락하면, 그 리소스의 새 상태는 해당 PUT에서 제공된 표현과 일관되어야 합니다. Content-Location은 협상된 표현들 중 하나만 선택적으로 업데이트하기 위한 역선택 식별자로 사용될 수 없습니다. 그런 의미를 원했다면 사용자 에이전트는 PUT을 Content-Location URI로 직접 적용했어야 합니다.

8.8. 밸리데이터 필드 (Validator Fields)

리소스 메타데이터는 조건문(섹션 13.1) 내에서 조건 요청(섹션 13)을 만들기 위해 사용될 수 있으면 validator로 지칭됩니다. 밸리데이터 필드는 selected representation에 대한 현재 밸리데이터를 전달합니다.

안전한 요청에 대한 응답에서 밸리데이터 필드는 응답을 처리하는 동안 출처 서버가 선택한 표현을 설명합니다. 메서드와 상태 코드 의미에 따라 특정 응답의 선택된 표현이 응답 콘텐츠로 포함된 표현과 반드시 동일하지 않을 수도 있음을 유의하십시오.

상태 변경 요청에 대한 성공적인 응답에서는 밸리데이터 필드가 요청 처리의 결과로 이전의 선택된 표현을 대체한 새 표현을 설명합니다.

예를 들어, 201 (Created) 응답의 ETag 필드는 새로 생성된 리소스 표현의 엔터티 태그를 전달하여, 이후의 조건 요청에서 "lost update" 문제를 방지하기 위한 밸리데이터로 사용할 수 있게 합니다.

이 명세서는 자원 상태를 관찰하고 사전 조건을 테스트하는 데 일반적으로 사용되는 두 가지 형태의 메타데이터를 정의합니다: 수정 날짜(섹션 8.8.2)와 불투명 엔터티 태그(섹션 8.8.3). 추가적인 리소스 상태를 반영하는 메타데이터는 WebDAV 등 HTTP 확장에 의해 정의되어 있으며 이 명세의 범위 밖입니다.

8.8.1. 약한 밸리데이터 vs 강한 밸리데이터

밸리데이터는 강하거나 약한 두 가지 유형이 있습니다. 약한 밸리데이터는 생성하기 쉽지만 비교에 있어 덜 유용합니다. 강한 밸리데이터는 비교에 이상적이지만 효율적으로 생성하기 매우 어렵거나 불가능할 수 있습니다. 모든 자원에 동일한 강도의 밸리데이터를 강요하기보다는, HTTP는 사용 중인 밸리데이터 유형을 노출하고 약한 밸리데이터를 전제로 사용할 때의 제한을 부과합니다.

강한 밸리데이터는 GET에 대한 200 (OK) 응답의 콘텐츠에서 관찰 가능한 표현 데이터에 변경이 일어날 때마다 값이 변경되는 표현 메타데이터입니다.

강한 밸리데이터는 표현 데이터 변경 외의 이유(예: 의미상 중요한 표현 메타데이터 변경)가 있어도 변경될 수 있지만, 출처 서버는 원격 캐시 및 저작 도구가 저장한 응답을 무효화해야 할 때만 값을 변경하는 것이 바람직합니다.

캐시 항목은 만료 시간과 관계없이 임의의 기간 동안 지속될 수 있으므로, 캐시는 오래전에 얻은 밸리데이터로 항목을 검증하려고 할 수 있습니다. 강한 밸리데이터는 특정 리소스에 연결된 모든 표현 버전 전반에 대해 고유해야 합니다. 다만 서로 다른 리소스의 표현 간에는 고유성을 보장하지 않습니다.

실무에서 사용되는 다양한 강한 밸리데이터가 있습니다. 최선의 방법은 각 변경마다 고유한 노드 이름과 수정 식별자를 할당하는 엄격한 버전 관리 기반입니다. 표현 데이터에 대한 충돌 저항 해시를 사용하는 것도 충분할 수 있습니다(응답 헤더가 전송되기 전에 데이터가 사용 가능하고, 검증 요청마다 재계산할 필요가 없는 경우). 단, 동일한 데이터 형식을 공유하지만 메타데이터가 다른 동시 표현이 있는 경우 출처 서버는 그런 표현들을 구분하기 위해 밸리데이터에 추가 정보를 포함해야 합니다.

대조적으로, 약한 밸리데이터는 표현 데이터의 모든 변경마다 값이 바뀌지 않을 수 있습니다. 이 약함은 값 계산 방식의 한계(예: 시계 해상도), 모든 가능한 표현에 대해 고유성을 보장할 수 없음, 또는 리소스 소유자가 표현들을 자체적으로 동치로 묶고자 하는 경우 등 때문일 수 있습니다.

출처 서버는 이전 표현이 현재 표현의 대체물로서 부적절하다고 간주될 때 약한 엔터티 태그를 변경해야 SHOULD 합니다. 즉, 출처 서버는 캐시가 오래된 응답을 무효화하도록 원할 때 약한 엔터티 태그를 변경해야 합니다.

예를 들어, 초단위로 콘텐츠가 변경되는 기상 보고서의 표현은 출처 서버 관점에서 동등한 표현 집합으로 그룹화되어 동일한 약한 밸리데이터를 가질 수 있으며, 이는 캐시된 표현이 합리적인 기간 동안 유효하도록 허용할 수 있습니다.

또한 밸리데이터가 동일한 리소스의 둘 이상의 표현에 동시에 공유되는 경우(그 표현들이 동일한 표현 데이터가 아닌 한) 그 밸리데이터는 약한 것으로 간주됩니다. 예를 들어, gzip 코딩이 적용된 표현과 적용되지 않은 표현에 대해 동일한 밸리데이터를 보낸다면 그 밸리데이터는 약합니다. 반면, 표현 메타데이터만 다른 두 동시 표현이 동일한 강한 밸리데이터를 가질 수는 있습니다.

강한 밸리데이터는 캐시 검증, 범위 요청, "lost update" 회피 등 모든 조건 요청에 사용할 수 있습니다. 약한 밸리데이터는 클라이언트가 이전에 얻은 표현 데이터와의 정확한 동일성을 요구하지 않을 때만 사용 가능합니다.

8.8.2. Last-Modified

응답의 "Last-Modified" 헤더 필드는 출처 서버가 선택된 표현이 마지막으로 수정되었다고 믿는 날짜 및 시간을 타임스탬프로 제공합니다(요청 처리 종료 시 기준).

사용 예:

Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
8.8.2.1. 생성 (Generation)

출처 서버는 마지막 수정 날짜를 합리적이고 일관되게 결정할 수 있는 선택된 표현에 대해 Last-Modified를 전송하는 것이 SHOULD 합니다. 이는 조건 요청과 캐시 신선도 평가에 유용하여 불필요한 전송을 줄이고 서비스 가용성과 확장성을 크게 개선할 수 있습니다.

표현은 일반적으로 리소스 인터페이스 뒤의 많은 부분의 합입니다. 마지막 수정 시간은 보통 그 부분들 중 어느 하나가 변경된 가장 최근 시간입니다. 해당 값이 어떻게 결정되는지는 구현 세부사항으로 이 명세의 범위를 벗어납니다.

출처 서버는 응답을 위한 Date 필드 값을 생성하는 시점에 가능한 한 가깝게 Last-Modified 값을 얻어야 SHOULD 합니다. 이는 표현이 응답 생성 시점 근처에서 변경되는 경우 수신자가 수정 시간을 정확히 판단하는 데 도움이 됩니다.

시계가 있는 출처 서버는 응답 생성 시간보다 이후의 Last-Modified 날짜를 생성해서는 MUST NOT 합니다. 만약 마지막 수정 시간이 출처 서버의 시계에 따라 미래로 평가되는 구현별 메타데이터에서 유도된다면, 출처 서버는 그 값을 메시지 생성 날짜로 대체해야 MUST 합니다. 이는 미래의 수정 날짜가 캐시 검증에 악영향을 미치는 것을 방지합니다.

시계가 없는 출처 서버는 해당 날짜 값이 다른 시스템(아마도 시계를 가진 시스템)에 의해 할당된 경우를 제외하고 Last-Modified 날짜를 생성해서는 MUST NOT 합니다.

8.8.2.2. 비교 (Comparison)

요청에서 밸리데이터로 사용되는 Last-Modified 시간은 아래 규칙에 따라 강한 것으로 추론되지 않는 한 암묵적으로 약한 것으로 간주됩니다:

  • 밸리데이터가 출처 서버에 의해 해당 표현의 실제 현재 밸리데이터와 비교되고,
  • 그 출처 서버가 제시된 밸리데이터가 가리키는 초 동안에 표현이 두 번 변경되지 않았음을 신뢰할 수 있게 알고 있는 경우;

또는

  • 클라이언트가 캐시 항목을 가지고 있어 해당 밸리데이터를 If-Modified-Since, If-Unmodified-Since 또는 If-Range에 사용하려는 경우,
  • 그 캐시 항목에 포함된 Date 값이 Last-Modified 값보다 최소 1초 이상 이후이고, 클라이언트가 그들이 동일한 시계에 의해 생성되었거나 Last-Modified와 Date 값 사이의 차이가 시계 동기화 문제를 일으킬 가능성이 낮을 만큼 충분히 크다고 믿을 만한 이유가 있는 경우;

또는

  • 밸리데이터가 중개자 캐시에서 자신이 저장한 캐시 항목의 밸리데이터와 비교되는 경우, 그리고
  • 그 캐시 항목에 포함된 Date 값이 Last-Modified 값보다 최소 1초 이상 이후이고, 캐시가 그들이 동일한 시계에 의해 생성되었거나 값들의 차이가 시계 동기화 문제를 발생시킬 가능성이 낮다고 믿을 만한 이유가 있는 경우.

이 방법은 동일한 초 동안 출처 서버가 서로 다른 두 응답을 보냈는데 둘 다 동일한 Last-Modified 시간을 가졌다면, 적어도 그 중 하나의 응답은 Date 값이 Last-Modified와 같을 것이라는 사실에 의존합니다.

8.8.3. ETag

응답의 "ETag" 필드는 요청 처리 종료 시 결정된 선택된 표현에 대한 현재 엔터티 태그를 제공합니다. 엔터티 태그는 동일 리소스의 여러 표현을 구별하기 위한 불투명한 밸리데이터로, 시간 경과에 따른 상태 변화, 콘텐츠 협상으로 인해 동일 시점에 복수 표현이 유효한 경우 등 다양한 경우에 사용됩니다. 엔터티 태그는 약점 표시가 접두된 불투명한 인용 문자열로 구성됩니다.

  ETag       = entity-tag

  entity-tag = [ weak ] opaque-tag
  weak       = %s"W/"
  opaque-tag = DQUOTE *etagc DQUOTE
  etagc      = %x21 / %x23-7E / obs-text
             ; VCHAR except double quotes, plus obs-text

엔터티 태그는 수정 날짜보다 검증에 더 신뢰할 수 있는 경우가 있습니다(예: 수정 날짜 저장이 불편하거나 초 해상도가 충분치 않은 경우).

예시:

ETag: "xyzzy"
ETag: W/"xyzzy"
ETag: ""

엔터티 태그는 약하거나 강한 밸리데이터일 수 있으며 기본값은 강한 것입니다. 만약 출처 서버가 엔터티 태그를 제공했지만 그것이 강한 밸리데이터의 특성을 모두 만족하지 못한다면, 출처 서버는 불투명 값 앞에 "W/" 접두어를 붙여 그 태그를 약한 것으로 표시해야 MUST 합니다.

발신자는 ETag 필드를 트레일러 섹션에서 보낼 수 MAY 있습니다(섹션 6.5 참조). 그러나 트레일러는 종종 무시되므로, 엔터티 태그가 콘텐츠 전송 중 생성되는 경우를 제외하고는 헤더 필드로 보내는 것이 바람직합니다.

8.8.3.1. 생성 (Generation)

엔터티 태그의 원리는 서비스 작성자만이 해당 리소스의 구현을 충분히 잘 알고 있어 그 리소스에 가장 정확하고 효율적인 검증 메커니즘을 선택할 수 있다는 것입니다. 그런 메커니즘은 간단한 옥텟 시퀀스로 매핑될 수 있으므로 클라이언트는 각 엔터티 태그가 어떻게 구성되는지 알 필요가 없습니다.

예를 들어, 모든 변경에 대해 구현별 버전 관리가 적용되는 리소스는 내부 수정 번호를 사용하거나, 콘텐츠 협상에 대한 분기 식별자와 결합하여 표현을 정확히 구별할 수 있습니다. 다른 구현은 표현 콘텐츠의 충돌 저항 해시, 여러 파일 속성의 조합, 또는 초 이하 해상도의 수정 타임스탬프를 사용할 수 있습니다.

출처 서버는 변경 감지가 합리적이고 일관되게 결정될 수 있는 선택된 표현에 대해 ETag를 전송하는 것이 SHOULD 합니다. 이는 조건 요청과 캐시 신선도 평가에 사용되어 불필요한 전송을 크게 줄이고 서비스 가용성, 확장성, 신뢰성을 향상시킬 수 있습니다.

8.8.3.2. 비교 (Comparison)

비교 문맥이 약한 밸리데이터의 사용을 허용하는지 여부에 따라 두 가지 엔터티 태그 비교 함수가 있습니다:

강한 비교 (Strong comparison):
두 엔터티 태그가 둘 다 약하지 않고 opaque-tags가 문자 단위로 일치하면 동등합니다.
약한 비교 (Weak comparison):
두 엔터티 태그의 opaque-tags가 문자 단위로 일치하면, 두 태그 중 하나 또는 둘 다 "weak"으로 표시되어 있어도 동등합니다.

다음 예시는 엔터티 태그 쌍에 대한 약한 비교 및 강한 비교 결과를 보여줍니다:

Table 3
ETag 1 ETag 2 강한 비교 약한 비교
W/"1" W/"1" 불일치 일치
W/"1" W/"2" 불일치 불일치
W/"1" "1" 불일치 일치
"1" "1" 일치 일치
8.8.3.3. 예시: 콘텐츠 협상 리소스에서 엔터티 태그의 차이

콘텐츠 협상에 종속되는 리소스를 고려해보십시오(섹션 12). 이 리소스에 대한 GET 요청에 대해 응답되는 표현이 Accept-Encoding 요청 헤더 필드에 따라 달라질 수 있습니다:

>> 요청:

GET /index HTTP/1.1
Host: www.example.com
Accept-Encoding: gzip

이 경우 응답은 gzip 콘텐츠 코딩을 사용하거나 사용하지 않을 수 있습니다. 사용하지 않는다면 응답은 다음과 같을 수 있습니다:

>> 응답:

HTTP/1.1 200 OK
Date: Fri, 26 Mar 2010 00:05:00 GMT
ETag: "123-a"
Content-Length: 70
Vary: Accept-Encoding
Content-Type: text/plain

Hello World!
Hello World!
Hello World!
Hello World!
Hello World!

대안으로 gzip 콘텐츠 코딩을 사용하는 표현은 다음과 같을 수 있습니다:

>> 응답:

HTTP/1.1 200 OK
Date: Fri, 26 Mar 2010 00:05:00 GMT
ETag: "123-b"
Content-Length: 43
Vary: Accept-Encoding
Content-Type: text/plain
Content-Encoding: gzip

...binary data...

9. 메서드 (Methods)

9.1. 개요 (Overview)

요청 메서드 토큰은 요청 의미의 주요 출처입니다. 이는 클라이언트가 이 요청을 수행한 목적과 클라이언트가 성공 결과로 기대하는 바를 나타냅니다.

요청 메서드의 의미는 요청에 포함된 일부 헤더 필드의 의미로 추가로 특수화될 수 있습니다(해당 추가 의미가 메서드와 충돌하지 않는 경우). 예를 들어, 클라이언트는 조건부 요청 헤더 필드(섹션 13.1)를 전송하여 요청된 동작을 대상 리소스의 현재 상태에 조건화할 수 있습니다.

HTTP는 분산 객체 시스템의 인터페이스로 사용되도록 설계되었습니다. 요청 메서드는 원격 메서드 호출이 식별된 객체로 보내질 수 있는 방식과 유사하게 대상 리소스에 적용될 동작을 호출합니다.

메서드 토큰은 케이스 민감(case-sensitive)입니다. 이는 대소문자를 구분하는 메서드 이름을 가진 객체 기반 시스템의 게이트웨이로 사용될 수 있기 때문입니다. 관례상, 표준화된 메서드는 대문자 US-ASCII 문자로 정의됩니다.

분산 객체와 달리 HTTP의 표준화된 요청 메서드는 리소스별이 아닙니다. 균일한 인터페이스는 네트워크 기반 시스템에서 가시성과 재사용을 향상시키기 때문입니다 ([REST]). 한 번 정의된 표준 메서드는 어떤 리소스에 적용되든 동일한 의미를 가져야 하지만, 각 리소스는 스스로 해당 의미를 구현하거나 허용할지를 결정합니다.

이 명세서는 일반적으로 HTTP에서 사용되는 여러 표준화된 메서드를 정의하며, 다음 표에 요약되어 있습니다.

표 4
Method Name 설명 (Description) 섹션 (Section)
GET 대상 리소스의 현재 표현을 전송합니다. 9.3.1
HEAD GET과 동일하지만 응답 본문을 전송하지 않습니다. 9.3.2
POST 요청 콘텐츠에 대해 리소스별 처리를 수행합니다. 9.3.3
PUT 대상 리소스의 모든 현재 표현을 요청 콘텐츠로 대체합니다. 9.3.4
DELETE 대상 리소스의 모든 현재 표현을 제거합니다. 9.3.5
CONNECT 대상 리소스가 식별하는 서버에 대한 터널을 설정합니다. 9.3.6
OPTIONS 대상 리소스에 대한 통신 옵션을 설명합니다. 9.3.7
TRACE 대상 리소스까지의 경로에서 메시지 루프백 테스트를 수행합니다. 9.3.8

모든 범용 서버는 MUST GET 및 HEAD 메서드를 지원해야 합니다. 나머지 메서드는 OPTIONAL입니다.

대상 리소스에서 허용되는 메서드 집합은 Allow 헤더 필드(섹션 10.2.1)에 나열될 수 있습니다. 다만 허용 메서드 집합은 동적으로 변경될 수 있습니다. 출처 서버가 인식하지 못하거나 구현하지 않은 요청 메서드를 수신하면 SHOULD 501 (Not Implemented) 상태 코드로 응답해야 합니다. 출처 서버가 인식하고 구현은 되었지만 대상 리소스에 대해 허용되지 않는 요청 메서드를 수신하면 SHOULD 405 (Method Not Allowed) 상태 코드로 응답해야 합니다.

이 명세의 범위를 벗어나는 추가 메서드들이 HTTP용으로 규정되어 왔습니다. 모든 이러한 메서드는 "Hypertext Transfer Protocol (HTTP) Method Registry"에 등록되어야 합니다(섹션 16.1 참조).

9.2. 공통 메서드 속성 (Common Method Properties)

9.2.1. 안전한 메서드 (Safe Methods)

요청 메서드는 정의된 의미가 본질적으로 읽기 전용인 경우 safe로 간주됩니다. 즉, 클라이언트는 안전한 메서드를 적용한 결과로 출처 서버의 상태 변경을 요청하거나 기대하지 않습니다. 또한 안전한 메서드를 합리적으로 사용하는 것은 출처 서버에 손해, 재산 손실 또는 비정상적인 부담을 초래할 것으로 예상되지 않습니다.

안전한 메서드 정의가 구현에 의해 잠재적으로 해롭거나 완전히 읽기 전용이 아니거나 부작용을 일으키는 동작을 포함하는 것을 금지하지는 않습니다. 중요한 점은 클라이언트가 그러한 추가 동작을 요청하지 않았으며 그에 대해 책임을 지지 않는다는 것입니다. 예를 들어, 대부분의 서버는 모든 응답 완료 시 요청 정보를 액세스 로그에 추가하며, 이는 메서드와 관계없이 로그 저장이 가득 차 서버 실패를 일으킬 수 있지만 안전하다고 간주됩니다. 또한 웹에서 광고를 선택하여 시작된 안전한 요청은 광고 계정에 과금되는 부작용을 가질 수 있습니다.

이 명세서에서 정의된 요청 메서드 중 GET, HEAD, OPTIONS, 및 TRACE 메서드는 안전하도록 정의되어 있습니다.

안전한 메서드와 비안전 메서드를 구분하는 목적은 스파이더와 같은 자동 검색 프로세스 및 캐시 성능 최적화(프리페칭)가 해를 끼칠 우려 없이 동작하도록 하기 위함입니다. 또한 사용자 에이전트가 신뢰할 수 없는 콘텐츠를 처리할 때 비안전 메서드의 자동 사용에 적절한 제약을 적용할 수 있게 합니다.

사용자 에이전트는 사용자가 잠재적 동작을 표시할 때 안전한 메서드와 비안전 메서드를 구분하여 사용자에게 비안전 동작을 요청하기 전에 이를 알릴 수 있어야 합니다(SHOULD).

대상 URI 내의 매개변수가 동작 선택의 효과를 가지도록 리소스를 구성한 경우, 그 동작이 요청 메서드 의미와 일치하도록 하는 것은 리소스 소유자의 책임입니다. 예를 들어 "page?do=delete"와 같은 쿼리 매개변수로 동작을 지정하는 웹 기반 편집 소프트웨어에서는 해당 리소스가 안전한 요청 메서드로 액세스될 때 그 동작을 비활성화하거나 허용하지 않아야 합니다. 그렇지 않으면 자동화된 프로세스가 모든 URI 참조에 대해 GET을 수행할 때 원치 않는 부작용이 발생할 수 있습니다.

9.2.2. 멱등성 메서드 (Idempotent Methods)

요청 메서드는 동일한 요청을 여러 번 보냈을 때 서버에 대한 의도된 효과가 단일 요청과 동일하면 idempotent(멱등)로 간주됩니다. 이 명세서에서 정의된 메서드 중 PUT, DELETE 및 안전한 요청 메서드는 멱등입니다.

안전의 정의와 마찬가지로, 멱등성 속성은 사용자가 요청한 것에만 적용됩니다. 서버는 각 요청을 별도로 기록하거나 수정 이력 관리를 유지하거나 멱등 요청마다 비멱등적인 부작용을 구현할 수 있습니다.

멱등성 메서드는 통신 실패로 인해 클라이언트가 서버 응답을 읽기 전에 동일 요청을 반복해야 할 때 자동으로 재시도할 수 있기 때문에 구별됩니다. 예를 들어, 클라이언트가 PUT 요청을 보냈고 기초 연결이 응답을 받기 전에 닫혔다면, 클라이언트는 새 연결을 설정하고 멱등 요청을 재시도할 수 있습니다. 원래 요청이 성공했더라도 반복 요청은 동일한 의도된 효과를 갖게 됩니다(응답은 다를 수 있음).

클라이언트는 요청이 실제로 멱등적이라는 것을 알 수 있는 수단이 없으면 비멱등 메서드를 자동으로 재시도해서는 SHOULD NOT 합니다.

예를 들어, 사용자 에이전트는 그 요청이 해당 리소스에 대해 안전하다고 알려져 있는 경우 POST 요청을 자동으로 반복할 수 있습니다. 유사하게, 버전 관리 저장소에서 작동하도록 설계된 사용자 에이전트는 실패한 연결 후 대상 리소스의 수정(들)을 확인하고 부분 적용된 변경을 되돌리거나 수정한 뒤 실패한 요청을 자동으로 재시도할 수 있습니다.

일부 클라이언트는 자동 재시도가 가능한 시점을 추측하는 더 위험한 접근을 취합니다. 예를 들어, 클라이언트는 응답의 어떤 부분도 수신되지 않았을 경우 POST 요청을 자동으로 재시도할 수 있습니다(특히 유휴 지속 연결이 사용된 경우).

프록시는 비멱등 요청을 자동으로 재시도해서는 MUST NOT 합니다. 클라이언트는 실패한 자동 재시도를 자동으로 재시도해서는 SHOULD NOT 합니다.

9.2.3. 메서드와 캐싱 (Methods and Caching)

캐시가 응답을 저장하고 사용하려면, 관련 메서드가 명시적으로 캐싱을 허용하고 어떤 조건에서 응답을 후속 요청을 만족시키는 데 사용할 수 있는지 자세히 규정해야 합니다. 메서드 정의가 이를 규정하지 않으면 캐시할 수 없습니다. 추가 요구사항은 [CACHING]를 참조하십시오.

이 명세서는 GET, HEAD 및 POST에 대한 캐싱 의미를 정의하지만, 대부분의 캐시 구현은 GET과 HEAD만 지원합니다.

9.3. 메서드 정의 (Method Definitions)

9.3.1. GET

GET 메서드는 선택된 표현(selected representation)의 전송을 요청합니다. 성공적인 응답은 대상 URI가 식별하는 동일성의 정도("sameness")를 반영합니다(자세한 내용은 Section 1.2.2 참조). 따라서 HTTP를 통한 식별 가능한 정보의 검색은 보통 해당 식별자에 대해 GET 요청을 수행하여 200 (OK) 응답으로 정보가 제공되는 방식으로 이루어집니다.

GET은 정보 검색의 주요 메커니즘이며 거의 모든 성능 최적화의 대상입니다. 중요한 리소스마다 URI를 생성하는 애플리케이션은 이러한 최적화를 활용하고 다른 애플리케이션이 재사용할 수 있어 웹의 확장을 촉진합니다.

리소스 식별자를 원격 파일 시스템 경로명으로, 표현을 이러한 파일의 내용 복사로 생각하기 쉽지만 실제 구현에는 제약이 없습니다(관련 보안 고려사항은 섹션 17.3 참조).

리소스의 HTTP 인터페이스는 콘텐츠 객체의 트리, 데이터베이스 레코드에 대한 프로그래밍적 뷰, 또는 다른 정보 시스템에 대한 게이트웨이로 구현될 수 있습니다. 심지어 URI 매핑이 파일 시스템에 연결된 경우에도 출처 서버는 요청을 입력으로 파일을 실행하고 출력을 표현으로 전송하도록 구성될 수 있습니다. 결국 어떤 리소스 식별자가 구현과 어떻게 대응하는지, 그리고 출처 서버가 대상 리소스의 현재 표현을 선택하고 전송하는 방법은 출처 서버만 알면 됩니다.

클라이언트는 Range 헤더 필드를 전송하여 GET의 의미를 "범위 요청"으로 변경할 수 있으며, 이는 선택된 표현의 일부(pieces)만 전송하도록 요청합니다(섹션 14.2).

요청 메시지 프레이밍은 사용된 메서드와 독립적이지만, GET 요청에서 수신된 콘텐츠는 일반적으로 정해진 의미가 없고 요청의 의미나 대상을 변경할 수 없습니다. 일부 구현은 요청 스머글링 공격의 가능성 때문에 이러한 요청을 거부하고 연결을 닫을 수 있습니다(섹션 11.2 참조). 클라이언트는 출처 서버가 사전에 그러한 요청을 지원한다고 표시하지 않는 한 GET 요청에 콘텐츠를 생성해서는 SHOULD NOT 합니다. 출처 서버는 사적 합의를 통해 콘텐츠 수신에 의존해서는 안 됩니다.

GET 요청에 대한 응답은 캐시 가능하며, 캐시는 Cache-Control 헤더 필드(섹션 5.2)에 달리 명시되지 않는 한 이후의 GET 및 HEAD 요청을 만족시키는 데 이를 사용할 수 있습니다.

사용자 제공 정보를 사용해 대상 URI를 구성하는 메커니즘(예: 폼의 쿼리 필드)을 통해 정보 검색을 수행할 때, 민감한 데이터가 URI에 포함되어 노출될 수 있습니다(관련 사항은 섹션 17.9 참조). 경우에 따라 이러한 데이터를 필터하거나 변환하여 노출을 방지할 수 있습니다. 캐시 사용의 이점이 거의 없는 경우에는 POST를 사용하여 데이터를 요청 콘텐츠로 전송하는 것이 더 적절할 수 있습니다(섹션 9.3.3).

9.3.3. POST

POST 메서드는 대상 리소스가 요청에 포함된 표현을 리소스 고유의 의미에 따라 처리하도록 요청합니다. 예를 들어 POST는 다음과 같은 기능에 사용됩니다(그 외에도 다수):

  • HTML 폼에 입력된 필드와 같은 데이터 블록을 데이터 처리 프로세스에 제공;
  • 게시판, 뉴스그룹, 메일링 리스트, 블로그 또는 유사한 기사 그룹에 메시지 게시;
  • 출처 서버에서 아직 식별되지 않은 새 리소스 생성;
  • 리소스의 기존 표현에 데이터 추가.

출처 서버는 POST 요청 처리 결과에 따라 적절한 상태 코드를 선택하여 응답 의미를 나타냅니다. 이 명세서에서 정의된 거의 모든 상태 코드는 POST 응답으로 수신될 수 있습니다(예외: 206, 304, 416).

하나 이상의 리소스가 POST 처리의 결과로 출처 서버에 생성된 경우, 출처 서버는 주 생성 리소스의 식별자를 제공하는 201 (Created) 응답과 함께 Location 헤더 필드를 포함하고 요청 상태를 설명하는 표현을 제공하는 것이 SHOULD 합니다.

POST 요청에 대한 응답은 명시적 신선도 정보가 포함된 경우에만 캐시할 수 있습니다(자세한 내용은 Section 4.2.1 참조). 또한 응답에 포함된 Content-Location 헤더 필드가 POST의 대상 URI와 동일한 값을 가지면 캐시된 POST 응답은 이후의 GET 또는 HEAD 요청을 만족시키는 데 재사용될 수 있습니다. 반대로 POST 요청은 잠재적으로 안전하지 않으므로 캐시된 POST 응답으로 만족될 수 없습니다.

POST 처리 결과가 기존 리소스의 표현과 동등하다면 출처 서버는 사용자 에이전트를 해당 리소스로 리디렉션하기 위해 303 (See Other) 응답을 보낼 수 있습니다. 이는 사용자 에이전트에 리소스 식별자를 제공하고 표현을 공유 캐시에 더 적합한 메서드로 전송하게 하여 이점이 있지만, 사용자 에이전트가 해당 표현을 캐시하지 않은 경우 추가 요청 비용이 발생할 수 있습니다.

9.3.4. PUT

PUT 메서드는 요청 메시지 콘텐츠에 포함된 표현으로 대상 리소스의 상태를 생성하거나 대체하도록 요청합니다. 주어진 표현의 성공적인 PUT은 이후 동일한 대상 리소스에 대한 GET이 동등한 표현을 반환할 것임을 시사합니다. 다만 대상 리소스가 병렬로 다른 에이전트에 의해 조작되거나 출처 서버의 동적 처리 대상일 수 있으므로 그러한 상태 변경이 관찰 가능할 것이라는 보장은 없습니다. 성공 응답은 단지 출처 서버가 처리한 시점에서 사용자 에이전트의 의도가 달성되었음을 의미합니다.

대상 리소스에 현재 표현이 없고 PUT으로 성공적으로 생성된 경우 출처 서버는 201 (Created) 응답을 전송해야 MUST 합니다. 대상 리소스에 현재 표현이 있고 해당 표현이 요청에 포함된 표현 상태에 따라 성공적으로 수정된 경우 출처 서버는 성공을 나타내기 위해 200 (OK) 또는 204 (No Content) 응답을 전송해야 MUST 합니다.

출처 서버는 PUT 표현이 대상 리소스의 구성 제약과 일치하는지 검증해야 SHOULD 합니다. 예를 들어 출처 서버가 리소스의 표현 메타데이터를 URI에 따라 결정한다면, 성공적인 PUT 요청에서 받은 콘텐츠가 해당 메타데이터와 일치하는지 확인해야 합니다. PUT 표현이 대상 리소스와 일치하지 않으면 출처 서버는 표현을 변환하거나 리소스 구성을 변경하여 일치시키거나, 해당 표현이 부적합함을 설명하는 적절한 오류 메시지로 요청을 거부해야 SHOULD 합니다. 제안된 상태 코드로는 409 (Conflict) 또는 415 (Unsupported Media Type) 등이 있습니다.

예를 들어 대상 리소스가 항상 "text/html"의 Content-Type을 갖도록 구성되어 있고 PUT으로 전송된 표현의 Content-Type이 "image/jpeg"인 경우 출처 서버는 다음 중 하나를 수행해야 합니다:

  1. 대상 리소스의 미디어 타입을 새 미디어 타입에 맞게 재구성;
  2. 저장하기 전에 PUT 표현을 리소스와 일치하는 형식으로 변환;
  3. 요청을 거부하고 대상 리소스가 "text/html"로 제한되어 있음을 나타내는 415 (Unsupported Media Type) 응답을 전송(필요하면 새 표현에 적합한 다른 리소스에 대한 링크 포함).

HTTP는 PUT 메서드가 출처 서버의 상태에 어떻게 영향을 미치는지를 정확히 정의하지 않습니다. 리소스가 무엇인지, 상태가 어떻게 저장되는지, 저장 방식이 상태 변경으로 인해 어떻게 변하는지, 출처 서버가 리소스 상태를 표현으로 어떻게 변환하는지는 정의하지 않습니다. 일반적으로 리소스 인터페이스 뒤의 모든 구현 세부사항은 서버에 의해 숨겨집니다.

이는 헤더 및 트레일러 필드의 저장 방식에도 확장됩니다. 일반적인 헤더 필드(예: Content-Type)는 보통 저장되어 이후의 GET 요청에 반환되지만, 헤더 및 트레일러 필드 처리 방법은 해당 요청을 수신한 리소스에 특정합니다. 결과적으로 출처 서버는 PUT 요청에서 수신된 인식되지 않은 헤더 및 트레일러 필드를 리소스 상태의 일부로 저장해서는 안 되며 이를 무시하는 것이 SHOULD 합니다.

출처 서버는 요청의 표현 데이터가 변환 없이 저장되지 않고 그 값이 새 표현과 동일할 때에만 성공 응답에 밸리데이터 필드(예: ETag 또는 Last-Modified)를 전송해서는 MUST NOT 합니다. 이는 사용자 에이전트가 자신이 보유한 표현이 PUT의 결과임을 알고 다시 가져올 필요가 없도록 하기 위함입니다. 응답에서 받은 새 밸리데이터는 이후의 조건부 요청에 사용될 수 있습니다.

POST와 PUT의 근본적 차이는 포함된 표현의 의도에서 드러납니다. POST의 대상 리소스는 포함된 표현을 리소스 고유의 의미에 따라 처리하도록 의도되는 반면, PUT의 포함 표현은 대상 리소스의 상태를 대체하도록 정의됩니다. 따라서 PUT은 멱등적이며 중개자에게 가시적입니다.

PUT 요청을 올바르게 해석하려면 사용자 에이전트가 원하는 대상 리소스를 알아야 합니다. 클라이언트를 대신해 적절한 URI를 선택하는 서비스는 PUT 대신 POST로 구현되어야 SHOULD 합니다. 출처 서버가 요청된 PUT 상태 변경을 대상 리소스에 적용하지 않고 다른 리소스에 적용하려는 경우(예: 리소스가 다른 URI로 이동된 경우) 출처 서버는 적절한 3xx 리디렉션 응답을 보내야 MUST 하며, 사용자 에이전트는 리디렉션할지 여부를 선택할 수 있습니다.

대상 리소스에 적용된 PUT 요청은 다른 리소스에 부작용을 초래할 수 있습니다. 예를 들어 "현재 버전"을 식별하는 URI가 각 특정 버전의 URI와 분리되어 있는 경우, "현재 버전" URI에 대한 성공적인 PUT은 새 버전 리소스를 생성하고 관련 리소스 간에 링크를 추가할 수 있습니다.

일부 출처 서버는 요청 수정자로서 Content-Range 헤더 필드의 사용을 지원하여 부분 PUT(Partial PUT)을 수행할 수 있습니다(자세한 내용은 섹션 14.5 참조).

PUT 메서드에 대한 응답은 캐시할 수 없습니다. 성공적인 PUT 요청이 대상 URI에 대해 하나 이상의 저장된 응답을 가진 캐시를 통과하면, 그 저장된 응답들은 무효화됩니다(자세한 내용은 Section 4.4 참조).

9.3.5. DELETE

DELETE 메서드는 출처 서버가 대상 리소스과 그 현재 기능 간의 연관을 제거하도록 요청합니다. 효과적으로 이 메서드는 UNIX의 "rm" 명령과 유사하며, 출처 서버의 URI 매핑에 대한 삭제 연산을 표현하지 이전 정보 자체가 삭제되어야 함을 기대하지는 않습니다.

대상 리소스에 하나 이상의 현재 표현이 있는 경우, 그것들이 출처 서버에 의해 파괴되거나 관련 저장소가 회수될지는 리소스의 성격과 출처 서버의 구현에 따라 다릅니다. 또한 DELETE로 인해 데이터베이스나 게이트웨이 연결 같은 다른 구현 측면이 비활성화되거나 보관되어야 할 수 있습니다. 일반적으로 출처 서버는 DELETE를 수행할 기제가 있는 리소스에 대해서만 DELETE를 허용합니다.

비교적 적은 수의 리소스만 DELETE 메서드를 허용합니다. 주요 사용 사례는 원격 저작 환경으로, 사용자가 그 효과에 대해 어느 정도 지침을 가진 경우입니다. 예를 들어 PUT으로 생성되었거나 POST 응답의 Location 필드로 식별된 리소스는 해당 DELETE 요청을 허용할 수 있습니다. 또한 버전 관리 클라이언트처럼 HTTP를 원격 작업에 사용하는 맞춤형 사용자 에이전트는 서버의 URI 공간이 버전 저장소에 대응한다고 가정하고 DELETE를 사용할 수 있습니다.

DELETE가 성공적으로 적용되면 출처 서버는 다음 중 하나를 보내는 것이 SHOULD 합니다:

  • 작업이 아직 실행되지 않았지만 성공할 가능성이 있는 경우 202 (Accepted) 상태 코드,
  • 작업이 실행되었고 추가 정보가 제공되지 않는 경우 204 (No Content) 상태 코드,
  • 작업이 실행되었고 상태를 설명하는 표현을 응답 메시지에 포함하는 경우 200 (OK) 상태 코드.

요청 메시지 프레이밍은 메서드와 독립적이지만 DELETE 요청에서 수신된 콘텐츠는 일반적으로 의미가 없고 요청의 의미나 대상을 변경할 수 없으며 요청 스머글링 공격의 잠재성 때문에 일부 구현은 이를 거부하고 연결을 닫을 수 있습니다. 클라이언트는 출처 서버가 사전에 그러한 요청을 지원한다고 표시하지 않는 한 DELETE 요청에 콘텐츠를 생성해서는 SHOULD NOT 합니다. 출처 서버는 사적 합의를 통해 콘텐츠 수신에 의존해서는 안 됩니다.

DELETE 메서드에 대한 응답은 캐시할 수 없습니다. 성공적인 DELETE 요청이 대상 URI에 대해 하나 이상의 저장된 응답을 가진 캐시를 통과하면, 그 저장된 응답들은 무효화됩니다(자세한 내용은 Section 4.4 참조).

9.3.6. CONNECT

CONNECT 메서드는 수신자에게 요청 대상이 식별하는 목적지 출처 서버로의 터널을 설정하도록 요청합니다. 성공하면 이후 터널이 닫힐 때까지 양방향으로 블라인드 포워딩만 수행해야 합니다. 터널은 하나 이상의 프록시를 통해 종단 간 가상 연결을 생성하는 데 일반적으로 사용되며, 이후 TLS로 보호될 수 있습니다.

CONNECT는 이 메서드 고유의 요청 대상 형식을 사용하며, 터널 목적지의 호스트 이름과 포트 번호만으로 구성됩니다(콜론으로 구분). 기본 포트는 없으므로 클라이언트는 CONNECT 요청에 포트 번호를 반드시 전송해야 MUST 합니다. 예:

CONNECT server.example.com:80 HTTP/1.1
Host: server.example.com

서버는 빈 포트나 잘못된 포트를 대상으로 하는 CONNECT 요청을 거부해야 MUST 하며, 일반적으로 400 (Bad Request)로 응답합니다.

CONNECT는 HTTP 연결의 요청/응답 성격을 변경하므로 특정 HTTP 버전은 그 의미를 프로토콜의 와이어 포맷으로 매핑하는 방법이 다를 수 있습니다.

CONNECT는 프록시에 대한 요청에서 사용하도록 의도되었습니다. 수신자는 요청 대상이 식별하는 서버에 직접 연결하거나 다른 프록시를 사용하도록 구성된 경우 다음 인바운드 프록시로 CONNECT 요청을 전달하여 터널을 설정할 수 있습니다. 출처 서버는 CONNECT를 허용할 수는 있지만 대부분은 구현하지 않습니다.

어떤 2xx (Successful) 응답도 송신자(및 모든 인바운드 프록시)가 응답 헤더 섹션 직후 터널 모드로 전환할 것임을 나타냅니다. 그 이후에 수신되는 데이터는 요청 대상이 식별하는 서버에서 온 데이터입니다. 성공 응답이 아닌 모든 응답은 터널이 아직 형성되지 않았음을 나타냅니다.

터널은 터널 중개자가 양쪽 중 하나가 연결을 닫았음을 감지하면 종료됩니다. 중개자는 닫힌 쪽에서 온 미전송 데이터를 상대쪽으로 전송하려 시도하고, 두 연결을 닫은 뒤 남아 있는 데이터를 폐기해야 MUST 합니다.

프록시 인증은 터널 생성 권한을 확립하는 데 사용될 수 있습니다. 예:

CONNECT server.example.com:443 HTTP/1.1
Host: server.example.com:443
Proxy-Authorization: basic aGVsbG86d29ybGQ=

임의의 서버로 터널을 설정하는 데에는 큰 위험이 있습니다. 특히 목적지가 웹 트래픽용이 아닌 잘 알려진 또는 예약된 TCP 포트일 때 위험이 큽니다. 예를 들어 "example.com:25"로의 CONNECT는 프록시가 SMTP 포트로 연결하게 하여 스팸 중계를 유발할 수 있습니다. CONNECT를 지원하는 프록시는 사용을 제한된 포트 집합이나 구성 가능한 안전한 대상 목록으로 제한해야 SHOULD 합니다.

서버는 CONNECT의 성공 응답에서 어떤 Transfer-Encoding 또는 Content-Length 헤더 필드를 보내서는 MUST NOT 합니다. 클라이언트는 성공 응답에서 수신된 Content-Length 또는 Transfer-Encoding 헤더 필드를 무시해야 MUST 합니다.

CONNECT 요청 메시지에는 콘텐츠가 없습니다. CONNECT 요청 메시지의 헤더 섹션 이후에 전송되는 데이터의 해석은 사용 중인 HTTP 버전에 따라 다릅니다.

CONNECT 메서드에 대한 응답은 캐시할 수 없습니다.

9.3.7. OPTIONS

OPTIONS 메서드는 대상 리소스에 대해 사용 가능한 통신 옵션에 관한 정보를 요청합니다. 이 메서드는 클라이언트가 리소스와 통신할 때의 옵션 및/또는 요구사항이나 서버의 기능을 리소스 동작 없이 결정할 수 있게 합니다.

요청 대상이 별표("*")인 OPTIONS 요청은 특정 리소스가 아닌 서버 전체에 적용됩니다. 서버의 통신 옵션은 보통 리소스에 따라 달라지므로 "*" 요청은 "ping" 또는 "noop" 유형의 메서드로만 유용합니다. 예를 들어 이는 프록시가 HTTP/1.1을 준수하는지 테스트하는 데 사용될 수 있습니다.

요청 대상이 별표가 아니면 OPTIONS 요청은 대상 리소스와 통신할 때 사용 가능한 옵션에 적용됩니다.

서버는 OPTIONS에 대해 성공 응답을 생성할 때 대상 리소스에 적용될 수 있는 구현된 선택적 기능을 나타내는 헤더(예: Allow)를 보내는 것이 SHOULD 합니다. 응답 콘텐츠가 있다면 기계나 사람이 읽을 수 있는 표현으로 통신 옵션을 설명할 수 있습니다. 표준 형식은 이 명세서에서 정의되지 않습니다.

클라이언트는 요청 체인의 특정 수신자를 대상으로 하기 위해 OPTIONS 요청에 Max-Forwards 헤더 필드를 보낼 수 있습니다. 프록시는 수신된 요청에 Max-Forwards 필드가 없는 한 전달하면서 Max-Forwards 헤더를 생성해서는 MUST NOT 합니다.

콘텐츠를 포함하는 OPTIONS 요청을 생성하는 클라이언트는 표현 미디어 타입을 설명하는 유효한 Content-Type 헤더 필드를 보내야 MUST 합니다. 이 명세서는 그러한 콘텐츠의 사용을 정의하지 않습니다.

OPTIONS 메서드에 대한 응답은 캐시할 수 없습니다.

9.3.8. TRACE

TRACE 메서드는 요청 메시지의 원격 애플리케이션 수준 루프백을 요청합니다. 요청의 최종 수신자는 수신한 메시지를 (아래에 설명된 일부 필드를 제외하고) 응답 본문의 콘텐츠로 클라이언트에게 반사하여 돌려줘야 SHOULD 합니다. "message/http" 포맷은 이를 수행하는 한 방법입니다. 최종 수신자는 출처 서버이거나 요청에서 Max-Forwards 값이 0인 첫 번째 서버입니다.

클라이언트는 TRACE 요청에 응답으로 노출될 수 있는 민감한 데이터를 포함하는 필드를 생성해서는 MUST NOT 합니다. 예를 들어 사용자 자격증명이나 쿠키를 TRACE 요청에 포함하는 것은 바람직하지 않습니다. 최종 수신자는 응답 콘텐츠를 생성할 때 민감한 데이터를 포함할 가능성이 있는 요청 필드를 제외해야 SHOULD 합니다.

TRACE는 클라이언트가 요청 체인에서 다른 쪽 끝에서 무엇이 수신되는지를 확인하고 테스트나 진단 정보를 얻는 데 사용됩니다. 특히 Via 헤더 필드 값은 요청 체인의 추적으로서 유용합니다. Max-Forwards 헤더 필드의 사용은 요청 체인의 길이를 제한할 수 있어 무한 루프를 포워딩하는 프록시 체인을 테스트할 때 유용합니다.

클라이언트는 TRACE 요청에 콘텐츠를 전송해서는 MUST NOT 합니다.

TRACE 메서드에 대한 응답은 캐시할 수 없습니다.

10. 메시지 컨텍스트

10.1. 요청 컨텍스트 필드

아래의 요청 헤더 필드는 사용자, 사용자 에이전트 및 요청 뒤에 있는 리소스에 관한 정보를 포함하여 요청 컨텍스트에 대한 추가 정보를 제공합니다.

10.1.1. Expect

요청의 "Expect" 헤더 필드는 이 요청을 적절히 처리하기 위해 서버가 지원해야 하는 특정 동작 집합(기대치)을 나타냅니다.

Expect 필드 값은 대소문자 구분이 없습니다.

이 명세에서 정의된 유일한 기대치는 인자 없는 "100-continue"입니다.

100-continue 이외의 멤버를 포함하는 Expect 필드 값을 수신한 서버는 그 예상치 못한 기대치를 충족할 수 없음을 나타내기 위해 417 (Expectation Failed) 상태 코드로 응답할 수 MAY 있습니다.

100-continue 기대치는 클라이언트가 이 요청에서 (아마도 큰) 콘텐츠를 전송하려고 하며, 메서드, 대상 URI 및 헤더 필드만으로 즉시 성공, 리디렉션 또는 오류 응답이 결정되지 않는다면 100 (Continue) 중간 응답을 받고자 함을 수신자에게 알립니다. 이는 클라이언트가 실제로 콘텐츠를 전송하기 전에 전송을 시작할 가치가 있는지를 확인할 수 있게 하여, 데이터가 거대하거나 오류가 발생할 가능성이 높다고 예상되는 경우(예: 상태 변경 메서드를 처음으로 인증 자격 증명 없이 보낼 때) 효율성을 개선할 수 있습니다.

예를 들어, 다음과 같이 시작하는 요청은

PUT /somewhere/fun HTTP/1.1
Host: origin.example.com
Content-Type: video/h264
Content-Length: 1234567890987
Expect: 100-continue

클라이언트가 불필요한 대용량 데이터 전송을 시작하기 전에 출처 서버가 즉시 401 (Unauthorized) 또는 405 (Method Not Allowed) 같은 오류 메시지로 응답할 수 있도록 합니다.

클라이언트에 대한 요구사항:

  • 클라이언트는 콘텐츠를 포함하지 않는 요청에서 100-continue 기대치를 생성해서는 MUST NOT 합니다.
  • 100 (Continue) 응답을 기다렸다가 요청 콘텐츠를 전송하려는 클라이언트는 Expect 헤더 필드에 100-continue 기대치를 포함하여 전송해야 MUST 합니다.
  • 100-continue 기대치를 전송하는 클라이언트는 특정 시간 동안 기다릴 의무가 없습니다; 그러한 클라이언트는 응답을 아직 받지 못했더라도 콘텐츠를 전송할 수 MAY 합니다. 또한 100 (Continue) 응답은 HTTP/1.0 중개자를 통해 전송될 수 없으므로, 이러한 클라이언트는 콘텐츠를 전송하기 전에 무기한 대기해서는 SHOULD NOT 합니다.
  • 100-continue 기대치를 포함한 요청에 대해 417 (Expectation Failed) 상태 코드를 수신한 클라이언트는, 417 응답이 단지 응답 체인이 기대치를 지원하지 않음을 나타내므로(예: HTTP/1.0 서버를 통과함) 100-continue 기대치 없이 동일한 요청을 반복해야 SHOULD 합니다.

서버에 대한 요구사항:

  • HTTP/1.0 요청에서 100-continue 기대치를 수신한 서버는 그 기대치를 무시해야 MUST 합니다.
  • 서버는 해당 요청에 대한 일부 또는 전부의 콘텐츠를 이미 수신했거나 프레이밍이 콘텐츠가 없음을 나타내는 경우 100 (Continue) 응답을 생략할 수 MAY 있습니다.
  • 100 (Continue) 응답을 전송한 서버는 요청 콘텐츠를 수신하고 처리한 후 최종 상태 코드를 반드시 전송해야 MUST 합니다(연결이 조기에 종료되지 않는 한).
  • 최종 상태 코드로 응답하기 전에 전체 요청 콘텐츠를 읽지 않은 서버는 연결을 닫을 의사가 있는지(예: 섹션 9.6 참조) 또는 계속 읽을 것인지 여부를 표시해야 SHOULD 합니다.

메서드, 대상 URI 및 완전한 헤더 섹션을 포함하고 100-continue 기대치와 요청 콘텐츠가 뒤따를 것임을 나타내는 HTTP/1.1(또는 이후) 요청을 수신하면, 출처 서버는 MUST 다음 중 하나를 전송해야 합니다:

  • 메서드, 대상 URI 및 헤더 필드만 검사하여 결정할 수 있는 최종 상태 코드로 즉시 응답, 또는
  • 클라이언트가 요청 콘텐츠를 전송하도록 권장하기 위한 즉시 100 (Continue) 응답.

출처 서버는 100 (Continue) 응답을 보내기 전에 콘텐츠를 기다려서는 MUST NOT 합니다.

메서드, 대상 URI 및 완전한 헤더 섹션을 포함하고 100-continue 기대치와 요청 콘텐츠가 뒤따를 것임을 나타내는 HTTP/1.1(또는 이후) 요청을 수신한 프록시는 MUST 다음 중 하나를 수행해야 합니다:

  • 메서드, 대상 URI 및 헤더 필드만 검사하여 결정할 수 있는 최종 상태 코드로 즉시 응답을 전송하거나,
  • 해당 요청과 일치하는 요청 라인과 헤더 섹션을 다음 인바운드 서버로 보내 출처 서버 쪽으로 요청을 전달한다.

프록시가 구성 또는 과거 상호작용으로부터 다음 인바운드 서버가 HTTP/1.0만 지원한다고 생각하면, 프록시는 클라이언트가 콘텐츠 전송을 시작하도록 장려하기 위해 즉시 100 (Continue) 응답을 생성할 수 MAY 있습니다.

10.1.2. From

"From" 헤더 필드에는 요청 사용자 에이전트를 제어하는 인간 사용자의 인터넷 이메일 주소가 포함됩니다. 이 주소는 [RFC5322]의 "mailbox"로 정의된 것처럼 기계가 사용할 수 있는 형태여야 합니다:

  From    = mailbox

  mailbox = <mailbox, see [RFC5322], Section 3.4>

예시:

From: spider-admin@example.org

From 헤더 필드는 비로봇 사용자 에이전트에서는 거의 전송되지 않습니다. 사용자 에이전트는 사용자의 명시적 구성 없이는 From 헤더 필드를 전송해서는 SHOULD NOT 합니다. 이는 사용자의 프라이버시 이익이나 사이트의 보안 정책과 충돌할 수 있기 때문입니다.

로봇 사용자 에이전트는 문제가 발생했을 때 로봇을 운영하는 담당자에게 연락할 수 있도록 유효한 From 헤더 필드를 전송해야 SHOULD 합니다(예: 로봇이 과다하거나 원치 않는, 또는 잘못된 요청을 보내는 경우).

서버는 From 헤더 필드를 접근 제어나 인증에 사용해서는 SHOULD NOT 합니다. From 값은 요청을 수신하거나 관찰하는 누구에게나 보이는 것이 예상되며 로그 파일과 오류 보고서에 기록될 수 있어 프라이버시 기대와 일치하지 않기 때문입니다.

10.1.3. Referer

"Referer" [sic] 헤더 필드는 사용자 에이전트가 대상 URI를 얻은 리소스의 URI 참조(즉, "referrer", 필드 이름은 철자 오류가 있음)를 지정할 수 있게 합니다. 사용자 에이전트는 URI 참조를 생성할 때 fragment 및 userinfo 구성요소가 있으면 이를 포함해서는 MUST NOT 합니다([URI] 참조).

필드 값은 absolute-URI 또는 partial-URI입니다. 후자의 경우(섹션 4 참조), 참조된 URI는 대상 URI에 상대적입니다.

Referer 헤더 필드는 서버가 간단한 분석, 로깅, 최적화된 캐싱 등을 위해 다른 리소스에 대한 백링크를 생성할 수 있게 합니다. 또한 유지보수를 위해 오래되거나 잘못된 링크를 찾는 데 도움을 줍니다. 일부 서버는 Referer 헤더 필드를 다른 사이트로부터의 링크(이른바 "deep linking")를 차단하거나 CSRF(교차 사이트 요청 위조)를 제한하는 수단으로 사용하지만, 모든 요청이 이를 포함하는 것은 아닙니다.

예시:

Referer: http://www.example.org/hypertext/Overview.html

대상 URI가 자체 URI가 없는 출처(예: 사용자 키보드 입력 또는 사용자의 북마크/즐겨찾기 항목)에서 얻어진 경우, 사용자 에이전트는 Referer 헤더 필드를 제외하거나 값으로 "about:blank"를 보내야 MUST 합니다.

Referer 헤더 필드 값은 반드시 참조하는 리소스의 전체 URI를 전달할 필요는 없습니다; 사용자 에이전트는 참조 출처(origin) 이외의 부분을 잘라낼 수 MAY 있습니다.

Referer 헤더는 참조 리소스의 식별자가 개인 정보를 드러내거나(예: 계정 이름) 방화벽 뒤 또는 보안 서비스 내부처럼 기밀로 간주되는 리소스를 드러내는 경우 요청 컨텍스트나 사용자의 방문 기록에 관한 정보를 유출할 가능성이 있어 프라이버시 문제를 일으킬 수 있습니다. 대부분의 범용 사용자 에이전트는 참조 리소스가 로컬 "file" 또는 "data" URI인 경우 Referer 헤더를 전송하지 않습니다. 사용자 에이전트는 참조 리소스가 보안 프로토콜로 액세스되었고 요청 대상이 참조 리소스의 origin과 다르면 Referer를 전송해서는 SHOULD NOT 하며, 참조 리소스가 명시적으로 Referer 전송을 허용하지 않는 한 전송해서는 MUST NOT 합니다. 추가 보안 고려사항은 섹션 17.9를 참조하십시오.

일부 중개자는 아웃고잉 요청에서 Referer 헤더 필드를 무차별적으로 제거하는 것으로 알려져 있습니다. 이는 CSRF 공격에 대한 보호를 방해하여 사용자에게 훨씬 더 해로울 수 있습니다. 정보 공개를 제한하려는 중개자와 사용자 에이전트 확장자는 내부 도메인 이름을 의사명으로 교체하거나 쿼리 및/또는 경로 구성요소를 잘라내는 등의 특정 편집으로 변경을 제한해야 합니다. 중개자는 필드 값이 대상 URI와 동일한 스킴 및 호스트를 공유하는 경우 Referer 헤더 필드를 변경하거나 삭제해서는 SHOULD NOT 합니다.

10.1.4. TE

"TE" 헤더 필드는 전송 코딩 및 트레일러 섹션에 관해 클라이언트의 능력을 설명합니다.

섹션 6.5에서 설명한 바와 같이, 요청에서 "trailers" 멤버가 있는 TE 필드는 클라이언트가 트레일러 필드를 버리지 않을 것임을 나타냅니다.

TE는 또한 HTTP/1.1에서 서버에게 응답에서 클라이언트가 수용할 수 있는 전송 코딩을 알리는 데 사용됩니다. 발행 시점 기준으로 전송 코딩을 사용하는 것은 HTTP/1.1뿐입니다(자세한 내용은 Section 7 참조).

TE 필드 값은 멤버들의 목록이며, "trailers"를 제외한 각 멤버는 선택적 가중치로 클라이언트가 해당 전송 코딩에 대한 상대적 선호도를 표시하는 전송 코딩 이름 토큰과 해당 전송 코딩에 대한 선택적 파라미터로 구성됩니다(섹션 12.4.2 참조).

TE를 전송하는 발신자는 또한 중개자가 이 필드를 전달하지 않도록 알리기 위해 Connection 헤더 필드에 "TE" connection option을 포함시켜야 MUST 합니다(섹션 7.6.1 참조).

10.1.5. User-Agent

"User-Agent" 헤더 필드는 요청을 생성한 사용자 에이전트에 관한 정보를 포함하며, 서버가 상호운용성 문제 범위를 식별하거나 특정 사용자 에이전트의 제한을 우회하거나 응답을 조정하는 데 자주 사용됩니다. 사용자 에이전트는 특별히 구성되지 않는 한 각 요청에 User-Agent 헤더 필드를 보내는 것이 SHOULD 합니다.

User-Agent 필드 값은 하나 이상의 제품 식별자로 구성되며, 각 식별자 뒤에는 0개 이상의 주석(섹션 5.6.5)이 올 수 있습니다. 이들은 함께 사용자 에이전트 소프트웨어와 그 중요한 하위 제품을 식별합니다. 관례적으로 제품 식별자는 중요도 순서로 나열됩니다. 각 제품 식별자는 이름과 선택적 버전으로 이루어집니다.

발신자는 생성된 제품 식별자를 제품을 식별하는 데 필요한 범위로 제한해야 SHOULD 하며, 광고나 기타 비본질적인 정보를 제품 식별자 내에 생성해서는 MUST NOT 합니다. 또한 product-version에 버전 식별자가 아닌 정보를 생성해서는 SHOULD NOT 합니다(동일 제품 이름의 연속 버전은 product-version 부분만 달라야 함).

예시:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

사용자 에이전트는 불필요하게 세세한 정보를 포함한 User-Agent 헤더 필드를 생성해서는 SHOULD NOT 하며, 제3자에 의한 하위 제품 추가를 제한해야 SHOULD 합니다. 지나치게 길고 상세한 User-Agent 값은 요청 지연을 증가시키고 사용자 식별 위험("fingerprinting")을 높입니다.

유사하게, 구현체는 호환성을 선언하기 위해 다른 구현체의 product 토큰을 사용하는 것을 권장하지 않습니다. 사용자 에이전트가 다른 사용자 에이전트로 가장하면, 수신자는 해당 식별된 사용자 에이전트에 맞춘 응답을 보려는 의도로 간주할 수 있으며, 실제로는 그 응답이 잘 동작하지 않을 수 있습니다.

10.2. 응답 컨텍스트 필드

아래의 응답 헤더 필드는 상태 코드로 암시되는 것 외에 응답에 관한 추가 정보를 제공합니다. 여기에는 서버, 대상 리소스 또는 관련 리소스에 관한 정보가 포함됩니다.

10.2.1. Allow

"Allow" 헤더 필드는 대상 리소스가 지원한다고 광고하는 메서드 집합을 나열합니다. 이 필드의 목적은 리소스와 연관된 유효한 요청 메서드를 수신자에게 정보를 제공하는 데에만 있습니다.

사용 예:

Allow: GET, HEAD, PUT

허용된 실제 메서드 집합은 각 요청 시점에 출처 서버에 의해 정의됩니다. 출처 서버는 405 (Method Not Allowed) 응답에서 Allow 헤더 필드를 반드시 생성해야 MUST 하며, 다른 응답에서는 생성할 수 MAY 있습니다. 빈 Allow 필드 값은 리소스가 어떤 메서드도 허용하지 않음을 나타내며, 이는 리소스가 구성상 일시적으로 비활성화된 경우 405 응답에서 발생할 수 있습니다.

프록시는 Allow 헤더 필드를 수정해서는 MUST NOT 합니다 — 프록시는 표시된 모든 메서드를 이해할 필요 없이 일반적인 메시지 처리 규칙에 따라 이를 처리할 수 있습니다.

10.2.2. Location

"Location" 헤더 필드는 일부 응답에서 응답과 관련된 특정 리소스를 참조하는 데 사용됩니다. 관계의 유형은 요청 메서드와 상태 코드 의미의 조합에 의해 정의됩니다.

필드 값은 단일 URI-reference로 구성됩니다. 상대 참조 형태일 때([URI] 참조), 최종 값은 대상 URI에 대해 해석하여 계산됩니다.

201 (Created) 응답의 경우 Location 값은 요청으로 생성된 주된 리소스를 가리킵니다. 3xx (Redirection) 응답의 경우 Location 값은 자동으로 요청을 리디렉션할 때 선호되는 대상 리소스를 가리킵니다.

3xx 응답에 제공된 Location 값이 fragment 구성요소를 가지지 않는다면, 사용자 에이전트는 원래 대상 URI를 생성한 참조의 fragment를 상속하는 것처럼 리디렉션을 처리해야 MUST 합니다(즉, 리디렉션은 원래 참조의 fragment를 상속합니다).

예를 들어, "http://www.example.org/~tim"에 대해 생성된 GET 요청은 303 (See Other) 응답을 초래하고 다음 헤더 필드를 포함할 수 있습니다:

Location: /People.html#tim

이는 사용자 에이전트가 "http://www.example.org/People.html#tim"으로 리디렉션하라는 제안을 합니다.

유사하게, "http://www.example.org/index.html#larry"에 대해 생성된 GET 요청은 301 (Moved Permanently) 응답을 초래하고 다음 헤더 필드를 포함할 수 있습니다:

Location: http://www.example.net/index.html

이는 원래 fragment 식별자 "#larry"를 보존하여 "http://www.example.net/index.html#larry"로 리디렉션하라는 제안을 합니다.

Location 값에 fragment 식별자가 적절하지 않은 상황도 있습니다. 예를 들어, 201 (Created) 응답의 Location 헤더는 생성된 리소스에 특정한 URI를 제공해야 합니다.

10.2.3. Retry-After

서버는 "Retry-After" 헤더 필드를 보내어 사용자 에이전트가 후속 요청을 수행하기 전에 얼마나 기다려야 하는지를 나타냅니다. 503 (Service Unavailable) 응답과 함께 전송되는 경우, Retry-After는 서비스가 클라이언트에게 얼마나 오랫동안 이용 불가능할 것으로 예상되는지 나타냅니다. 모든 3xx (Redirection) 응답과 함께 전송되는 경우에는 리디렉션된 요청을 수행하기 전에 사용자 에이전트가 기다리도록 요청된 최소 시간을 나타냅니다.

Retry-After 필드 값은 HTTP-date 또는 응답 수신 후 지연할 초 수 중 하나일 수 있습니다.

delay-seconds 값은 음이 아닌 10진 정수로, 초 단위를 나타냅니다.

사용 예 두 가지는 다음과 같습니다

Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
Retry-After: 120

후자의 예에서는 지연 시간이 2분입니다.

10.2.4. Server

"Server" 헤더 필드는 요청을 처리하는 데 사용된 출처 서버 소프트웨어에 관한 정보를 포함하며, 이는 클라이언트가 보고된 상호운용성 문제의 범위를 식별하거나 특정 서버 제한을 우회하거나 응답을 조정하는 데 자주 사용됩니다. 출처 서버는 응답에 Server 헤더 필드를 생성할 수 MAY 있습니다.

Server 헤더 필드 값은 하나 이상의 제품 식별자로 구성되며, 각 식별자 뒤에는 0개 이상의 주석(섹션 5.6.5)이 올 수 있습니다. 이는 출처 서버 소프트웨어와 그 중요한 하위 제품을 식별합니다. 관례적으로 제품 식별자는 중요도 순서로 나열됩니다. 각 제품 식별자는 이름과 선택적 버전으로 이루어집니다(섹션 10.1.5 참조).

예시:

Server: CERN/3.0 libwww/2.17

출처 서버는 불필요하게 세세한 정보를 포함한 Server 헤더 필드를 생성해서는 SHOULD NOT 하며, 제3자에 의한 하위 제품 추가를 제한해야 SHOULD 합니다. 지나치게 길고 상세한 Server 값은 응답 지연을 증가시키고 내부 구현 세부사항을 노출하여 공격자가 알려진 보안 취약점을 찾고 악용하기 더 쉽게 만들 수 있습니다.

11. HTTP 인증

11.1. 인증 스킴 (Authentication Scheme)

HTTP는 서버가 클라이언트 요청에 대해 챌린지를 제시하거나 클라이언트가 인증 정보를 제공할 때 사용할 수 있는 확장 가능한 챌린지-응답 인증 스킴 집합을 통해 접근 제어 및 인증을 위한 일반적인 프레임워크를 제공합니다. 인증 스킴을 식별하기 위해 대소문자 구분 없는 토큰을 사용합니다:

  auth-scheme    = token

일반적인 프레임워크를 제외하고, 이 문서는 특정 인증 스킴을 규정하지 않습니다. 새로운 인증 스킴과 기존 스킴은 독립적으로 규정되어야 하며 "Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry"에 등록되어야 합니다. 예를 들어 "basic" 및 "digest" 인증 스킴은 각각 [RFC7617][RFC7616]에 정의되어 있습니다.

11.2. 인증 매개변수 (Authentication Parameters)

인증 스킴 다음에는 해당 스킴을 통해 인증을 달성하는 데 필요한 추가 정보가 콤마로 구분된 매개변수 목록 또는 base64 인코딩 정보를 담을 수 있는 단일 문자 시퀀스로 따라옵니다.

  token68        = 1*( ALPHA / DIGIT /
                       "-" / "." / "_" / "~" / "+" / "/" ) *"="

token68 문법은 base64, base64url(파일명 및 URL 안전 알파벳), base32 또는 base16(16진) 인코딩을 패딩 유무와 관계없이 담을 수 있도록 URI의 비예약 66자([URI])와 몇몇 추가 문자를 허용하지만 공백은 제외합니다([RFC4648]).

인증 매개변수는 이름/값 쌍이며, 이름 토큰은 대소문자 구분 없이 매치되고 각 매개변수 이름은 챌린지마다 단 한 번만 발생해야 합니다(MUST).

  auth-param     = token BWS "=" BWS ( token / quoted-string )

매개변수 값은 "token" 또는 "quoted-string"(섹션 5.6) 중 하나로 표현될 수 있습니다. 인증 스킴 정의는 송신자와 수신자 모두에 대해 두 표기법을 수용해야 하며, 이는 인증 스킴에 관계없이 수신자가 일반적인 구문 분석 요소를 사용할 수 있게 합니다.

하위 호환성을 위해, 인증 스킴 정의는 송신자 형식을 두 변형 중 하나로 제한할 수 있습니다. 이는 배포된 구현체가 두 형식 중 하나를 만났을 때 실패할 것임이 알려진 경우 중요할 수 있습니다.

11.3. 챌린지와 응답 (Challenge and Response)

401 (Unauthorized) 응답 메시지는 출처 서버가 사용자 에이전트의 권한 부여를 챌린지하는 데 사용되며, 요청된 리소스에 적용 가능한 적어도 하나의 챌린지를 포함하는 WWW-Authenticate 헤더 필드를 포함합니다.

407 (Proxy Authentication Required) 응답 메시지는 프록시가 클라이언트의 인증을 챌린지할 때 사용되며, 요청된 리소스에 대해 프록시에 적용 가능한 적어도 하나의 챌린지를 포함하는 Proxy-Authenticate 헤더 필드를 포함합니다.

출처 서버에 대해 자신을 인증하려는 사용자 에이전트는 — 보통은 401 (Unauthorized)를 받은 후에 — 요청에 Authorization 헤더 필드를 포함하여 인증할 수 있습니다.

프록시에 대해 자신을 인증하려는 클라이언트는 — 보통은 407 (Proxy Authentication Required)를 받은 후에 — 요청에 Proxy-Authorization 헤더 필드를 포함하여 인증할 수 있습니다.

11.4. 자격 증명 (Credentials)

Authorization 필드 값과 Proxy-Authorization 필드 값은 챌린지(과거 어느 시점에 수신된 것일 수 있음)를 기반으로 요청된 리소스의 영역(realm)에 대한 클라이언트의 자격 증명을 포함합니다. 값 생성 시 사용자 에이전트는 이해하는 것 중 가장 안전하다고 생각되는 auth-scheme을 선택하고, 필요에 따라 사용자로부터 자격 증명을 얻어야 합니다. 헤더 필드 값 내 자격 증명 전송은 연결의 기밀성과 관련된 중요한 보안 고려사항을 수반하며, 이는 섹션 17.16.1에 설명되어 있습니다.

보호된 리소스에 대한 요청이 자격 증명을 누락했거나 잘못된 자격 증명(예: 잘못된 비밀번호) 또는 부분 자격 증명을 포함하는 경우(예: 인증 스킴이 여러 라운드 트립을 요구하는 경우), 출처 서버는 요청된 리소스에 적용 가능한 적어도 하나의(가능하면 새로운) 챌린지를 포함하는 401 (Unauthorized) 응답을 전송하는 것이 SHOULD 합니다.

마찬가지로 프록시 자격 증명을 누락했거나 잘못된 경우, 인증을 요구하는 프록시는 프록시에게 적용 가능한 적어도 하나의 챌린지를 포함하는 407 (Proxy Authentication Required) 응답을 생성해야 SHOULD 합니다.

유효하지만 접근 권한을 얻기에 충분하지 않은 자격 증명을 받은 서버는 403 (Forbidden) 상태 코드로 응답해야 합니다(섹션 15.5.4).

HTTP는 접근 인증을 위해 이 단순한 챌린지-응답 프레임워크에만 애플리케이션을 제한하지 않습니다. 전송 계층 수준의 인증이나 메시지 캡슐화, 추가 인증 정보를 지정하는 다른 헤더 필드와 같은 추가 메커니즘을 사용할 수 있지만, 이러한 추가 메커니즘은 이 명세서에 의해 정의되지 않습니다.

참고로, 사용자 인증을 위해 Set-Cookie 및 Cookie 헤더 필드([COOKIE])를 사용해 인증 관련 토큰을 전달하는 다양한 맞춤 메커니즘이 존재합니다.

11.5. 보호 영역(Realm) 설정

realm 인증 매개변수는 보호 범위를 나타내고자 하는 인증 스킴에서 사용하기 위해 예약되어 있습니다.

protection space는 액세스되는 서버의 출처(원점, 섹션 4.3.1 참조)와 realm 값(있다면)의 조합으로 정의됩니다. 이러한 realm은 서버의 보호된 리소스를 보호 공간 집합으로 분할하여 각각 고유한 인증 스킴 및/또는 권한 부여 데이터베이스를 가질 수 있게 합니다. realm 값은 일반적으로 출처 서버에 의해 할당되는 문자열이며 인증 스킴에 특유한 추가 의미를 가질 수 있습니다. 응답은 동일한 auth-scheme이지만 서로 다른 realm을 가진 여러 챌린지를 포함할 수 있습니다.

보호 공간은 자격 증명이 자동으로 적용될 수 있는 도메인을 결정합니다. 이전 요청이 인증된 경우, 사용자 에이전트는 인증 스킴, 매개변수 및/또는 사용자 환경설정(예: 구성 가능한 비활성 타임아웃)에 의해 결정된 기간 동안 해당 보호 공간 내의 다른 모든 요청에 동일한 자격 증명을 재사용할 수 있습니다(MAY).

보호 공간의 범위는 추가 정보 없이는 클라이언트가 반드시 알 수 있는 것은 아닙니다. 인증 스킴은 보호 공간의 범위를 설명하는 매개변수를 정의할 수 있습니다. 인증 스킴이 특별히 허용하지 않는 한, 단일 보호 공간은 그 서버의 범위를 벗어날 수 없습니다.

역사적 이유로 송신자는 인용된 문자열(quoted-string) 문법만 생성해야 MUST 합니다. 수신자는 상호운용성을 위해 오랫동안 두 표기법을 모두 허용해온 기존 클라이언트와의 최대 호환성을 위해 토큰과 인용-문자열 문법 둘 다 지원해야 할 수 있습니다.

11.6. 출처 서버에 대한 사용자 인증

11.6.1. WWW-Authenticate

"WWW-Authenticate" 응답 헤더 필드는 대상 리소스에 적용되는 인증 스킴과 매개변수를 나타냅니다.

서버가 401 (Unauthorized) 응답을 생성하는 경우, 반드시 적어도 하나의 챌린지를 포함하는 WWW-Authenticate 헤더 필드를 전송해야 MUST 합니다. 서버는 응답에 자격 증명(또는 다른 자격 증명)을 제공하면 응답에 영향을 줄 수 있음을 나타내기 위해 다른 응답 메시지에서도 WWW-Authenticate 헤더 필드를 생성할 수 있습니다(MAY).

프록시가 응답을 전달할 때 해당 응답의 어떤 WWW-Authenticate 헤더 필드도 수정해서는 MUST NOT 합니다.

사용자 에이전트는 필드 값이 둘 이상의 챌린지를 포함할 수 있고 각 챌린지가 콤마로 구분된 인증 매개변수 목록을 포함할 수 있으므로 필드 값을 구문 분석할 때 특별히 주의해야 합니다. 또한 헤더 필드 자체가 여러 번 나타날 수 있습니다.

예를 들어:

WWW-Authenticate: Basic realm="simple", Newauth realm="apps",
                 type=1, title="Login to \"apps\""

이 헤더 필드는 "simple"이라는 realm 값을 가진 "Basic" 스킴에 대한 챌린지와 "apps"라는 realm 값을 가진 "Newauth" 스킴에 대한 다른 챌린지, 그리고 "type"과 "title"이라는 추가 매개변수 두 개를 포함합니다.

그러나 일부 사용자 에이전트는 이러한 형식을 인식하지 못할 수 있습니다. 결과적으로 같은 헤더 라인에 멤버가 둘 이상 포함된 WWW-Authenticate 필드 값을 보내는 것은 상호운용성이 없을 수 있습니다.

11.6.2. Authorization

"Authorization" 헤더 필드는 사용자 에이전트가 출처 서버에 대해 자신을 인증할 수 있게 합니다 — 보통은 401 (Unauthorized) 응답을 받은 후입니다. 그 값은 요청된 리소스의 realm에 대한 사용자 에이전트의 인증 정보를 담은 자격 증명으로 구성됩니다.

요청이 인증되었고 realm이 지정된 경우, 동일한 자격 증명은 해당 realm 내의 다른 모든 요청에 대해 유효한 것으로 추정됩니다(인증 스킴 자체가 달리 요구하지 않는 한, 예: 챌린지 값에 따라 자격 증명이 달라지거나 동기화된 시계를 사용하는 경우).

프록시가 요청을 전달할 때 해당 요청의 어떤 Authorization 헤더 필드도 수정해서는 MUST NOT 합니다. 인증된 요청에 대한 응답을 저장하는 방법 및 Authorization 헤더 필드 처리에 관한 요구사항은 섹션 3.5 of [CACHING]를 참조하십시오.

11.6.3. Authentication-Info

HTTP 인증 스킴은 클라이언트의 인증 자격 증명이 수락된 이후 서버가 정보를 전달하기 위해 "Authentication-Info" 응답 필드를 사용할 수 있습니다. 이 정보에는 서버의 최종화 메시지(예: 서버 인증)가 포함될 수 있습니다.

필드 값은 섹션 11.3에 정의된 "auth-param" 문법을 사용하는 매개변수(이름/값 쌍) 목록입니다. 이 명세서는 일반 형식만 설명하며, Authentication-Info를 사용하는 인증 스킴은 개별 매개변수를 정의합니다. 예를 들어 "Digest" 인증 스킴은 RFC7616 섹션 3.5에서 여러 매개변수를 정의합니다.

Authentication-Info 필드는 요청 메서드나 상태 코드와 무관하게 어떤 HTTP 응답에서도 사용할 수 있습니다. 그 의미는 해당 요청의 Authorization 헤더 필드(섹션 11.6.2)가 나타내는 인증 스킴에 의해 정의됩니다.

프록시가 응답을 전달할 때 필드 값을 어떤 방식으로든 수정하는 것은 허용되지 않습니다.

Authentication-Info는 인증 스킴이 명시적으로 허용하는 경우 트레일러 필드(섹션 6.5)로 전송될 수 있습니다.

11.7. 클라이언트의 프록시 인증

11.7.1. Proxy-Authenticate

"Proxy-Authenticate" 헤더 필드는 이 요청에 대해 프록시에 적용되는 인증 스킴과 매개변수를 나타내는 적어도 하나의 챌린지로 구성됩니다. 프록시는 생성하는 각 407 (Proxy Authentication Required) 응답에 대해 최소 하나의 Proxy-Authenticate 헤더 필드를 전송해야 MUST 합니다.

WWW-Authenticate와 달리, Proxy-Authenticate 헤더 필드는 응답 체인에서 다음 아웃바운드 클라이언트에만 적용됩니다. 이는 특정 프록시를 선택한 클라이언트만이 해당 인증에 필요한 자격 증명을 가질 가능성이 높기 때문입니다. 그러나 동일한 관리 도메인 내에서 여러 프록시가 사용되는 경우(예: 대규모 기업 네트워크의 사무실 및 지역 캐싱 프록시), 자격 증명이 사용자 에이전트에 의해 생성되어 계층을 통해 전달되어 소비될 수 있습니다. 따라서 이러한 구성에서는 각 프록시가 동일한 챌린지 집합을 전송하여 Proxy-Authenticate가 전달되는 것처럼 보일 수 있습니다.

WWW-Authenticate에 대한 구문 분석 고려사항이 이 헤더 필드에도 적용된다는 점에 유의하십시오; 자세한 내용은 섹션 11.6.1을 참조하십시오.

11.7.2. Proxy-Authorization

"Proxy-Authorization" 헤더 필드는 클라이언트가 인증을 요구하는 프록시에 자신(또는 사용자)을 식별할 수 있게 합니다. 그 값은 프록시 및/또는 요청된 리소스의 realm에 대한 클라이언트의 인증 정보를 포함하는 자격 증명으로 구성됩니다.

Authorization과 달리, Proxy-Authorization 헤더 필드는 인증을 요구한 다음 인바운드 프록시에만 적용됩니다. 프록시 체인이 사용되는 경우 Proxy-Authorization 헤더 필드는 자격 증명을 기대한 첫 번째 인바운드 프록시에 의해 소비됩니다. 프록시는 프록시들이 협력적으로 요청을 인증하는 메커니즘이라면 클라이언트 요청의 자격 증명을 다음 프록시로 중계할 수 MAY 있습니다.

11.7.3. Proxy-Authentication-Info

"Proxy-Authentication-Info" 응답 헤더 필드는 Authentication-Info와 동등하지만, 프록시 인증에 적용되며 그 의미는 해당 요청의 Proxy-Authorization 헤더 필드(섹션 11.7.2)가 나타내는 인증 스킴에 의해 정의됩니다.

그러나 Authentication-Info와 달리, Proxy-Authentication-Info 헤더 필드는 응답 체인에서 다음 아웃바운드 클라이언트에만 적용됩니다. 이는 특정 프록시를 선택한 클라이언트만이 해당 인증에 필요한 자격 증명을 가질 가능성이 높기 때문입니다. 다만, 동일한 관리 도메인 내에서 여러 프록시가 사용되는 구성에서는 사용자 에이전트가 자격 증명을 생성하여 계층을 통해 전달하는 것이 일반적이므로, 각 프록시가 동일한 필드 값을 보낼 경우 Proxy-Authentication-Info가 전달되는 것처럼 보일 수 있습니다.

Proxy-Authentication-Info는 인증 스킴이 명시적으로 허용하는 경우 트레일러 필드(섹션 6.5)로 전송될 수 있습니다.

12. 콘텐츠 협상

응답이 성공이든 오류든 콘텐츠를 전달할 때, 출처 서버는 종종 그 정보를 여러 방식으로 표현할 수 있습니다. 예를 들어 서로 다른 형식, 언어 또는 인코딩으로 제공할 수 있습니다. 마찬가지로 서로 다른 사용자나 사용자 에이전트는 사용할 수 있는 표현들 중에서 어떤 표현을 제공하는 것이 가장 적절한지에 영향을 줄 수 있는 서로 다른 기능, 특성 또는 선호도를 가질 수 있습니다. 이러한 이유로 HTTP는 콘텐츠 협상을 위한 메커니즘을 제공합니다.

이 명세서는 프로토콜 내에서 드러날 수 있는 세 가지 콘텐츠 협상 패턴을 정의합니다: 서버가 사용자 에이전트의 명시된 선호도에 기초해 표현을 선택하는 "사전적(proactive)" 협상(서버 주도 협상), 서버가 사용자 에이전트가 선택할 수 있도록 표현 목록을 제공하는 "반응적(reactive)" 협상, 그리고 서버의 과거 응답에서 명시한 선호도에 따라 사용자 에이전트가 향후 요청의 표현을 선택하는 "요청-콘텐츠(request content)" 협상입니다.

다른 콘텐츠 협상 패턴으로는 사용자 에이전트 매개변수에 따라 선택적으로 렌더링되는 여러 파트로 이루어진 표현인 "조건부 콘텐츠(conditional content)", 표현에 스크립트를 포함하여 사용자 에이전트 특성에 기반해 추가(보다 구체적인) 요청을 수행하는 "액티브 콘텐츠(active content)", 그리고 중개자가 콘텐츠 선택을 수행하는 "투명 콘텐츠 협상(Transparent Content Negotiation)"([RFC2295])이 있습니다. 이러한 패턴들은 상호 배타적이지 않으며 각각 적용성 및 실용성 측면에서 장단점이 있습니다.

모든 경우에 HTTP는 리소스 의미를 인식하지 못한다는 점에 유의하십시오. 특정 시점과 콘텐츠 협상의 다양한 차원들에 걸쳐 출처 서버가 요청에 어떻게 응답하는지, 그리고 결과적으로 관찰된 리소스 표현들의 시간에 따른 "동일성(sameness)"은 전적으로 그러한 응답을 선택하거나 생성하는 엔터티나 알고리즘에 의해 결정됩니다.

12.1. 사전적 협상 (Proactive Negotiation)

사용자 에이전트가 요청에서 콘텐츠 협상 선호도를 전송하여 서버에 위치한 알고리즘이 우선 표현을 선택하도록 유도할 때, 이를 사전적 협상(또는 서버 주도 협상)이라고 합니다. 선택은 응답을 위한 사용 가능한 표현들(언어, 콘텐츠 코딩 등처럼 변할 수 있는 차원)을 요청에 제공된 여러 정보—아래에 정의된 명시적 협상 헤더 필드들과 클라이언트의 네트워크 주소 또는 User-Agent 필드의 일부와 같은 암묵적 특성—와 비교하여 이뤄집니다.

사전적 협상은 사용 가능한 표현 중에서 선택하는 알고리즘을 사용자 에이전트에게 설명하기 어려운 경우나 서버가 첫 응답과 함께 "최선의 추측(best guess)"을 사용자 에이전트에 보내고자 할 때 유리합니다(그 추측이 사용자에게 충분히 좋다면 후속 요청의 왕복 지연을 피할 수 있습니다). 서버의 추측을 개선하기 위해 사용자 에이전트는 요청 헤더 필드들을 전송할 수 있습니다(MAY).

사전적 협상에는 심각한 단점들이 있습니다:

  • 서버가 어떤 사용자의 "최선"이 무엇인지 정확히 결정하는 것은 불가능합니다. 이는 사용자 에이전트의 기능과 응답의 의도된 사용(예: 화면에서 볼 것인지 인쇄할 것인지)을 완전히 알 필요가 있기 때문입니다;
  • 모든 요청에서 사용자 에이전트가 자신의 기능을 설명하게 하는 것은 매우 비효율적일 수 있고(응답의 소수만이 복수 표현을 갖기 때문에) 사용자의 프라이버시에 대한 위험이 될 수 있습니다;
  • 출처 서버와 요청에 대한 응답 생성 알고리즘의 구현을 복잡하게 만듭니다; 그리고
  • 공유 캐싱을 위한 응답 재사용성을 제한합니다.

사용자 에이전트는 출처 서버가 요청된 리소스에 대해 사전적 협상을 구현하지 않거나, 사용자 에이전트의 선호도를 따르지 않고 선호도에 맞지 않는 응답을 보내는 것이 406 (Not Acceptable) 응답을 보내는 것보다 낫다고 판단할 수 있으므로, 사전적 협상 선호도가 일관되게 존중될 것이라고 신뢰할 수 없습니다.

사전적 협상 대상인 응답에서는 어떤 요청 정보 부분이 선택 알고리즘에 사용되었는지 표시하기 위해 종종 Vary 헤더 필드(Section 12.5.5)가 전송됩니다.

사용자 에이전트가 사전적 협상에 참여하기 위해 전송할 수 있는 요청 헤더 필드는 Accept, Accept-Charset, Accept-Encoding, 및 Accept-Language로 아래에서 정의됩니다. 이들 필드에 전송된 선호도는 대상 리소스의 표현, 오류나 처리 상태의 표현, 그리고 프로토콜 내에 나타날 수 있는 기타 텍스트 문자열을 포함한 응답의 모든 콘텐츠에 적용됩니다.

12.2. 반응적 협상 (Reactive Negotiation)

반응적 협상(reactive negotiation)(또는 에이전트 주도 협상)에서는 콘텐츠 선택(상태 코드에 관계없이)이 초기 응답을 받은 후 사용자 에이전트에 의해 수행됩니다. 반응적 협상 메커니즘은 대체 표현들에 대한 참조 목록처럼 간단할 수 있습니다.

사용자 에이전트가 초기 응답 콘텐츠에 만족하지 못하면, 하나 이상의 대체 리소스에 대해 GET 요청을 수행하여 다른 표현을 얻을 수 있습니다. 이러한 대체 선택은 자동으로(사용자 에이전트에 의해) 또는 수동으로(예: 하이퍼텍스트 메뉴에서 사용자가 선택) 이루어질 수 있습니다.

서버는 초기 표현 대신 대체 목록만 전송하여 사용자 에이전트의 반응적 협상을 선호함을 표시할 수 있습니다. 예를 들어, 300 (Multiple Choices)406 (Not Acceptable) 상태 코드의 응답에 나열된 대체 항목들은 사용 가능 표현에 대한 정보를 포함하여 사용자 또는 사용자 에이전트가 선택하도록 합니다.

반응적 협상은 응답이 흔히 사용되는 차원들(예: 타입, 언어 또는 인코딩)에 따라 달라지는 경우, 출처 서버가 요청을 검사하여 사용자 에이전트의 기능을 결정할 수 없는 경우, 그리고 일반적으로 공개 캐시가 서버 부하를 분산하고 네트워크 사용을 줄이는 데 사용되는 경우에 유리합니다.

반응적 협상은 대체 목록을 사용자 에이전트로 전송해야 하는 단점(헤더 섹션에서 전송될 경우 사용자 지각 지연을 악화시킴)과 대체 표현을 얻기 위해 두 번째 요청이 필요하다는 단점이 있습니다. 또한 이 명세서는 자동 선택을 지원하는 메커니즘을 정의하지 않지만, 그러한 메커니즘의 개발을 금지하지는 않습니다.

12.3. 요청 콘텐츠 협상 (Request Content Negotiation)

서버의 응답에서 콘텐츠 협상 선호도가 전송될 때, 나열된 선호도는 향후 해당 리소스에 대한 요청의 적절한 콘텐츠 선택에 영향을 주려는 의도로 요청 콘텐츠 협상(request content negotiation)이라고 불립니다. 예를 들어 응답에서 전송될 수 있는 헤더 필드인 Accept(Section 12.5.1) 및 Accept-Encoding(Section 12.5.3)는 이후 해당 리소스에 대한 요청에서 선호되는 미디어 타입과 콘텐츠 코딩을 나타내기 위해 응답에 포함될 수 있습니다.

유사하게, RFC5789 섹션 3.1은 PATCH 요청에서 허용되는 콘텐츠 타입을 발견할 수 있게 하는 "Accept-Patch" 응답 헤더 필드를 정의합니다.

12.4. 콘텐츠 협상 필드의 특징

12.4.1. 부재(Absence)

각 콘텐츠 협상 필드에 대해, 해당 필드를 포함하지 않는 요청은 발신자가 해당 협상 차원에 대해 선호가 없음을 의미합니다.

요청에 콘텐츠 협상 헤더 필드가 포함되어 있고 사용 가능한 응답 표현 중 어느 것도 그 필드에 따라 허용될 수 없다고 간주되는 경우, 출처 서버는 해당 헤더 필드를 존중하여 406 (Not Acceptable) 응답을 보내거나 그 헤더 필드를 무시하여 해당 요청 헤더 필드에 대해 콘텐츠 협상의 대상이 아닌 것처럼 응답을 처리할 수 있습니다. 그러나 이는 클라이언트가 실제로 그 표현을 사용할 수 있다는 것을 보장하지는 않습니다.

12.4.2. 품질 값(Quality Values)

이 명세서에서 정의된 콘텐츠 협상 필드들은 공통 매개변수인 "q"(대소문자 구분 없음)를 사용하여 관련 종류의 콘텐츠에 대한 상대적 "가중치"를 지정할 수 있습니다. 이 가중치는 종종 서버 구성에서 리소스에 대해 선택 가능한 다양한 표현의 상대적 품질에 가중치를 부여하는 데 사용되므로 "품질 값(qvalue)"이라고 불립니다.

가중치는 0에서 1 사이의 실수로 정규화되며, 0.001이 가장 덜 선호되고 1이 가장 선호됩니다; 값 0은 "허용되지 않음"을 의미합니다. "q" 파라미터가 없으면 기본 가중치는 1입니다.

  weight = OWS ";" OWS "q=" qvalue
  qvalue = ( "0" [ "." 0*3DIGIT ] )
         / ( "1" [ "." 0*3("0") ] )

qvalue를 전송하는 발신자는 소수점 이하 세 자리를 초과하여 생성해서는 MUST NOT 합니다. 사용자 구성도 동일한 방식으로 제한되어야 합니다.

12.4.3. 와일드카드 값(Wildcard Values)

해당 헤더 필드들 중 대부분은 명시된 경우 미지정 값을 선택하는 와일드카드 값("*")을 정의합니다. 와일드카드가 없으면 필드에 명시적으로 언급되지 않은 값은 허용되지 않는 것으로 간주됩니다. Vary 내에서 와일드카드 값은 분산(variance)이 무제한임을 의미합니다.

12.5. 콘텐츠 협상 필드

12.5.1. Accept

"Accept" 헤더 필드는 사용자 에이전트가 응답의 미디어 타입에 관해 자신의 선호도를 지정하는 데 사용할 수 있습니다. 예를 들어 인라인 이미지 요청처럼 요청이 특정한 소수의 원하는 타입으로 제한된 경우 이를 나타내는 데 사용될 수 있습니다.

서버가 응답에 포함하여 전송할 경우, Accept는 동일한 리소스에 대한 이후 요청의 콘텐츠에서 어떤 콘텐츠 타입이 선호되는지에 대한 정보를 제공합니다.

  Accept = #( media-range [ weight ] )

  media-range    = ( "*/*"
                     / ( type "/" "*" )
                     / ( type "/" subtype )
                   ) parameters

별표 "*" 문자는 미디어 타입을 범위로 그룹화하는 데 사용되며, "*/*"는 모든 미디어 타입을, "type/*"는 해당 타입의 모든 서브타입을 나타냅니다. media-range는 해당 범위에 적용 가능한 미디어 타입 파라미터를 포함할 수 있습니다.

각 media-range 뒤에는 선택적으로 적용 가능한 미디어 타입 파라미터(예: charset)가 올 수 있으며, 그 뒤에 상대적 가중치를 나타내는 선택적 "q" 파라미터가 올 수 있습니다(Section 12.4.2).

이전 규격은 가중치 파라미터 뒤에 확장 파라미터가 나타나는 것을 허용했었습니다. accept 확장 문법(accept-params, accept-ext)은 복잡하게 정의되어 있고 실무에서 사용되지 않았으며 새로운 헤더 필드를 통해 더 쉽게 배포될 수 있으므로 제거되었습니다. 가중치를 사용하는 발신자는 "q"를 마지막에 보내는 것이 SHOULD 합니다(모든 media-range 파라미터 뒤). 수신자는 파라미터 순서와 관계없이 이름이 "q"인 어떤 파라미터든 가중치로 처리해야 SHOULD 합니다.

예시

Accept: audio/*; q=0.2, audio/basic

는 "나는 audio/basic을 선호하지만, 이용 가능한 최선의 선택에서 품질을 80%로 할인한 뒤 어떤 audio 타입이라도 보내라"로 해석됩니다.

좀 더 정교한 예시는

Accept: text/plain; q=0.5, text/html,
       text/x-dvi; q=0.8, text/x-c

말로 표현하면 "text/html 및 text/x-c가 동등하게 선호되며, 이것들이 없으면 text/x-dvi를 보내고, 그것도 없으면 text/plain을 보내라"가 됩니다.

미디어 범위는 더 구체적인 범위나 특정 미디어 타입으로 재정의될 수 있습니다. 주어진 타입에 대해 둘 이상의 media range가 적용되면 가장 구체적인 참조가 우선합니다. 예를 들어,

Accept: text/*, text/plain, text/plain;format=flowed, */*

는 다음과 같은 우선순위를 가집니다:

  1. text/plain;format=flowed
  2. text/plain
  3. text/*
  4. */*

주어진 타입에 연관된 미디어 타입 품질 계수는 해당 타입과 일치하는 가장 높은 우선순위의 media range를 찾아 결정됩니다. 예를 들어,

Accept: text/*;q=0.3, text/plain;q=0.7, text/plain;format=flowed,
       text/plain;format=fixed;q=0.4, */*;q=0.5

는 다음 값들을 연관시킵니다:

Table 5
Media Type Quality Value
text/plain;format=flowed 1
text/plain 0.7
text/html 0.3
image/jpeg 0.5
text/plain;format=fixed 0.4
text/html;level=3 0.7

12.5.2. Accept-Charset

"Accept-Charset" 헤더 필드는 사용자 에이전트가 텍스트 응답 콘텐츠에서 선호하는 문자 집합(charset)을 나타내기 위해 보낼 수 있습니다. 예를 들어, 더 포괄적이거나 특수 목적의 문자 집합을 이해할 수 있는 사용자 에이전트는 해당 기능을 출처 서버에 신호할 수 있습니다.

  Accept-Charset = #( ( token / "*" ) [ weight ] )

문자셋 이름은 섹션 8.3.2에서 정의됩니다. 사용자 에이전트는 각 문자셋에 대해 품질 값을 연결하여 해당 문자셋에 대한 상대적 선호도를 나타낼 수 있습니다(섹션 12.4.2). 예:

Accept-Charset: iso-8859-5, unicode-1-1;q=0.8

Accept-Charset 필드에 "*" 특수 값이 있으면, 이는 필드의 다른 곳에 명시되지 않은 모든 문자셋과 일치합니다.

12.5.3. Accept-Encoding

"Accept-Encoding" 헤더 필드는 콘텐츠 코딩(Section 8.4.1)의 사용에 관한 선호도를 나타내는 데 사용될 수 있습니다.

사용자 에이전트가 요청에서 전송할 때, Accept-Encoding은 응답에서 허용되는 콘텐츠 코딩을 나타냅니다.

서버가 응답에서 전송할 때, Accept-Encoding은 이후 동일 리소스에 대한 요청의 콘텐츠에서 어떤 콘텐츠 코딩이 선호되는지를 나타냅니다.

"identity" 토큰은 "인코딩 없음(no encoding)"의 동의어로 사용되어 인코딩이 없음을 선호할 때 이를 전달합니다.

  Accept-Encoding  = #( codings [ weight ] )
  codings          = content-coding / "identity" / "*"

각 codings 값은 해당 인코딩에 대한 선호도를 나타내는 품질 값(가중치)을 가질 수 있습니다(Section 12.4.2). Accept-Encoding 필드의 "*" 기호는 필드에 명시적으로 나열되지 않은 이용 가능한 콘텐츠 코딩과 일치합니다.

예시:

Accept-Encoding: compress, gzip
Accept-Encoding:
Accept-Encoding: *
Accept-Encoding: compress;q=0.5, gzip;q=1.0
Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0

서버는 주어진 표현의 콘텐츠 코딩이 허용되는지 다음 규칙을 사용하여 테스트합니다:

  1. 요청에 Accept-Encoding 헤더 필드가 없으면, 어떠한 콘텐츠 코딩도 사용자 에이전트에 의해 허용되는 것으로 간주됩니다.
  2. 표현에 콘텐츠 코딩이 없으면, Accept-Encoding 헤더 필드가 "identity;q=0" 또는 "*;q=0"을 명시하고 "identity"에 대한 더 구체적인 항목이 없지 않는 한, 기본적으로 허용됩니다.
  3. 표현의 콘텐츠 코딩이 Accept-Encoding 필드 값에 나열된 콘텐츠 코딩 중 하나이면, 그 qvalue가 0이 아닌 한 허용됩니다. (섹션 12.4.2에 정의된 대로 qvalue 0은 "허용되지 않음"을 의미합니다.)

표현은 여러 콘텐츠 코딩으로 인코딩될 수 있습니다. 그러나 대부분의 콘텐츠 코딩은 동일한 목적(예: 데이터 압축)을 달성하는 대안적 방법입니다. 동일한 목적을 가진 여러 콘텐츠 코딩 중에서 선택할 때, 가장 높은 비제로 qvalue를 가진 허용 가능한 콘텐츠 코딩이 선호됩니다.

빈 필드 값을 가진 Accept-Encoding 헤더 필드는 사용자 에이전트가 응답에 어떤 콘텐츠 코딩도 원하지 않는다는 것을 의미합니다. 비어 있지 않은 Accept-Encoding 헤더 필드가 요청에 존재하고 사용 가능한 응답 표현 중 어느 것도 나열된 허용 가능한 콘텐츠 코딩을 갖지 않는다면, 출처 서버는 identity 코딩이 허용되지 않은 것으로 표시되지 않는 한 콘텐츠 코딩이 없는 응답을 전송해야 SHOULD 합니다.

응답에 Accept-Encoding 헤더 필드가 존재하면, 그것은 해당 요청에서 리소스가 받아들일 의향이 있던 콘텐츠 코딩을 나타냅니다. 필드 값은 요청에서와 동일한 방식으로 평가됩니다.

이 정보는 연관된 요청에 특정적임에 유의하십시오; 동일 서버의 다른 리소스에 대한 지원 인코딩 집합은 다를 수 있고 시간에 따라 변경되거나 요청의 다른 측면(예: 요청 메서드)에 따라 달라질 수 있습니다.

지원되지 않는 콘텐츠 코딩 때문에 요청이 실패하는 서버는 415 (Unsupported Media Type) 상태로 응답하고 해당 응답에 Accept-Encoding 헤더 필드를 포함하여 클라이언트가 콘텐츠 코딩 관련 문제와 미디어 타입 관련 문제를 구별할 수 있도록 해야 합니다. 미디어 타입과 관련 없는 이유로 415 상태로 요청을 실패시키는 서버는 혼동을 피하기 위해 Accept-Encoding 헤더 필드를 포함해서는 MUST NOT 합니다.

Accept-Encoding의 가장 일반적인 사용은 클라이언트가 낙관적으로 콘텐츠 코딩을 사용했지만 실패한 경우에 대한 415 응답에서입니다. 그러나 이 헤더 필드는 또한 향후 상호작용을 최적화하기 위해 클라이언트에게 콘텐츠 코딩이 지원됨을 알리는 데 사용될 수 있습니다. 예를 들어, 요청 콘텐츠가 압축 사용을 정당화할 만큼 충분히 클 경우 리소스는 2xx 응답에 이를 포함할 수 있습니다.

12.5.4. Accept-Language

"Accept-Language" 헤더 필드는 사용자 에이전트가 응답에서 선호하는 자연어 집합을 표시하는 데 사용할 수 있습니다. 언어 태그는 섹션 8.5.1에 정의되어 있습니다.

각 language-range에는 그 범위에 지정된 언어에 대한 사용자의 선호 추정치를 나타내는 품질 값을 부여할 수 있습니다(섹션 12.4.2). 예를 들어,

Accept-Language: da, en-gb;q=0.8, en;q=0.7

는 "덴마크어를 선호하지만 영국식 영어와 기타 영어도 허용한다"는 의미입니다.

일부 수신자는 언어 태그가 나열된 순서를 동일한 품질 값을 가진 태그들에 대해 내림차순 우선순위의 표시로 취급하기도 하지만(값이 없으면 q=1과 동일), 이 동작에 의존해서는 안 됩니다. 일관성과 상호운용성을 극대화하기 위해 많은 사용자 에이전트는 각 언어 태그에 고유한 품질 값을 부여하면서 또한 내림차순 품질 순서로 나열합니다. 언어 우선순위 목록에 대한 추가 논의는 RFC4647 섹션 2.3을 참조하십시오.

매칭을 위해서는 RFC4647의 섹션 3이 여러 매칭 스킴을 정의합니다. 구현체는 요구사항에 가장 적합한 매칭 스킴을 제공할 수 있습니다. "기본 필터링(Basic Filtering)" 스킴([RFC4647], RFC4647 섹션 3.3.1)은 이전 HTTP 규격에서 정의된 매칭 스킴과 동일합니다.

사용자의 언어적 이해 가능성은 개인에 크게 의존하므로, 사용자 에이전트는 언어 선호 설정에 대해 사용자가 제어할 수 있도록 해야 합니다(사용자 에이전트 자체의 구성 또는 사용자 제어가 가능한 시스템 설정을 기본으로 함). 이러한 제어를 사용자에게 제공하지 않는 사용자 에이전트는 Accept-Language 헤더 필드를 보내서는 MUST NOT 합니다.

12.5.5. Vary

응답의 "Vary" 헤더 필드는 메서드와 대상 URI를 제외한 요청 메시지의 어떤 부분이 이 응답의 콘텐츠 선택 과정에 영향을 미쳤을 수 있는지를 설명합니다.

  Vary = #( "*" / field-name )

Vary 필드 값은 와일드카드 "*"이거나, 이 응답의 표현을 선택하는 데 역할을 했을 수 있는 요청 필드 이름들의 목록(선택 헤더 필드)입니다. 잠재적 선택 헤더 필드는 이 명세서에 정의된 필드에만 국한되지 않습니다.

"*" 멤버를 포함하는 목록은 요청의 다른 측면(예: 클라이언트의 네트워크 주소)을 포함하여 응답 표현 선택에 역할을 했을 수 있음을 알립니다. 수신자는 이 응답이 이후의 요청에 적합한지 결정할 수 없으므로 원점 서버에 요청을 전달하지 않고는 판단할 수 없습니다. 프록시는 Vary 필드 값으로 "*"를 생성해서는 MUST NOT 합니다.

예를 들어, 다음을 포함하는 응답은

Vary: accept-encoding, accept-language

출처 서버가 이 응답의 콘텐츠를 선택할 때 요청의 Accept-EncodingAccept-Language 헤더 필드(또는 그 부재)를 결정 요인으로 사용했을 수 있음을 나타냅니다.

필드 이름 목록을 포함하는 Vary 필드에는 두 가지 목적이 있습니다:

  1. 캐시 수신자에게 이 응답을 나중 요청에 재사용하려면 원래 요청과 나중 요청이 나열된 헤더 필드에 대해 동일한 값을 가져야 하며(Section 4.1 of [CACHING] 참조), 그렇지 않으면 출처 서버에 의해 재사용이 검증되어야 MUST NOT 합니다. 즉, Vary는 새로운 요청이 저장된 캐시 항목과 일치하기 위해 필요한 캐시 키를 확장합니다.

  2. 사용자 에이전트 수신자에게 이 응답이 콘텐츠 협상의 대상이었음을 알리고(Section 12) 나열된 헤더 필드에 다른 값이 제공되면 이후의 요청에서 다른 표현이 전송될 수 있음을 알립니다(proactive negotiation).

출처 서버는 이후 요청에 대해 이 응답을 선택적으로 재사용하기를 원할 때 캐시 가능한 응답에 Vary 헤더 필드를 생성하는 것이 SHOULD 합니다. 일반적으로 이는 응답 콘텐츠가 선택 헤더 필드에 의해 표현이 맞춤화된 경우에 해당합니다(예: 출처 서버가 요청의 Accept-Language 헤더 필드를 기반으로 응답 언어를 선택한 경우).

Vary는 응답 선택에서의 분산이 캐싱에 미치는 성능 영향보다 덜 중요하다고 출처 서버가 판단할 때 생략될 수 있습니다. 특히 재사용이 이미 캐시 응답 지시자(Section 5.2 of [CACHING])에 의해 제한되는 경우 그러합니다.

Authorization 필드 이름은 해당 응답을 다른 사용자에 대해 재사용하는 것이 금지되어 있으므로 Vary에 포함할 필요가 없습니다(Section 11.6.2). 마찬가지로, 응답 콘텐츠가 네트워크 지역에 의해 선택되었지만 출처 서버가 캐시된 응답을 수신자가 지역을 이동하더라도 재사용되게 하려는 경우, 출처 서버는 Vary에 그러한 분산을 표시할 필요가 없습니다.

13. Conditional Requests

조건부 요청은 하나 이상의 요청 헤더 필드를 포함하여 대상 리소스에 요청 메서드를 적용하기 전에 테스트할 선행 조건을 나타내는 HTTP 요청입니다. Section 13.2는 여러 선행 조건이 존재할 때 언제 선행 조건을 평가할지와 우선순위 순서를 정의합니다.

조건부 GET 요청은 HTTP 캐시 업데이트를 위한 가장 효율적인 메커니즘입니다 [CACHING]. 조건부는 또한 PUT 및 DELETE와 같은 상태 변경 메서드에 적용되어 "lost update" 문제 — 병행으로 작동하는 다른 클라이언트의 작업을 우발적으로 덮어쓰는 것 — 를 방지할 수 있습니다.

13.1. Preconditions

선행 조건은 보통 대상 리소스 전체의 상태(그 현재 값 집합)에 대해 또는 이전에 획득한 표현에서 관찰된 상태(그 집합의 한 값)에 대해 정의됩니다. 리소스가 각자 고유한 관찰 가능한 상태를 가진 복수의 현재 표현을 보유하는 경우, 선행 조건은 각 요청이 선택된 표현(Section 3.2)으로 매핑되는 것이 시간 경과 동안 일관된다고 가정합니다. 어쨌든 매핑이 일관되지 않거나 서버가 적절한 표현을 선택할 수 없을 때, 선행 조건이 거짓으로 평가되더라도 해가 발생하지 않습니다.

아래에 정의된 각 선행 조건은 대상 리소스의 이전 표현으로부터 얻은 밸리데이터 집합과 선택된 표현의 현재 밸리데이터 상태 간의 비교로 구성됩니다(Section 8.8). 따라서 이러한 선행 조건은 클라이언트가 알고 있는 특정 상태 이후에 대상 리소스의 상태가 변경되었는지를 평가합니다. 이러한 평가의 효과는 메서드 의미와 조건의 선택에 따라 달라지며, 이는 Section 13.2에 정의되어 있습니다.

확장 필드로서 다른 명세에서 정의한 다른 선행 조건은 모든 수신자에 대해, 대상 리소스의 일반적인 상태에 대해, 또는 리소스 그룹에 대해 조건을 부과할 수 있습니다. 예를 들어 WebDAV의 "If" 헤더 필드는 수신자가 해당 필드를 이해하고 구현하는 경우 잠금과 같은 여러 리소스의 다양한 측면에 요청을 조건화할 수 있습니다 ([WEBDAV], Section 10.4).

선행 조건의 확장성은 오직 선행 조건을 알 수 없을 때 안전하게 무시할 수 있을 때(예: If-Modified-Since와 같은 경우), 특정 사용 사례에 대해 배포를 가정할 수 있을 때, 또는 대상 리소스의 다른 특성으로 구현이 신호될 때만 가능합니다. 이는 공통 표준의 상호 합의된 배포에 초점을 맞추도록 장려합니다.

13.1.1. If-Match

"If-Match" 헤더 필드는 필드 값이 "*"일 때 수신자 출처 서버가 대상 리소스의 적어도 하나의 현재 표현을 가지고 있음을 조건으로 하거나, 필드 값에 제공된 엔터티 태그 목록 중 하나와 일치하는 엔터티 태그를 가진 대상 리소스의 현재 표현을 가지고 있음을 조건으로 하여 요청 메서드를 조건화합니다.

출처 서버는 If-Match에 대해 엔터티 태그를 비교할 때 강한 비교 함수를 사용해야 MUST 합니다(Section 8.8.3.2). 클라이언트는 이 선행 조건이 표현 데이터에 어떤 변경이라도 있었을 경우 메서드 적용을 방지하도록 의도했기 때문입니다.

  If-Match = "*" / #entity-tag

예시:

If-Match: "xyzzy"
If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-Match: *

If-Match는 주로 여러 사용자 에이전트가 동일한 리소스에서 병행으로 작동할 때 우발적인 덮어쓰기를 방지하기 위해 상태 변경 메서드(e.g., POST, PUT, DELETE)와 함께 사용됩니다(즉, "lost update" 문제를 방지). 일반적으로 선택되거나 수정되는 표현이 포함된 모든 메서드에 사용될 수 있으며, 선택된 표현의 현재 엔터티 태그가 If-Match 필드 값의 멤버가 아니면 요청을 중단합니다.

출처 서버가 표현을 선택하는 요청을 수신하고 그 요청에 If-Match 헤더 필드가 포함된 경우, 출처 서버는 메서드를 수행하기 전에 Section 13.2에 따라 If-Match 조건을 평가해야 MUST 합니다.

수신된 If-Match 헤더 필드를 평가하는 방법:

  1. 필드 값이 "*"인 경우, 출처 서버가 대상 리소스에 대한 현재 표현을 가지고 있으면 조건은 참입니다.
  2. 필드 값이 엔터티 태그 목록인 경우, 나열된 태그들 중 어느 하나라도 선택된 표현의 엔터티 태그와 일치하면 조건은 참입니다.
  3. 그 밖의 경우, 조건은 거짓입니다.

If-Match 조건을 평가한 출처 서버는 그 조건이 거짓으로 평가되면 요청된 메서드를 수행해서는 MUST NOT 합니다. 대신 출처 서버는 조건부 요청이 실패했음을 나타내기 위해 412 (Precondition Failed) 상태 코드로 응답할 수 MAY 있습니다. 또는 요청이 선택된 표현에 이미 적용된 것으로 보이는 상태 변경 연산인 경우, 출처 서버는 사용자 에이전트가 이를 인식하지 못했을 수 있으므로 2xx (Successful) 상태 코드로 응답할 수 MAY 있습니다(예: 이전 응답이 손실되었거나 다른 사용자 에이전트가 동등한 변경을 수행한 경우).

변경 요청이 이미 적용된 것으로 보일 때 출처 서버가 성공 응답을 보내는 것은 많은 저작(use-case)에서 더 효율적이지만, 여러 사용자 에이전트가 매우 유사하지만 협력적이지 않은 변경 요청을 하는 경우 일부 상태 전이가 손실될 위험이 있습니다. 예를 들어 공통 리소스에 대해 원자적이지 않은 증가 연산을 세마포어처럼 사용하는 여러 에이전트는 충돌 가능성이 큽니다. 이런 종류의 리소스에 대해서는 출처 서버가 비안전 메서드의 모든 실패한 선행 조건에 대해 412를 엄격하게 보내는 것이 더 낫습니다. 다른 경우에는 성공 응답에서 ETag 필드를 제외하면 사용자 에이전트가 다음 요청으로 GET을 수행하여 리소스의 현재 상태에 대한 혼동을 해소하도록 유도할 수 있습니다.

클라이언트는 선택된 표현이 일치하지 않을 경우 412 (Precondition Failed) 응답을 선호함을 나타내기 위해 GET 요청에 If-Match 헤더 필드를 전송할 수 MAY 있습니다. 그러나 이것은 부분 표현을 완성하기 위한 범위 요청(Section 14)에서만 유용합니다. If-Range(If-Range, Section 13.1.5)가 클라이언트가 새 표현을 선호할 때 범위 요청에 더 적합합니다.

캐시 또는 중개자는 상호운용성 특징이 출처 서버에만 필요하므로 If-Match를 무시할 수 MAY 있습니다.

If-Match 헤더 필드가 "*"와 다른 값들(다른 "*" 인스턴스 포함)을 동시에 포함하는 목록 값을 갖는 것은 문법적으로 유효하지 않으며(따라서 생성해서는 안 됨) 또한 상호운용성이 없을 가능성이 높습니다.

13.1.2. If-None-Match

"If-None-Match" 헤더 필드는 수신자 캐시나 출처 서버가 필드 값이 "*"일 때 대상 리소스에 대한 어떠한 현재 표현도 가지고 있지 않거나, 선택된 표현의 엔터티 태그가 필드 값에 나열된 것들과 일치하지 않는 경우에만 요청 메서드를 허용하도록 조건화합니다.

수신자는 If-None-Match에 대해 엔터티 태그를 비교할 때 약한 비교 함수를 사용해야 MUST 합니다(Section 8.8.3.2). 약한 엔터티 태그는 표현 데이터에 변경이 있더라도 캐시 검증에 사용될 수 있기 때문입니다.

예시:

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

If-None-Match는 주로 조건부 GET 요청에서 캐시된 정보를 최소한의 트랜잭션 오버헤드로 효율적으로 업데이트할 수 있게 사용됩니다. 클라이언트가 엔터티 태그를 가진 하나 이상의 저장된 응답을 업데이트하려는 경우, 클라이언트는 GET 요청을 만들 때 해당 엔터티 태그 목록을 포함하는 If-None-Match 헤더 필드를 생성해야 SHOULD 합니다. 이렇게 하면 수신 서버는 선택된 표현이 저장된 응답 중 하나와 일치할 때 304 (Not Modified) 응답을 보내 이를 나타낼 수 있습니다.

If-None-Match는 또한 값 "*"을 사용하여 클라이언트가 대상 리소스에 현재 표현이 없다고 믿을 때 비안전 요청 메서드(e.g., PUT)가 기존 표현을 우발적으로 수정하는 것을 방지할 수 있습니다(Section 9.2.1). 이는 클라이언트 여러 명이 대상 리소스의 초기 표현을 생성하려고 시도할 때 발생할 수 있는 "lost update" 문제의 변형입니다.

출처 서버가 표현을 선택하는 요청을 수신하고 그 요청에 If-None-Match 헤더 필드가 포함된 경우, 출처 서버는 메서드를 수행하기 전에 Section 13.2에 따라 If-None-Match 조건을 평가해야 MUST 합니다.

수신된 If-None-Match 헤더 필드를 평가하는 방법:

  1. 필드 값이 "*"인 경우, 출처 서버가 대상 리소스에 대한 현재 표현을 가지고 있으면 조건은 거짓입니다.
  2. 필드 값이 엔터티 태그 목록인 경우, 나열된 태그들 중 하나가 선택된 표현의 엔터티 태그와 일치하면 조건은 거짓입니다.
  3. 그 밖의 경우, 조건은 참입니다.

If-None-Match 조건을 평가한 출처 서버는 그 조건이 거짓으로 평가되면 요청된 메서드를 수행해서는 MUST NOT 합니다; 대신 출처 서버는 다음 중 하나로 응답해야 MUST 합니다: a) 요청 메서드가 GET 또는 HEAD인 경우 304 (Not Modified) 상태 코드, 또는 b) 다른 모든 요청 메서드에 대해서는 412 (Precondition Failed) 상태 코드.

수신된 If-None-Match 헤더 필드의 캐시 처리에 대한 요구사항은 Section 4.3.2 of [CACHING]에 정의되어 있습니다.

If-None-Match 헤더 필드가 "*"와 다른 값들(다른 "*" 인스턴스 포함)을 동시에 포함하는 목록 값을 갖는 것은 문법적으로 유효하지 않으며(따라서 생성해서는 안 됨) 또한 상호운용성이 없을 가능성이 높습니다.

13.1.3. If-Modified-Since

"If-Modified-Since" 헤더 필드는 GET 또는 HEAD 요청 메서드를 선택된 표현의 수정 날짜가 필드 값으로 제공된 날짜보다 더 최근인 경우에만 수행되도록 조건화합니다. 선택된 표현의 데이터 전송은 해당 데이터가 변경되지 않았다면 회피됩니다.

필드의 예:

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

수신자는 요청이 If-None-Match 헤더 필드를 포함하는 경우 If-Modified-Since를 무시해야 MUST 합니다; If-None-Match의 조건이 If-Modified-Since 조건보다 더 정확한 대체로 간주되며, 두 필드는 If-None-Match를 구현하지 않을 수 있는 오래된 중개자와의 상호운용성을 위해서만 결합됩니다.

수신자는 If-Modified-Since 헤더 필드의 값이 유효한 HTTP-date가 아니거나 필드 값이 둘 이상 존재하거나 요청 메서드가 GET 또는 HEAD가 아닌 경우 If-Modified-Since를 무시해야 MUST 합니다.

수신자는 리소스에 수정 날짜가 제공되지 않는 경우 If-Modified-Since 헤더 필드를 무시해야 MUST 합니다.

수신자는 If-Modified-Since 필드 값의 타임스탬프를 출처 서버의 시계 기준으로 해석해야 MUST 합니다.

If-Modified-Since는 일반적으로 두 가지 목적에 사용됩니다: 1) 엔터티 태그가 없는 캐시된 표현의 효율적인 업데이트를 허용하기 위해, 2) 웹 탐색 범위를 최근에 변경된 리소스로 제한하기 위해.

캐시 업데이트에 사용될 때, 캐시는 보통 캐시된 메시지의 Last-Modified 헤더 필드 값을 사용하여 If-Modified-Since의 필드 값을 생성합니다. 이 동작은 시계가 잘 동기화되지 않았거나 서버가 정확한 타임스탬프 일치를 선호할 때 가장 상호운용적입니다(예: 출처 서버의 시계가 수정되었거나 표현이 아카이브 백업에서 복원된 경우 Last-Modified 날짜가 "과거로 돌아가는" 문제가 발생할 수 있음). 그러나 캐시는 캐시된 메시지에 Last-Modified 헤더 필드가 없는 경우 수신 시의 Date 헤더 필드나 메시지를 받은 시각 같은 다른 데이터를 기반으로 필드 값을 생성하기도 합니다.

최근 시간 창으로 검색 범위를 제한하는 데 사용될 때, 사용자 에이전트는 자신의 시계나 이전 응답에서 서버로부터 받은 Date 헤더 필드를 기반으로 If-Modified-Since 값을 생성합니다. 선택된 표현의 Last-Modified 헤더 필드에 기반한 엄격한 타임스탬프 일치를 선택하는 출처 서버는 지정된 창 동안에 변경된 항목만 사용자 에이전트가 제한하도록 도울 수 없습니다.

출처 서버가 표현을 선택하는 요청을 수신하고 그 요청에 If-None-Match 헤더 필드 없이 If-Modified-Since 헤더 필드가 포함된 경우, 출처 서버는 메서드를 수행하기 전에 If-Modified-Since 조건을 Section 13.2에 따라 평가하는 것이 SHOULD 합니다.

수신된 If-Modified-Since 헤더 필드를 평가하는 방법:

  1. 선택된 표현의 마지막 수정 날짜가 필드 값으로 제공된 날짜보다 이전이거나 같다면, 조건은 거짓입니다.
  2. 그렇지 않으면, 조건은 참입니다.

If-Modified-Since 조건을 평가한 출처 서버는 조건이 거짓으로 평가되면 요청된 메서드를 수행해서는 SHOULD NOT 하며, 대신 이전에 캐시된 응답을 식별하거나 업데이트하는 데 유용한 메타데이터만 포함하는 304 (Not Modified) 응답을 생성해야 SHOULD 합니다.

수신된 If-Modified-Since 헤더 필드의 캐시 처리에 대한 요구사항은 Section 4.3.2 of [CACHING]에 정의되어 있습니다.

13.1.4. If-Unmodified-Since

"If-Unmodified-Since" 헤더 필드는 요청 메서드를 선택된 표현의 마지막 수정 날짜가 필드 값으로 제공된 날짜보다 이전이거나 같을 경우에만 수행하도록 조건화합니다. 이 필드는 사용자 에이전트가 표현에 대한 엔터티 태그를 가지고 있지 않은 경우 If-Match와 동일한 목적을 달성합니다.

필드의 예:

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

수신자는 요청에 If-Match 헤더 필드가 포함된 경우 If-Unmodified-Since를 무시해야 MUST 합니다; If-Match의 조건이 If-Unmodified-Since 조건보다 더 정확한 대체로 간주되며, 두 필드는 If-Match를 구현하지 않을 수 있는 오래된 중개자와의 상호운용성을 위해서만 결합됩니다.

수신자는 If-Unmodified-Since 헤더 필드의 값이 유효한 HTTP-date가 아니거나(값이 날짜 목록처럼 보이는 경우 포함)면 If-Unmodified-Since를 무시해야 MUST 합니다.

수신자는 리소스에 수정 날짜가 제공되지 않는 경우 If-Unmodified-Since 헤더 필드를 무시해야 MUST 합니다.

수신자는 If-Unmodified-Since 필드 값의 타임스탬프를 출처 서버의 시계 기준으로 해석해야 MUST 합니다.

If-Unmodified-Since는 리소스가 표현에 엔터티 태그를 제공하지 않는 경우에 여러 사용자 에이전트가 병행으로 작동할 때 우발적인 덮어쓰기를 방지하기 위해 상태 변경 메서드(e.g., POST, PUT, DELETE)와 함께 가장 자주 사용됩니다(즉, "lost update" 문제 방지). 일반적으로 이는 선택되거나 수정되는 표현이 포함된 모든 메서드에 사용되어 선택된 표현의 마지막 수정 날짜가 If-Unmodified-Since 값 이후로 변경되었을 경우 요청을 중단합니다.

출처 서버가 표현을 선택하는 요청을 수신하고 그 요청에 If-Unmodified-Since 헤더 필드가 포함되었지만 If-Match 헤더 필드는 없는 경우, 출처 서버는 메서드를 수행하기 전에 Section 13.2에 따라 If-Unmodified-Since 조건을 평가해야 MUST 합니다.

수신된 If-Unmodified-Since 헤더 필드를 평가하는 방법:

  1. 선택된 표현의 마지막 수정 날짜가 필드 값으로 제공된 날짜보다 이전이거나 같으면, 조건은 참입니다.
  2. 그렇지 않으면, 조건은 거짓입니다.

If-Unmodified-Since 조건을 평가한 출처 서버는 그 조건이 거짓으로 평가되면 요청된 메서드를 수행해서는 MUST NOT 합니다. 대신 출처 서버는 조건부 요청이 실패했음을 나타내기 위해 412 (Precondition Failed) 상태 코드로 응답할 수 MAY 있습니다. 또는 요청이 선택된 표현에 이미 적용된 것으로 보이는 상태 변경 연산인 경우, 출처 서버는 사용자 에이전트가 이를 인식하지 못했을 수 있으므로 2xx (Successful) 상태 코드로 응답할 수 MAY 있습니다.

변경 요청이 이미 적용된 것으로 보일 때 출처 서버가 성공 응답을 보내는 것은 많은 저작(use-case)에서 더 효율적이지만, 여러 사용자 에이전트가 매우 유사하지만 협력적이지 않은 변경 요청을 하는 경우 일부 위험이 있습니다. 그런 경우 출처 서버는 비안전 메서드의 모든 실패한 선행 조건에 대해 412를 엄격하게 보내는 것이 더 낫습니다.

클라이언트는 선택된 표현이 수정되었을 경우 412 (Precondition Failed) 응답을 선호함을 나타내기 위해 GET 요청에 If-Unmodified-Since 헤더 필드를 전송할 수 MAY 있습니다. 그러나 이것은 범위 요청(Section 14)에서만 유용하며, If-Range(If-Range, Section 13.1.5)가 클라이언트가 새 표현을 선호할 때 범위 요청에 더 적합합니다.

캐시 또는 중개자는 상호운용성 기능이 출처 서버에만 필요하므로 If-Unmodified-Since를 무시할 수 MAY 있습니다.

13.1.5. If-Range

"If-Range" 헤더 필드는 If-MatchIf-Unmodified-Since 헤더 필드와 유사하지만 특별한 조건부 요청 메커니즘을 제공하며, 밸리데이터가 일치하지 않으면 수신자에게 Range 헤더 필드를 무시하도록 지시하여 412 (Precondition Failed) 응답 대신 새 선택된 표현의 전체 전송이 일어나게 합니다.

클라이언트에게 표현의 부분 복사본이 있고 전체 표현의 최신 복사본을 원할 경우, 조건부 GET과 함께 Range 헤더 필드를 사용할 수 있습니다(예: If-Unmodified-Since 및/또는 If-Match 중 하나 또는 둘을 사용). 그러나 선행 조건이 표현이 수정되었기 때문에 실패하면, 클라이언트는 전체 현재 표현을 얻기 위해 두 번째 요청을 해야 합니다.

"If-Range" 헤더 필드는 클라이언트가 두 번째 요청을 "단축"할 수 있게 합니다. 비공식적으로 그 의미는 다음과 같습니다: 표현이 변경되지 않았다면 내가 Range로 요청한 부분들을 보내고, 그렇지 않으면 전체 표현을 보내라.

유효한 entity-tag은 처음 세 문자에서 DQUOTE를 검사하여 유효한 HTTP-date와 구별할 수 있습니다.

클라이언트는 Range 헤더 필드를 포함하지 않는 요청에서 If-Range 헤더 필드를 생성해서는 MUST NOT 합니다. 서버는 Range 헤더 필드를 포함하지 않는 요청에서 수신된 If-Range 헤더 필드를 무시해야 MUST 합니다. 출처 서버는 Range 요청을 지원하지 않는 대상 리소스에 대해 수신된 If-Range 헤더 필드를 무시해야 MUST 합니다.

클라이언트는 엔터티 태그가 약한 것으로 표시된 If-Range 헤더 필드를 생성해서는 MUST NOT 합니다. 클라이언트는 해당 표현에 대한 엔터티 태그가 없고 그 날짜가 Section 8.8.2.2에 정의된 의미에서 강한 밸리데이터인 경우가 아니면 HTTP-date를 포함하는 If-Range 헤더 필드를 생성해서는 MUST NOT 합니다.

서버는 Range 요청에서 If-Range 헤더 필드를 수신하면, 메서드를 수행하기 전에 Section 13.2에 따라 조건을 평가해야 MUST 합니다.

HTTP-date를 포함하는 If-Range 헤더 필드를 평가하는 방법:

  1. 제공된 HTTP-date 밸리데이터가 Section 8.8.2.2에 정의된 의미에서 강한 밸리데이터가 아니면, 조건은 거짓입니다.
  2. 제공된 HTTP-date 밸리데이터가 선택된 표현의 Last-Modified 필드 값과 정확히 일치하면, 조건은 참입니다.
  3. 그렇지 않으면, 조건은 거짓입니다.

entity-tag를 포함하는 If-Range 헤더 필드를 평가하는 방법:

  1. 제공된 entity-tag 밸리데이터가 강한 비교 함수(Section 8.8.3.2)를 사용하여 선택된 표현의 ETag 필드 값과 정확히 일치하면, 조건은 참입니다.
  2. 그렇지 않으면, 조건은 거짓입니다.

If-Range 헤더 필드의 수신자는 If-Range 조건이 거짓으로 평가되면 Range 헤더 필드를 무시해야 MUST 합니다. 그렇지 않으면 수신자는 요청된 대로 Range 헤더 필드를 처리해야 SHOULD 합니다.

If-Range 비교는 HTTP-date인 경우를 포함하여 정확한 일치로 수행된다는 점을 주의하십시오. 따라서 이는 If-Unmodified-Since 조건을 평가할 때 사용되는 "이전이거나 같음" 비교와 다릅니다.

13.2. Evaluation of Preconditions

13.2.1. When to Evaluate

아래에 제외된 경우를 제외하고, 수신자 캐시 또는 출처 서버는 정상적인 요청 검사를 성공적으로 수행한 후, 요청 콘텐츠(있는 경우)를 처리하거나 요청 메서드와 관련된 작업을 수행하기 직전에 수신된 요청 선행 조건을 평가해야 MUST 합니다. 서버는 조건 없이 동일한 요청에 대해 요청 콘텐츠를 처리하기 전에의 응답이 2xx (Successful) 또는 412 (Precondition Failed) 이외의 상태 코드였을 경우 모든 수신 선행 조건을 무시해야 MUST 합니다. 다시 말해, 중요한 처리가 발생하기 전에 감지할 수 있는 리디렉션과 실패가 선행 조건 평가보다 우선합니다.

대상 리소스의 출처 서버가 아니어서 대상 리소스에 대한 요청을 위한 캐시로서 작동할 수 없는 서버는 이 명세서에서 정의한 조건부 요청 헤더 필드를 평가해서는 MUST NOT 하며, 요청이 전달되는 경우 이를 전달해야 MUST 합니다. 클라이언트는 해당 필드들이 현재 표현을 제공할 수 있는 서버에 의해 평가되기를 의도했기 때문입니다. 마찬가지로, 서버는 CONNECT, OPTIONS 또는 TRACE와 같이 선택된 표현의 선택 또는 수정을 수반하지 않는 요청 메서드와 함께 수신된 이 명세서에서 정의된 조건부 요청 헤더 필드를 무시해야 MUST 합니다.

프로토콜 확장은 선행 조건이 평가되는 조건이나 그 평가의 결과를 수정할 수 있습니다. 예를 들어 immutable 캐시 지시자([RFC8246])는 캐시가 신선한 응답을 보유하고 있을 때 조건부 요청을 전달하지 않도록 지시합니다.

조건부 요청 헤더 필드는 HEAD 메서드와 함께 사용 가능하도록 정의되어 있습니다(HEAD의 의미를 GET과 일관되게 유지하기 위해) — 다만 조건부 HEAD를 전송하는 것은 의미가 없습니다. 성공 응답은 304 (Not Modified) 응답과 동일한 크기이고 412 (Precondition Failed) 응답보다 더 유용합니다.

13.2.2. Precedence of Preconditions

요청에 둘 이상의 조건부 요청 헤더 필드가 존재할 때, 필드들이 평가되는 순서가 중요해집니다. 실무에서는 "lost update" 선행 조건이 캐시 검증보다 더 엄격한 요구사항을 가지며, 검증된 캐시는 부분 응답보다 더 효율적이고, 엔터티 태그가 날짜 밸리데이터보다 더 정확하다고 여겨지기 때문에 이 문서에서 정의된 필드들이 단일 논리적 순서로 일관되게 구현됩니다.

수신자 캐시 또는 출처 서버는 이 명세서에서 정의한 요청 선행 조건을 다음 순서로 평가해야 MUST 합니다:

  1. 수신자가 출처 서버이고 If-Match가 존재하는 경우, If-Match 선행 조건을 평가합니다:

    • 참이면, 3단계(3)로 계속합니다
    • 거짓이면, 상태 변경 요청이 이미 성공했는지 판단할 수 없는 한 412 (Precondition Failed)로 응답합니다(자세한 내용은 Section 13.1.1 참조).
  2. 수신자가 출처 서버이고 If-Match가 없고 If-Unmodified-Since가 존재하는 경우, If-Unmodified-Since 선행 조건을 평가합니다:

    • 참이면, 3단계(3)로 계속합니다
    • 거짓이면, 상태 변경 요청이 이미 성공했는지 판단할 수 없는 한 412 (Precondition Failed)로 응답합니다(자세한 내용은 Section 13.1.4 참조).
  3. If-None-Match가 존재하는 경우, If-None-Match 선행 조건을 평가합니다:

  4. 메서드가 GET 또는 HEAD이고 If-None-Match가 없고 If-Modified-Since가 존재하는 경우, If-Modified-Since 선행 조건을 평가합니다:

  5. 메서드가 GET이고 RangeIf-Range가 모두 존재하는 경우, If-Range 선행 조건을 평가합니다:

  6. 그 외의 경우,

    • 요청된 메서드를 수행하고 그 성공 또는 실패에 따라 응답합니다.

HTTP에 대한 확장은 이 문서에 정의된 필드들과 실무에서 발견될 수 있는 다른 조건부 필드들에 대해 그러한 필드들을 평가하는 순서를 정의해야 합니다.

14. 범위 요청

클라이언트는 종종 요청 취소나 연결 끊김으로 인해 데이터 전송이 중단되는 상황을 겪습니다. 클라이언트가 부분 표현을 저장하고 있는 경우 전체 표현을 다시 전송받기보다 후속 요청에서 그 표현의 나머지를 요청하는 것이 바람직합니다. 마찬가지로, 로컬 저장공간이 제한된 장치는 매우 큰 문서의 단일 페이지나 임베디드 이미지의 치수처럼 더 큰 표현의 일부 집합만 요청할 수 있으면 유익할 수 있습니다.

Range 요청은 HTTP의 OPTIONAL 기능으로, 이 기능을 구현하지 않거나 대상 리소스에 대해 지원하지 않는 수신자가 상호운용성에 영향을 주지 않고 일반적인 GET 요청처럼 응답할 수 있도록 설계되었습니다. 부분 응답은 기능을 구현하지 않을 수 있는 캐시가 전체 응답으로 오해하지 않도록 별도의 상태 코드로 표시됩니다.

14.1. 범위 단위

표현 데이터는 해당 데이터의 콘텐츠 인코딩 또는 미디어 타입에 내재된 주소 지정 가능한 구조 단위가 있을 때 하위 범위로 분할될 수 있습니다. 예를 들어, 옥텟(바이트) 경계는 모든 표현 데이터에 공통적인 구조 단위로, 데이터의 시작 또는 끝으로부터의 오프셋으로 바이트 범위를 식별하여 데이터를 분할할 수 있게 합니다.

이러한 일반적인 range unit 개념은 응답 헤더 필드인 Accept-Ranges (Section 14.3)에서 범위 요청 지원을 광고하는 데 사용되며, 요청 헤더 필드인 Range (Section 14.2)는 요청된 표현의 부분을 구분하고, Content-Range (Section 14.4) 헤더 필드는 전송되는 표현의 어느 부분인지 설명하는 데 사용됩니다.

모든 range unit 이름은 대소문자 구분이 없으며 Section 16.5.1에 정의된 "HTTP Range Unit Registry"에 등록되어야 합니다.

Range unit은 Section 16.5에 설명된 것처럼 확장 가능하도록 의도되었습니다.

14.1.1. 범위 지정자

범위는 범위 단위와 범위 지정자 집합으로 표현됩니다. 범위 단위 이름은 해당 단위에 적용 가능한 범위 지정자 종류를 결정합니다. 따라서 다음 문법은 일반적입니다: 각 range unit은 언제 int-range, suffix-range, 및 other-range가 허용되는지를 지정해야 합니다.

범위 요청은 단일 범위 또는 단일 표현 내의 여러 범위를 지정할 수 있습니다.

int-range은 두 개의 음이 아닌 정수로 표현되거나 하나의 음이 아닌 정수부터 표현 데이터의 끝까지를 나타내는 범위입니다. 범위 단위는 정수들이 무엇을 의미하는지(예: 시작부터의 단위 오프셋, 포함 번호 매겨진 부분 등)를 지정합니다.

int-rangelast-pos 값이 존재하고 그것이 first-pos보다 작을 경우 무효입니다.

suffix-range는 제공된 음이 아닌 정수 최대 길이(범위 단위에서)의 접미사로 표현되는 범위입니다. 다시 말해 표현 데이터의 마지막 N 단위입니다.

확장성을 제공하기 위해, other-range 규칙은 애플리케이션별 또는 미래의 범위 단위가 추가 범위 지정자를 정의할 수 있도록 거의 제약이 없는 문법을 허용합니다.

  other-range   = 1*( %x21-2B / %x2D-7E )
                ; 1*(VCHAR excluding comma)

ranges-specifier에 무효이거나 해당 range-unit에 대해 정의되지 않은 어떤 range-spec가 포함되어 있으면 그 ranges-specifier는 무효입니다.

유효한 ranges-specifier는 적어도 하나의 해당 range-unit에 대해 정의된 만족 가능한 range-spec을 포함하는 경우 satisfiable로 간주됩니다. 그렇지 않으면 unsatisfiable입니다.

14.1.2. 바이트 범위

"bytes" 범위 단위는 표현 데이터의 옥텟(바이트) 시퀀스의 하위 범위를 표현하는 데 사용됩니다. 각 바이트 범위는 표현 데이터의 시작(int-range) 또는 끝(suffix-range)을 기준으로 한 오프셋에서의 정수 범위로 표현됩니다. 바이트 범위는 other-range 지정자를 사용하지 않습니다.

bytes int-rangefirst-pos 값은 범위 내 첫 바이트의 오프셋을 제공합니다. last-pos 값은 범위 내 마지막 바이트의 오프셋을 제공합니다; 즉 지정된 바이트 위치는 포함적입니다. 바이트 오프셋은 0에서 시작합니다.

표현 데이터에 콘텐츠 인코딩이 적용된 경우, 각 바이트 범위는 디코딩 후 얻어지는 기본 바이트 시퀀스가 아니라 인코딩된 바이트 시퀀스를 기준으로 계산됩니다.

바이트 범위 지정자 예시:

  • 처음 500 바이트(바이트 오프셋 0-499, 포함):

    bytes=0-499
    
  • 두 번째 500 바이트(바이트 오프셋 500-999, 포함):

    bytes=500-999
    

클라이언트는 선택된 표현의 길이를 알지 못하더라도 요청하는 바이트 수를 제한할 수 있습니다. last-pos 값이 없거나 그 값이 현재 표현 길이보다 크거나 같으면 바이트 범위는 표현의 나머지로 해석됩니다(즉, 서버는 last-pos 값을 선택된 표현의 현재 길이보다 하나 작은 값으로 대체합니다).

클라이언트는 suffix-range를 사용하여 선택된 표현의 마지막 N 바이트(N > 0)를 참조할 수 있습니다. 선택된 표현이 지정된 suffix-length보다 짧으면 전체 표현이 사용됩니다.

추가 예시(표현 길이가 10000이라고 가정):

  • 마지막 500 바이트(바이트 오프셋 9500-9999, 포함):

    bytes=-500
    

    또는:

    bytes=9500-
    
  • 처음과 마지막 바이트만(바이트 0 및 9999):

    bytes=0-0,-1
    
  • 처음, 중간, 마지막 각각 1000 바이트:

    bytes= 0-999, 4500-5499, -1000
    
  • 두 번째 500 바이트(바이트 오프셋 500-999, 포함)의 다른 유효한(하지만 정규형이 아닌) 명세:

    bytes=500-600,601-999
    bytes=500-700,601-999
    

GET 요청의 경우 유효한 bytes range-spec는 다음 중 하나일 때 satisfiable합니다:

선택된 표현의 길이가 0일 때, GET 요청에서 만족 가능한 형태의 range-spec은 비제로 suffix-length을 갖는 suffix-range뿐입니다.

바이트-범위 문법에서 first-pos, last-pos, 및 suffix-length은 옥텟의 십진수로 표현됩니다. 콘텐츠 길이에 대한 사전 정의된 제한이 없으므로, 수신자는 잠재적으로 큰 십진수에 대비하고 정수 변환 오버플로로 인한 파싱 오류를 방지해야 MUST 합니다.

14.2. Range

GET 요청의 "Range" 헤더 필드는 전체 selected representation 대신 선택된 표현 데이터(Section 8.1)의 하나 이상의 하위 범위 전송을 요청하도록 메서드 의미를 변경합니다.

서버는 Range 헤더 필드를 무시할 MAY 있습니다. 그러나 출처 서버와 중간 캐시는 부분 전송에서 효율적인 복구와 큰 표현의 부분 검색을 지원하므로 가능하면 바이트 범위를 지원해야 ought to 합니다.

서버는 인식되지 않거나 범위 처리가 정의되지 않은 요청 메서드와 함께 수신된 Range 헤더 필드를 무시해야 MUST 합니다. 이 명세서에서 범위 처리가 정의된 메서드는 GET뿐입니다.

출처 서버는 자신이 이해하지 못하는 범위 단위를 포함하는 Range 헤더 필드를 무시해야 MUST 합니다. 프록시는 이해하지 못하는 범위 단위를 포함하는 Range 헤더 필드를 폐기할 수 MAY 있습니다.

범위 요청을 지원하는 서버는 잘못된 ranges-specifier를 포함하거나, 두 개를 초과하는 중첩되는 범위를 가졌거나, 오름차순으로 나열되지 않은 많은 작은 범위 집합을 포함하는 Range 헤더 필드를 무시하거나 거부할 수 MAY 있습니다. 이는 손상된 클라이언트이거나 의도적인 서비스 거부 공격의 징후일 수 있기 때문입니다 (Section 17.15). 클라이언트는 동일한 데이터를 포함하는 단일 범위보다 처리 및 전송 면에서 본질적으로 덜 효율적인 여러 범위를 요청해서는 SHOULD NOT 합니다.

범위 요청을 지원하는 서버는 선택된 표현에 콘텐츠가 없는 경우(즉, 선택된 표현의 데이터 길이가 0인 경우) Range 헤더 필드를 무시할 수 MAY 있습니다.

여러 범위를 요청하는 클라이언트는 특별한 필요가 없는 한 해당 범위들을 오름차순으로 나열해야 SHOULD 합니다(이는 전체 표현에서 일반적으로 수신되는 순서). 예를 들어, 내부 파트 카탈로그를 가진 사용자 에이전트는 나중 파트를 먼저 요청해야 할 수 있습니다—특히 표현이 역순으로 저장된 페이지로 구성되어 있고 사용자 에이전트가 한 번에 한 페이지씩 전송하기를 원할 때 그렇습니다.

Range 헤더 필드는 Section 13.1에 정의된 선행 조건 헤더 필드들을 평가한 후, 그리고 Range 헤더가 없을 때의 결과가 200 (OK) 응답일 경우에만 평가됩니다. 즉, 조건부 GET이 304 (Not Modified) 응답을 생성할 경우 Range는 무시됩니다.

If-Range 헤더 필드(Section 13.1.5)는 Range 헤더 필드를 적용하기 위한 선행 조건으로 사용될 수 있습니다.

모든 선행 조건이 참이고, 서버가 대상 리소스에 대해 Range 헤더 필드를 지원하며, 수신된 Range 필드값이 대상 리소스에 대해 지원되는 range-unitranges-specifier이고, 그 ranges-specifier가 선택된 표현에 대해 satisfiable한 경우, 서버는 요청된 만족 가능한 range-spec(들)에 해당하는 하나 이상의 부분 표현을 포함하는 206 (Partial Content) 응답을 전송해야 SHOULD 합니다.

위의 내용이 서버가 요청된 모든 범위를 전송할 것임을 의미하지는 않습니다. 어떤 경우에는 요청된 범위의 일부만 먼저 전송하는 것이 가능하거나 효율적일 수 있으며, 클라이언트가 여전히 나머지 부분을 원하면 나중에 재요청하도록 기대할 수 있습니다(자세한 내용은 Section 15.3.7 참조).

모든 선행 조건이 참이고, 서버가 대상 리소스에 대해 Range 헤더 필드를 지원하며, 수신된 Range 필드값이 유효한 ranges-specifier을 포함하지만 그 range-unit이 해당 대상 리소스에서 지원되지 않거나 그 ranges-specifier가 선택된 표현에 대해 만족 불가(unsatisfiable)한 경우, 서버는 416 (Range Not Satisfiable) 응답을 보내야 SHOULD 합니다.

14.3. Accept-Ranges

응답의 "Accept-Ranges" 필드는 업스트림 서버가 해당 대상 리소스에 대해 범위 요청을 지원하는지 여부를 나타냅니다.

예를 들어, 바이트 범위 요청(Section 14.1.2)을 지원하는 서버는 다음과 같은 필드를 보낼 수 있습니다

Accept-Ranges: bytes

이는 해당 대상 리소스에 대해 바이트 범위 요청을 지원함을 나타내어 클라이언트가 동일한 요청 경로에서 향후 부분 요청을 사용할 것을 장려합니다. 범위 단위는 Section 14.1에 정의되어 있습니다.

클라이언트는 Accept-Ranges 필드를 수신했는지에 관계없이 범위 요청을 생성할 수 MAY 있습니다. 이 정보는 성능 개선과 불필요한 네트워크 전송 감소를 위한 조언일 뿐입니다.

반대로 클라이언트는 Accept-Ranges 필드를 수신했다고 해서 향후 범위 요청이 부분 응답을 반환할 것이라고 가정해서는 MUST NOT 합니다. 콘텐츠가 변경되었을 수 있고, 서버가 특정 시점이나 조건에서만 범위 요청을 지원할 수 있으며, 다음 요청을 다른 중개자가 처리할 수도 있기 때문입니다.

대상 리소스에 대해 어떤 종류의 범위 요청도 지원하지 않는 서버는 다음을 보낼 수 MAY 있습니다

Accept-Ranges: none

이는 클라이언트에게 동일한 요청 경로에서 범위 요청을 시도하지 말라는 조언입니다. "none" 범위 단위는 이 목적을 위해 예약되어 있습니다.

Accept-Ranges 필드는 트레일러 섹션으로 보낼 수 MAY 있지만, 정보가 특히 큰 전송의 중간 실패(트레일러가 수신되기 전)에 대한 재시작에 유용하므로 헤더 필드로 보내는 것이 바람직합니다.

14.4. Content-Range

"Content-Range" 헤더 필드는 단일 부분의 206 (Partial Content) 응답에서 포함된 selected representation의 부분 범위를 나타내기 위해 전송되며, multipart 206 응답의 각 파트에 포함된 본문 파트 내에서 각 파트에 포함된 범위를 표시하고(Section 14.6), 416 (Range Not Satisfiable) 응답에서는 선택된 표현에 관한 정보를 제공하는 데 사용됩니다.

206 (Partial Content) 응답이 수신자에게 이해되지 않는 range unit을 가진 Content-Range 헤더 필드를 포함하는 경우, 수신자는 이를 저장된 표현과 재조합하려 시도해서는 MUST NOT 합니다. 그러한 메시지를 수신한 프록시는 해당 메시지를 하류로 전달하는 것이 SHOULD 합니다.

Content-Range는 클라이언트와 출처 서버 간의 사적 합의에 따라 부분 PUT을 요청하기 위한 요청 수식어로서 요청에 보내질 수도 있습니다(Section 14.5 참조). 서버는 Content-Range 지원이 정의되지 않은 메서드와 함께 수신된 요청의 Content-Range 헤더 필드를 무시해야 MUST 합니다.

바이트 범위의 경우, 전송자는 범위가 추출된 표현의 전체 길이를 표시하는 것이 바람직합니다(SHOULD), 단 전체 길이를 알 수 없거나 결정하기 어려운 경우는 예외입니다. 전체 길이 대신 별표("*")를 사용하면 헤더 생성 시점에 표현 길이를 모른다는 것을 나타냅니다.

다음 예시는 송신자가 선택된 표현의 전체 길이를 1234 바이트로 알고 있을 때를 보여줍니다:

Content-Range: bytes 42-1233/1234

다음 예시는 전체 길이를 알지 못할 때를 보여줍니다:

Content-Range: bytes 42-1233/*

Content-Range 값은 range-resp가 그 last-pos 값이 first-pos 값보다 작거나, complete-length 값이 그 last-pos 값보다 작거나 같으면 무효입니다. 무효인 Content-Range를 수신한 수신자는 수신된 콘텐츠를 저장된 표현과 재조합하려 시도해서는 MUST NOT 합니다.

바이트-범위 요청에 대해 416 (Range Not Satisfiable) 응답을 생성하는 서버는 unsatisfied-range 값을 가진 Content-Range 헤더 필드를 보내는 것이 SHOULD 합니다. 예:

Content-Range: bytes */1234

416 응답의 complete-length는 선택된 표현의 현재 길이를 나타냅니다.

Content-Range 헤더 필드는 그 의미를 명시적으로 설명하지 않는 상태 코드에 대해서는 의미가 없습니다. 이 명세서에서는 206 (Partial Content)416 (Range Not Satisfiable) 상태 코드만 Content-Range에 의미를 부여합니다.

선택된 표현의 총합이 1234 바이트인 경우의 Content-Range 값 예시는 다음과 같습니다:

  • 처음 500 바이트:

    Content-Range: bytes 0-499/1234
    
  • 두 번째 500 바이트:

    Content-Range: bytes 500-999/1234
    
  • 처음 500 바이트를 제외한 모두:

    Content-Range: bytes 500-1233/1234
    
  • 마지막 500 바이트:

    Content-Range: bytes 734-1233/1234
    

14.5. 부분 PUT

일부 출처 서버는 요청에서 Content-Range 헤더 필드를 포함할 때 부분 표현에 대한 PUT을 지원합니다. 그러나 이러한 지원은 일관되지 않으며 사용자 에이전트와의 사적 합의에 따라 다릅니다. 일반적으로 이는 Content-Range 값이 표시하는 오프셋과 길이에 따라 대상 리소스의 상태가 일부 대체되도록 요청하는 것으로, 오프셋은 현재 선택된 표현을 기준으로 합니다.

출처 서버는 대상 리소스가 부분 PUT 요청을 지원하지 않는 경우 PUT 요청에서 Content-Range를 수신하면 400 (Bad Request) 상태 코드로 응답해야 SHOULD 합니다.

부분 PUT은 PUT의 원래 정의와 역호환되지 않습니다. 부분 PUT은 현재 표현을 완전 대체로 작성하도록 결과를 초래할 수 있습니다.

부분 리소스 업데이트는 또한 더 큰 리소스의 일부와 겹치거나 확장되는 상태를 가진 별도로 식별된 리소스를 대상으로 하거나, 부분 업데이트를 위해 특별히 정의된 메서드(예: [RFC5789]에 정의된 PATCH)를 사용하는 방식으로도 가능할 수 있습니다.

14.6. 미디어 타입 multipart/byteranges

206 (Partial Content) 응답 메시지가 여러 범위의 내용을 포함하는 경우, 그것들은 본문에서 여러 파트로 전송되며([RFC2046], Section 5.1) 미디어 타입 "multipart/byteranges"로 전송됩니다.

"multipart/byteranges" 미디어 타입은 각자 고유한 Content-TypeContent-Range 필드를 갖는 하나 이상의 본문 파트를 포함합니다. 필수인 boundary 파라미터는 각 본문 파트를 구분하는 경계 문자열을 지정합니다.

구현 참고사항:

  1. 본문의 첫 경계 문자열 앞에 추가 CRLF가 올 수 있습니다.
  2. [RFC2046]는 경계 문자열을 인용할 수 있도록 허용하지만, 일부 기존 구현체는 인용된 경계 문자열을 잘못 처리합니다.
  3. 많은 클라이언트와 서버는 "multipart/x-byteranges"라는 미디어 타입을 사용한 초기 초안에 맞춰 코딩되었으며, 이는 이 타입과 거의(하지만 완전히는) 호환됩니다.

이름에도 불구하고 "multipart/byteranges" 미디어 타입은 바이트 범위에 국한되지 않습니다. 다음 예시는 "exampleunit" 범위 단위를 사용합니다:

HTTP/1.1 206 Partial Content
Date: Tue, 14 Nov 1995 06:25:24 GMT
Last-Modified: Tue, 14 July 04:58:08 GMT
Content-Length: 2331785
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES

--THIS_STRING_SEPARATES
Content-Type: video/example
Content-Range: exampleunit 1.2-4.3/25

...the first range...
--THIS_STRING_SEPARATES
Content-Type: video/example
Content-Range: exampleunit 11.2-14.3/25

...the second range
--THIS_STRING_SEPARATES--

다음 정보는 "multipart/byteranges" 미디어 타입의 등록 양식으로 사용됩니다.

Type name:
multipart
Subtype name:
byteranges
Required parameters:
boundary
Optional parameters:
N/A
Encoding considerations:
only "7bit", "8bit", or "binary" are permitted
Security considerations:
see Section 17
Interoperability considerations:
N/A
Published specification:
RFC 9110 (see Section 14.6)
Applications that use this media type:
HTTP components supporting multiple ranges in a single request
Fragment identifier considerations:
N/A
Additional information:
Deprecated alias names for this type:
N/A
Magic number(s):
N/A
File extension(s):
N/A
Macintosh file type code(s):
N/A
Person and email address to contact for further information:
See Authors' Addresses section.
Intended usage:
COMMON
Restrictions on usage:
N/A
Author:
See Authors' Addresses section.
Change controller:
IESG

15. 상태 코드

응답의 상태 코드는 요청 결과와 응답의 의미(요청이 성공했는지 및 포함된 콘텐츠가 무엇인지 등)를 설명하는 세 자리 정수 코드입니다. 모든 유효한 상태 코드는 100에서 599 범위(포함) 내에 있습니다.

상태 코드의 첫 번째 숫자는 응답의 클래스(類)를 정의합니다. 마지막 두 자리는 분류 역할을 하지 않습니다. 첫 자리 숫자에는 다섯 가지 값이 있습니다:

HTTP 상태 코드는 확장 가능하게 설계되었습니다. 클라이언트는 모든 등록된 상태 코드의 의미를 이해할 필요는 없지만, 그러한 이해가 바람직합니다. 다만 클라이언트는 상태 코드의 첫 자리로 표시되는 클래스는 반드시 이해해야 하며(MUST), 인식하지 못하는 상태 코드를 해당 클래스의 x00 상태 코드와 동등하게 처리해야 합니다.

예를 들어, 클라이언트가 인식하지 못하는 471 상태 코드를 수신하면 첫 자리 숫자에서 클라이언트의 요청에 문제가 있음을 알 수 있으므로 응답을 400 (Bad Request) 상태 코드로 처리할 수 있습니다. 응답 메시지는 보통 상태를 설명하는 표현을 포함합니다.

100..599 범위를 벗어나는 값은 무효입니다. 구현체는 내부 통신(예: 라이브러리 오류)을 위해 종종 이 범위 밖의 세 자리 정수(600..999 등)를 사용할 수 있습니다. 무효 상태 코드를 가진 응답을 수신한 클라이언트는 응답을 5xx (Server Error) 상태 코드로 처리하는 것이 SHOULD 합니다.

단일 요청에는 여러 관련 응답이 있을 수 있습니다: 0개 이상(연속된) 중간(interim) (비-최종) 응답(정보성 범위인 1xx 코드)들이 있고, 그 뒤에 정확히 하나의 다른 범위에 속하는 최종(final) 응답이 옵니다.

15.1. 상태 코드 개요

아래에 나열된 상태 코드들은 이 명세서에서 정의된 것입니다. 여기의 이유 구문(reason phrases)은 권고사항일 뿐이며 — 로컬 동등 표현으로 대체하거나 완전히 생략해도 프로토콜에는 영향이 없습니다.

휴리스틱하게 캐시 가능하다고 정의된 상태 코드(예: 이 명세서의 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, 501)는 명시적 캐시 제어나 메서드 정의에 달리 표시되지 않는 한 캐시가 휴리스틱 만료로 재사용할 수 있습니다([CACHING] 참조). 다른 모든 상태 코드는 휴리스틱 캐시 가능하지 않습니다.

이 명세서의 범위를 벗어난 추가 상태 코드들이 HTTP용으로 정의되어 왔습니다. 모든 그러한 상태 코드는 Section 16.2에 설명된 "Hypertext Transfer Protocol (HTTP) Status Code Registry"에 등록되어야 합니다.

15.2. 정보성 1xx

1xx (정보성) 클래스의 상태 코드는 요청된 동작을 완료하고 최종 응답을 보내기 전에 연결 상태나 요청 진행 상황을 통신하기 위한 중간 응답을 나타냅니다. HTTP/1.0은 1xx 상태 코드를 정의하지 않았으므로, 서버는 HTTP/1.0 클라이언트에 1xx 응답을 보내서는 MUST NOT 합니다.

1xx 응답은 헤더 섹션의 끝으로 종료되며, 콘텐츠나 트레일러를 포함할 수 없습니다.

클라이언트는 최종 응답 전에 수신될 수 있는 하나 이상의 1xx 응답을 파싱할 수 있어야 하며(MUST), 예상치 못한 1xx 응답은 사용자 에이전트가 무시할 수 MAY 있습니다.

프록시는 자신이 1xx 응답의 생성을 요청하지 않은 경우 1xx 응답을 전달해야 MUST 합니다. 예를 들어 프록시가 요청을 전달할 때 "Expect: 100-continue" 헤더 필드를 추가하면 해당 프록시는 대응되는 100 (Continue) 응답을 전달할 필요가 없습니다.

15.2.1. 100 Continue

100 (Continue) 상태 코드는 요청의 초기 부분이 수신되었고 아직 서버에 의해 거부되지 않았다는 것을 나타냅니다. 서버는 요청이 완전히 수신되어 처리된 후 최종 응답을 보낼 의도가 있습니다.

요청에 Expect 헤더 필드가 포함되어 있고 그 안에 100-continue 기대가 있으면, 100 응답은 서버가 요청 본문을 받기를 원함을 나타냅니다(자세한 내용은 Section 10.1.1 참조). 클라이언트는 요청을 계속 전송하고 100 응답은 폐기하는 것이 바람직합니다.

요청에 Expect 헤더 필드가 없었다면 클라이언트는 이 중간 응답을 단순히 폐기할 수 있습니다.

15.2.2. 101 Switching Protocols

101 (Switching Protocols) 상태 코드는 서버가 Upgrade 헤더 필드(Section 7.8)를 통해 클라이언트의 요청을 이해하고 준수하여 이 연결에서 사용되는 응용 프로토콜을 변경하겠다는 의사를 나타낼 때 사용됩니다. 서버는 응답에 어떤 프로토콜이 이 응답 후에 유효할지 나타내는 Upgrade 헤더 필드를 생성해야 MUST 합니다.

서버는 이 프로토콜 전환이 유리할 때만 동의할 것으로 가정됩니다. 예를 들어, 오래된 버전보다 새 HTTP 버전으로 전환하는 것이 유리할 수 있고, 실시간 동기화 프로토콜로 전환하는 것이 적합한 경우도 있습니다.

15.3. 성공 2xx

2xx (성공) 클래스의 상태 코드는 클라이언트의 요청이 성공적으로 수신, 이해 및 수락되었음을 나타냅니다.

15.3.1. 200 OK

200 (OK) 상태 코드는 요청이 성공했음을 나타냅니다. 200 응답에 전송되는 콘텐츠는 요청 메서드에 따라 다릅니다. 이 명세서에서 정의한 메서드들에 대해 콘텐츠의 의도된 의미는 요약하면 다음과 같습니다:

Table 6
Request Method 응답 콘텐츠는 다음의 표현입니다:
GET 대상 리소스
HEAD 대상 리소스 (GET과 같지만 표현 데이터 전송 없음)
POST 동작의 상태 또는 얻은 결과
PUT, DELETE 동작의 상태
OPTIONS 대상 리소스에 대한 통신 옵션
TRACE 서버가 수신한 대로의 요청 메시지(트레이스를 반환)

CONNECT에 대한 응답을 제외하고, 200 응답은 메시지 프레이밍이 명시적으로 콘텐츠 길이가 0이라고 표시하지 않는 한 메시지 콘텐츠를 포함하는 것이 기대됩니다. 성공 시 콘텐츠 없음 선호를 요청하는 측면이 있다면 출처 서버는 대신 204 (No Content) 응답을 보내는 것이 바람직합니다. CONNECT의 경우 성공 결과가 터널이므로 200 응답 이후 즉시 터널이 시작되어 콘텐츠가 없습니다.

200 응답은 휴리스틱하게 캐시 가능하며, 즉 메서드 정의나 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

GET 또는 HEAD에 대한 200 응답에서 출처 서버는 선택된 표현에 대해 사용 가능한 밸리데이터 필드(Section 8.8)를 전송하는 것이 SHOULD 합니다. 강한 엔터티 태그와 Last-Modified 날짜를 함께 제공하는 것이 선호됩니다.

상태 변경 메서드에 대한 200 응답에서 전송되는 밸리데이터 필드는 요청을 성공적으로 적용한 결과로 형성된 새 표현의 현재 밸리데이터를 전달합니다. PUT 메서드(Section 9.3.4)는 이러한 밸리데이터 전송을 제한할 수 있는 추가 요구사항이 있음을 유의하십시오.

15.3.2. 201 Created

201 (Created) 상태 코드는 요청이 이행되어 하나 이상 새 리소스가 생성되었음을 나타냅니다. 요청으로 생성된 주요 리소스는 응답의 Location 헤더 필드로 식별되거나, Location 헤더가 없으면 대상 URI로 식별됩니다.

201 응답 콘텐츠는 일반적으로 생성된 리소스들을 설명하고 링크합니다. 응답에 전송된 밸리데이터 필드(Section 8.8)는 요청으로 생성된 새 표현에 대한 현재 밸리데이터를 전달합니다. PUT 메서드(Section 9.3.4)는 이러한 밸리데이터 전송을 제한할 수 있는 추가 요구사항이 있음을 유의하십시오.

15.3.3. 202 Accepted

202 (Accepted) 상태 코드는 요청이 처리 대상으로 접수되었지만 처리가 완료되지 않았음을 나타냅니다. 요청이 실제로 처리될지 여부는 처리가 실제로 일어날 때 허용되지 않을 수 있으므로 확정적이지 않습니다. HTTP에는 비동기 작업의 상태 코드를 재전송하는 수단이 없습니다.

202 응답은 의도적으로 비확정적입니다. 이는 서버가 요청을 어떤 다른 프로세스(예: 하루에 한 번만 실행되는 배치 프로세스)에 위임하면서 사용자 에이전트의 연결이 그 프로세스 완료까지 유지될 필요가 없도록 허용하기 위한 목적입니다. 이 응답과 함께 전송되는 표현은 요청의 현재 상태를 설명하고 요청이 언제 이행될지 추정치를 제공할 수 있는 상태 모니터를 가리키거나 포함해야 합니다.

15.3.4. 203 Non-Authoritative Information

203 (Non-Authoritative Information) 상태 코드는 요청이 성공했지만 포함된 콘텐츠가 변환 프록시(Section 7.7)에 의해 원본 서버의 200 (OK) 응답과 다르게 수정되었음을 나타냅니다. 이 상태 코드는 프록시가 변환을 적용했음을 수신자에게 알릴 수 있게 하며, 이는 이후 콘텐츠에 대한 결정을 내리는 데 영향을 줄 수 있습니다. 예를 들어, 향후 캐시 검증 요청은 동일한 요청 경로(동일한 프록시를 경유)에서만 적용될 수 있습니다.

203 응답은 휴리스틱하게 캐시 가능하며, 즉 메서드 정의나 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

15.3.5. 204 No Content

204 (No Content) 상태 코드는 서버가 요청을 성공적으로 이행했으며 응답 본문에 추가로 보낼 콘텐츠가 없음을 나타냅니다. 응답 헤더 필드의 메타데이터는 요청된 동작이 적용된 후의 대상 리소스 및 그 선택된 표현을 참조합니다.

예를 들어, PUT 요청에 대한 응답으로 204 상태 코드가 수신되고 응답에 ETag 필드가 포함되어 있으면, PUT이 성공했으며 ETag 필드 값은 해당 대상 리소스의 새 표현에 대한 엔터티 태그를 포함합니다.

204 응답은 서버가 대상 리소스에 동작을 성공적으로 적용했음을 나타내면서 사용자 에이전트가 현재의 "문서 보기"(있을 경우)에서 벗어날 필요가 없음을 의미합니다. 서버는 사용자 에이전트가 자체 인터페이스에 따라 성공을 사용자에게 알리고 응답의 새 또는 업데이트된 메타데이터를 활성 표현에 적용할 것이라고 가정합니다.

예를 들어 204 상태 코드는 "저장" 동작에 해당하는 문서 편집 인터페이스에서 자주 사용되어 사용자가 저장한 문서를 계속 편집할 수 있게 합니다. 또한 분산 버전 관리 시스템처럼 자동화된 데이터 전송이 빈번할 것으로 예상되는 인터페이스에서도 자주 사용됩니다.

204 응답은 헤더 섹션의 끝에서 종료되며 콘텐츠나 트레일러를 포함할 수 없습니다.

204 응답은 휴리스틱하게 캐시 가능하며, 즉 메서드 정의나 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

15.3.6. 205 Reset Content

205 (Reset Content) 상태 코드는 서버가 요청을 이행했으며 요청을 보낸 "문서 보기"를 원래 상태(출처 서버로부터 받은 상태)로 재설정하도록 사용자 에이전트에게 요청함을 나타냅니다.

이 응답은 폼, 메모장, 캔버스 등 데이터 입력을 지원하는 콘텐츠를 받은 사용자가 데이터를 입력하거나 조작하고 그 데이터를 요청으로 제출한 다음 다음 입력을 위해 입력 메커니즘을 재설정하는 일반적인 데이터 입력 사용 사례를 지원하기 위한 것입니다.

205 상태 코드는 추가 콘텐츠가 제공되지 않음을 의미하므로 서버는 205 응답에서 콘텐츠를 생성해서는 MUST NOT 합니다.

15.3.7. 206 Partial Content

206 (Partial Content) 상태 코드는 서버가 대상 리소스에 대한 범위 요청을 성공적으로 이행하여 선택된 표현의 하나 이상의 부분을 전송하고 있음을 나타냅니다.

범위 요청을 지원하는 서버(Section 14)는 보통 요청된 모든 범위를 만족시키려 시도합니다. 왜냐하면 더 적은 데이터를 전송하면 클라이언트가 나머지를 위해 추가 요청을 보낼 가능성이 높기 때문입니다. 그러나 서버는 임시적인 불가용, 캐시 효율성, 부하 분산 등 자체 사유로 요청된 데이터의 일부만 전송하려 할 수 있습니다. 206 응답은 자체 설명적이므로 클라이언트는 범위 요청을 부분적으로만 만족시키는 응답도 이해할 수 있습니다.

클라이언트는 206 응답의 Content-TypeContent-Range 필드를 검사하여 어떤 부분이 포함되었는지 및 추가 요청이 필요한지 판단해야 MUST 합니다.

206 응답을 생성하는 서버는 다음 섹션들에서 요구하는 것들 외에 동일한 요청에 대해 200 (OK) 응답에서 전송했을 필드들이 해당되는 경우 다음 헤더 필드를 생성해야 MUST 합니다: Date, Cache-Control, ETag, Expires, Content-Location, 및 Vary.

206 응답에 있는 Content-Length 헤더 필드는 이 메시지의 콘텐츠 바이트 수를 나타내며, 일반적으로 선택된 표현의 전체 길이는 아닙니다. 각 Content-Range 헤더 필드는 선택된 표현의 전체 길이에 대한 정보를 포함합니다.

If-Range 헤더 필드가 있는 요청에 대해 206 응답을 생성하는 발신자는 클라이언트가 이전 응답에 이미 포함된 헤더 필드를 가지고 있으므로 다른 표현 헤더 필드를 생성해서는 SHOULD NOT 합니다. 그렇지 않으면 발신자는 동일한 요청에 대해 200 (OK) 응답에서 전송되었을 모든 표현 헤더 필드를 생성해야 MUST 합니다.

206 응답은 휴리스틱하게 캐시 가능하며, 즉 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

15.3.7.1. 단일 부분

단일 부분이 전송되는 경우, 206 응답을 생성하는 서버는 Content-Range 헤더 필드를 생성하여 선택된 표현의 어떤 범위가 포함되었는지 설명하고, 그 범위의 데이터를 콘텐츠로 포함해야 MUST 합니다. 예:

HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif

... 26012 bytes of partial image data ...
15.3.7.2. 다중 부분

여러 부분이 전송되는 경우, 206 응답을 생성하는 서버는 Section 14.6에 정의된 대로 "multipart/byteranges" 콘텐츠를 생성하고, "multipart/byteranges" 미디어 타입과 필수 경계(boundary) 파라미터를 포함하는 Content-Type 헤더 필드를 생성해야 MUST 합니다. 혼동을 피하기 위해 서버는 다중 부분 응답의 HTTP 헤더 섹션에서 Content-Range 헤더 필드를 생성해서는 MUST NOT 합니다(이 필드는 각 파트 내에서 전송됩니다).

멀티파트 콘텐츠의 각 본문 파트 헤더 영역 내에서 서버는 포함되는 범위에 해당하는 Content-Range 헤더 필드를 생성해야 MUST 합니다. 선택된 표현이 200 응답에서 Content-Type 헤더 필드를 갖고 있었다면, 서버는 각 본문 파트의 헤더 영역에 동일한 Content-Type 헤더 필드를 생성하는 것이 SHOULD 합니다. 예:

HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Length: 1741
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES

--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 500-999/8000

...the first range...
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 7000-7999/8000

...the second range
--THIS_STRING_SEPARATES--

여러 범위가 요청되었을 때 서버는 겹치거나 각 파트를 보내는 비용보다 작은 간격으로 분리된 범위를 병합할 수 MAY 있습니다. "multipart/byteranges"의 각 파트 사이의 전형적인 오버헤드는 선택된 표현의 미디어 타입과 경계 문자열 길이에 따라 약 80바이트 정도이므로, 많은 작은 불연속 파트를 전송하는 것이 전체 선택된 표현을 전송하는 것보다 비효율적일 수 있습니다.

서버는 단일 범위를 요청한 요청에 대해 멀티파트 응답을 생성해서는 MUST NOT 합니다. 클라이언트가 다중 부분 응답을 지원하지 않을 수 있기 때문입니다. 그러나 서버는 여러 범위가 요청되었고 만족 가능한 범위가 하나뿐이거나 병합 후 하나만 남는 경우에만 단일 본문 파트만 있는 "multipart/byteranges" 응답을 생성할 수 MAY 있습니다. "multipart/byteranges" 응답을 처리할 수 없는 클라이언트는 다중 범위를 요청해서는 MUST NOT 합니다.

서버는 멀티파트 응답을 생성할 때 수신된 Range 헤더 필드에서 해당 범위-명세(range-spec)가 나타난 순서와 동일한 순서로 파트들을 전송하는 것이 SHOULD 합니다(단, 만족 불가로 간주되었거나 병합된 범위는 제외). 멀티파트 응답을 수신한 클라이언트는 각 본문 파트에 있는 Content-Range 헤더 필드를 검사하여 해당 파트에 어떤 범위가 포함되었는지 결정해야 MUST 합니다; 클라이언트는 요청한 범위와 동일한 범위나 동일한 순서를 수신할 것을 신뢰할 수 없습니다.

15.3.7.3. 부분 결합

연결이 조기에 종료되었거나 요청이 하나 이상 Range 지정자를 사용했기 때문에 응답이 표현의 하위 범위만 전송할 수 있습니다. 여러 차례 그런 전송이 발생하면 클라이언트는 동일한 표현의 여러 범위를 수신할 수 있습니다. 이러한 범위들은 모두 동일한 강한 밸리데이터를 공유하는 경우에만 안전하게 결합될 수 있습니다(Section 8.8.1).

타깃 리소스에 대해 GET 요청의 여러 부분 응답을 수신한 클라이언트는 동일한 강한 밸리데이터를 공유하는 경우 해당 응답들을 더 큰 연속 범위로 결합할 수 MAY 합니다.

가장 최근 응답이 불완전한 200 (OK) 응답이면, 그 응답의 헤더 필드가 결합된 응답에 사용되며 일치하는 저장된 응답들의 것을 대체합니다.

가장 최근 응답이 206 (Partial Content)이고 일치하는 저장된 응답들 중 적어도 하나가 200 (OK)이라면, 결합된 응답의 헤더 필드는 가장 최근의 200 응답의 헤더 필드를 구성합니다. 일치하는 저장된 응답이 모두 206 응답이면, 가장 최근 헤더 필드를 가진 저장된 응답을 결합 응답의 헤더 필드의 출처로 사용합니다. 단, 클라이언트는 새로운 응답에 제공된 다른 헤더 필드(다만 Content-Range는 제외)를 사용하여 저장된 응답의 해당 헤더 필드들을 대체해야 MUST 합니다.

결합된 응답 콘텐츠는 새로운 응답과 모든 일치하는 저장된 응답 내의 부분 콘텐츠 범위들의 합집합으로 구성됩니다. 만약 합집합이 표현의 전체 범위를 포함하면, 클라이언트는 결합된 응답을 전체 200 (OK) 응답처럼 처리해야 MUST 하며, 전체 길이를 반영하는 Content-Length 헤더 필드를 포함해야 합니다. 그렇지 않으면 클라이언트는 연속 범위 집합을 다음 중 하나로 처리해야 MUST 합니다: 표현의 접두사인 불완전한 200 (OK) 응답, "multipart/byteranges" 콘텐츠를 포함하는 단일 206 (Partial Content) 응답, 또는 각 연속 범위마다 하나의 206 (Partial Content) 응답(각각이 Content-Range 헤더 필드로 표시됨).

15.4. 리다이렉션 3xx

3xx (리다이렉션) 클래스의 상태 코드는 요청을 이행하기 위해 사용자 에이전트가 추가 조치를 취해야 함을 나타냅니다. 리다이렉션에는 여러 유형이 있습니다:

  1. 이 리소스가 다른 URI에서 이용 가능할 수 있음을 나타내는 리다이렉트(예: Location 헤더 필드로 제공): 301 (Moved Permanently), 302 (Found), 307 (Temporary Redirect), 308 (Permanent Redirect).
  2. 이 리소스를 표현할 수 있는 일치 리소스들 중 선택을 제공하는 리다이렉션(예: 300 (Multiple Choices)).
  3. 원래 요청에 대한 간접 응답을 나타낼 수 있는 다른 리소스로의 리다이렉션(예: 303 (See Other)).
  4. 이전에 저장된 결과로의 리다이렉션(예: 304 (Not Modified)).

Location 헤더 필드(Section 10.2.2)가 제공되면, 사용자 에이전트는 그 Location 필드 값이 참조하는 URI로 자동으로 요청을 리다이렉트할 수 MAY 있습니다. 자동 리다이렉션은 안전하지 않은 메서드에 대해서는 주의해서 수행해야 합니다(safe로 정의된 메서드가 아니면 사용자가 비안전 요청을 리다이렉트하기를 원하지 않을 수 있음).

자동으로 리다이렉션을 따를 때 사용자 에이전트는 다음 수정을 적용하여 원래 요청 메시지를 재전송하는 것이 SHOULD 합니다:

  1. 원래 요청의 대상 URI를 리다이렉션 응답의 Location 헤더 값으로 해석하여 대체합니다.

  2. 자동으로 구현에 의해 생성된 헤더 필드들을 제거하고, 새 요청에 적절히 갱신된 값으로 대체합니다. 여기에는 다음이 포함됩니다:

    1. 연결 전용 헤더 필드(Section 7.6.1의 Connection 참조),
    2. 클라이언트의 프록시 구성에 특화된 헤더 필드(예: Proxy-Authorization 등),
    3. 원점-특정 헤더 필드(예: Host 등),
    4. 구현의 캐시가 추가한 검증 헤더 필드(예: If-None-Match, If-Modified-Since),
    5. 리소스-특정 헤더 필드(예: Referer, Origin, Authorization, Cookie 등).
  3. 보안상 문제가 있을 수 있는 자동 생성되지 않은 헤더 필드(요청에 호출 컨텍스트가 추가한 것들)는 제거를 고려합니다; 여기에는 Authorization 및 Cookie가 포함되지만 이에 국한되지는 않습니다.

  4. 해당되는 경우 리다이렉트 상태 코드의 의미에 따라 요청 메서드를 변경합니다.

  5. 요청 메서드가 GET 또는 HEAD로 변경된 경우 Content-Encoding, Content-Language, Content-Location, Content-Type, Content-Length, Digest, Last-Modified 등 콘텐츠-특정 헤더 필드들을 제거합니다.

클라이언트는 순환 리다이렉션(즉, "무한" 리다이렉션 루프)을 감지하고 개입해야 SHOULD 합니다.

15.4.1. 300 Multiple Choices

300 (Multiple Choices) 상태 코드는 대상 리소스가 여러 표현을 가지며 각 표현이 고유한 더 구체적인 식별자를 가지고 있다는 것을 나타냅니다. 서버는 대체 항목들에 대한 정보를 제공하여 사용자(또는 에이전트)가 하나 이상의 식별자로 요청을 리다이렉트하여 선호 표현을 선택하도록 유도합니다. 즉, 서버는 사용자 에이전트가 가장 적합한 표현을 선택하도록 반응적 협상(Section 12)에 참여하기를 원합니다.

서버에 선호 선택이 있으면, 서버는 선호 선택의 URI 참조를 포함하는 Location 헤더 필드를 생성하는 것이 SHOULD 합니다. 사용자 에이전트는 자동 리다이렉션을 위해 Location 필드 값을 사용할 수 MAY 있습니다.

HEAD 이외의 요청 메서드에 대해서는 서버는 300 응답에 표현 메타데이터와 URI 참조 목록이 포함된 콘텐츠를 생성하는 것이 SHOULD 합니다. 사용자 에이전트는 제공된 미디어 타입을 이해하면 그 목록에서 자동으로 선택할 수 MAY 있습니다. 자동 선택을 위한 구체적 형식은 이 명세서에서 정의하지 않습니다. 실제로 표현은 사용자 에이전트에 수용 가능할 것으로 판단되는 쉽게 파싱 가능한 형식이나 일반적으로 수용되는 하이퍼텍스트 형식으로 제공됩니다.

300 응답은 휴리스틱하게 캐시 가능하며, 즉 메서드 정의나 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

15.4.2. 301 Moved Permanently

301 (Moved Permanently) 상태 코드는 대상 리소스에 새 영구 URI가 할당되었음을 나타내며, 이후 해당 리소스에 대한 모든 참조는 서버가 전송한 새 URI들 중 하나를 사용해야 합니다. 서버는 링크 편집 기능을 가진 사용자 에이전트가 대상 URI에 대한 참조를 새 참조로 영구 교체할 것을 제안할 수 있습니다. 그러나 이 제안은 일반적으로 무시됩니다(사용자가 실제로 참조 편집을 하고 있고 연결이 안전하며 출처 서버가 편집 대상 콘텐츠의 신뢰할 수 있는 권한자일 때를 제외).

서버는 응답에 새 영구 URI에 대한 선호 URI 참조를 포함하는 Location 헤더 필드를 생성하는 것이 SHOULD 합니다. 사용자 에이전트는 자동 리다이렉션을 위해 Location 필드 값을 사용할 수 MAY 있습니다. 서버의 응답 콘텐츠는 보통 새 URI에 대한 짧은 하이퍼텍스트 노트를 포함합니다.

301 응답은 휴리스틱하게 캐시 가능하며, 즉 메서드 정의나 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

15.4.3. 302 Found

302 (Found) 상태 코드는 대상 리소스가 임시로 다른 URI에 존재함을 나타냅니다. 리다이렉션이 때때로 변경될 수 있으므로 클라이언트는 향후 요청에 원래 대상 URI를 계속 사용해야 합니다.

서버는 응답에 다른 URI의 URI 참조를 포함하는 Location 헤더 필드를 생성하는 것이 SHOULD 합니다. 사용자 에이전트는 자동 리다이렉션을 위해 Location 필드 값을 사용할 수 MAY 있습니다. 서버의 응답 콘텐츠는 보통 다른 URI에 대한 짧은 하이퍼텍스트 노트를 포함합니다.

15.4.4. 303 See Other

303 (See Other) 상태 코드는 서버가 사용자 에이전트를 Location 헤더 필드에 있는 다른 리소스로 리다이렉트하고 있음을 나타내며, 이는 원래 요청에 대한 간접 응답을 제공하도록 의도됩니다. 사용자 에이전트는 해당 URI를 대상으로 하는 검색 요청(GET 또는 HEAD)을 수행할 수 있으며, 그 요청도 리다이렉트될 수 있고 최종적으로 얻은 결과를 원래 요청에 대한 응답으로 제시할 수 있습니다. Location 헤더의 새 URI는 대상 URI와 동등하다고 간주되지 않습니다.

이 상태 코드는 모든 HTTP 메서드에 적용될 수 있습니다. 주로 POST 동작의 출력이 사용자 에이전트를 다른 리소스로 리다이렉트하도록 허용하기 위해 사용됩니다. 이렇게 하면 POST 응답에 해당하는 정보를 별도로 식별, 북마크, 캐시할 수 있는 리소스로 제공할 수 있습니다.

GET 요청에 대한 303 응답은 출처 서버가 대상 리소스의 표현을 HTTP로 전송할 수 없음을 의미합니다. 그러나 Location 필드 값은 대상 리소스를 설명하는 리소스를 가리키므로 해당 다른 리소스에 대한 검색 요청이 유용한 표현을 반환할 수 있습니다. 어떤 것이 표현 가능하고 어떤 표현이 적절한지, 무엇이 유용한 설명인지는 HTTP 범위를 벗어납니다.

HEAD 요청에 대한 응답을 제외하고, 303 응답의 표현은 Location 헤더에 제공된 동일한 URI 참조에 대한 하이퍼링크을 포함한 짧은 하이퍼텍스트 노트를 포함하는 것이 바람직합니다.

15.4.5. 304 Not Modified

304 (Not Modified) 상태 코드는 조건부 GET 또는 HEAD 요청이 수신되었고, 조건이 거짓으로 평가되어 200 (OK) 응답이 될 수 있었으나 그럴 필요가 없음을 의미합니다. 즉, 서버는 클라이언트가 이미 유효한 표현을 가지고 있기 때문에 대상 리소스의 표현을 전송할 필요가 없습니다. 서버는 클라이언트가 저장한 표현을 200 (OK) 응답의 내용처럼 사용하도록 안내합니다.

304 응답을 생성하는 서버는 동일한 요청에 대해 200 (OK) 응답에서 전송했을 수 있는 다음 헤더 필드들 중 해당되는 것을 생성해야 MUST 합니다:

304 응답의 목표는 수신자가 이미 하나 이상의 캐시된 표현을 가지고 있을 때 정보 전송을 최소화하는 것이므로, 발신자는 위에 나열된 필드 이외의 표현 메타데이터를 생성해서는 SHOULD NOT 합니다(단, 캐시 업데이트를 안내하기 위한 메타데이터(예: ETag가 없는 경우의 Last-Modified)는 예외일 수 있습니다).

304 응답을 수신한 캐시의 처리 요구사항은 Section 4.3.4 of [CACHING]에 정의되어 있습니다. 만약 조건부 요청이 외부 클라이언트(예: 자체 캐시를 가진 사용자 에이전트가 공유 프록시에 조건부 GET을 보냄)에서 시작된 경우, 프록시는 그 304 응답을 해당 클라이언트에 전달해야 SHOULD 합니다.

304 응답은 헤더 섹션의 끝에서 종료되며 콘텐츠나 트레일러를 포함할 수 없습니다.

15.4.6. 305 Use Proxy

305 (Use Proxy) 상태 코드는 이전 버전의 명세에서 정의되었으며 지금은 더 이상 권장되지 않습니다(참조: Appendix B of [RFC7231]).

15.4.7. 306 (Unused)

306 상태 코드는 이전 버전의 명세에서 정의되었으나 더 이상 사용되지 않으며 코드가 예약되어 있습니다.

15.4.8. 307 Temporary Redirect

307 (Temporary Redirect) 상태 코드는 대상 리소스가 임시로 다른 URI에 있으며, 사용자 에이전트가 자동 리다이렉션을 수행하더라도 요청 메서드를 변경해서는 안 됨을 MUST NOT 나타냅니다. 리다이렉션은 시간이 지남에 따라 변경될 수 있으므로 클라이언트는 향후 요청에 대해 원래 대상 URI를 계속 사용해야 합니다.

서버는 응답에 다른 URI의 URI 참조를 포함하는 Location 헤더 필드를 생성하는 것이 SHOULD 합니다. 사용자 에이전트는 자동 리다이렉션을 위해 Location 필드 값을 사용할 수 MAY 있습니다. 서버의 응답 콘텐츠는 보통 다른 URI에 대한 짧은 하이퍼텍스트 노트를 포함합니다.

15.4.9. 308 Permanent Redirect

308 (Permanent Redirect) 상태 코드는 대상 리소스에 새 영구 URI가 할당되었으며 이후 해당 리소스에 대한 모든 참조는 서버가 보낸 새 URI들 중 하나를 사용해야 함을 나타냅니다. 서버는 링크 편집 기능을 가진 사용자 에이전트가 대상 URI에 대한 참조를 새 참조로 영구 교체할 것을 제안할 수 있습니다. 그러나 이 제안은 일반적으로 무시됩니다(사용자가 참조 편집을 실제로 하고 있고 연결이 안전하며 출처 서버가 편집 대상 콘텐츠의 신뢰할 수 있는 권한자일 때를 제외).

서버는 응답에 새 영구 URI에 대한 선호 URI 참조를 포함하는 Location 헤더 필드를 생성하는 것이 SHOULD 합니다. 사용자 에이전트는 자동 리다이렉션을 위해 Location 필드 값을 사용할 수 MAY 있습니다. 서버의 응답 콘텐츠는 보통 새 URI에 대한 짧은 하이퍼텍스트 노트를 포함합니다.

308 응답은 휴리스틱하게 캐시 가능하며, 즉 메서드 정의나 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

15.5. 클라이언트 오류 4xx

4xx (클라이언트 오류) 클래스의 상태 코드는 클라이언트가 오류를 범한 것으로 보임을 나타냅니다. HEAD 요청에 응답하는 경우를 제외하고, 서버는 오류 상황과 그것이 임시인지 영구한지를 설명하는 표현을 포함하여 응답을 보내는 것이 SHOULD 합니다. 이 상태 코드들은 모든 요청 메서드에 적용될 수 있습니다. 사용자 에이전트는 포함된 표현을 사용자에게 표시해야 SHOULD 합니다.

15.5.1. 400 Bad Request

400 (Bad Request) 상태 코드는 요청 구문이 잘못되었거나 요청 메시지 프레이밍이 유효하지 않거나 속이는 요청 라우팅 등 클라이언트 오류로 인식되는 무언가로 인해 서버가 요청을 처리할 수 없음을 나타냅니다.

15.5.2. 401 Unauthorized

401 (Unauthorized) 상태 코드는 대상 리소스에 대한 유효한 인증 자격 증명이 부족하여 요청이 적용되지 않았음을 나타냅니다. 401 응답을 생성하는 서버는 해당 대상 리소스에 적용되는 적어도 하나의 챌린지를 포함하는 WWW-Authenticate 헤더 필드를 전송해야 MUST 합니다(Section 11.6.1 참조).

요청에 인증 자격 증명이 포함되어 있었다면 401 응답은 해당 자격 증명에 대한 권한 부여가 거부되었음을 나타냅니다. 사용자 에이전트는 새롭거나 교체된 Authorization 헤더 필드로 요청을 반복할 수 MAY 있습니다. 만약 401 응답이 이전 응답과 동일한 챌린지를 포함하고 있고 사용자 에이전트가 이미 적어도 한 번 인증을 시도했다면, 사용자 에이전트는 보통 진단 정보를 포함하고 있는 표현을 사용자에게 제시해야 SHOULD 합니다.

15.5.3. 402 Payment Required

402 (Payment Required) 상태 코드는 향후 사용을 위해 예약되어 있습니다.

15.5.4. 403 Forbidden

403 (Forbidden) 상태 코드는 서버가 요청을 이해했지만 이행을 거부함을 나타냅니다. 서버가 요청이 금지된 이유를 공개적으로 알리려면 응답 콘텐츠(있다면)에 그 이유를 기술할 수 있습니다.

요청에 인증 자격 증명이 포함되어 있었다면 서버는 이를 충분하지 않다고 간주합니다. 클라이언트는 동일한 자격 증명으로 요청을 자동으로 반복해서는 SHOULD NOT 하며, 새로운 또는 다른 자격 증명으로 요청을 반복할 수 MAY 있습니다. 그러나 요청이 자격 증명과 무관한 이유로 금지될 수도 있습니다.

출처 서버가 금지된 대상 리소스의 현재 존재를 "숨기고" 싶으면 대신 404 (Not Found) 상태 코드로 응답할 수 MAY 있습니다.

15.5.5. 404 Not Found

404 (Not Found) 상태 코드는 출처 서버가 대상 리소스에 대한 현재 표현을 찾지 못했거나 존재를 공개하기를 원하지 않음을 나타냅니다. 404는 이 표현의 부재가 일시적인지 영구적인지를 나타내지 않습니다; 영구적이라고 서버가 알고 있다면 410 (Gone)을 404 대신 사용하는 것이 선호됩니다.

404 응답은 휴리스틱하게 캐시 가능하며, 즉 메서드 정의나 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

15.5.6. 405 Method Not Allowed

405 (Method Not Allowed) 상태 코드는 요청 라인에 있는 메서드가 출처 서버에서 알려져 있지만 대상 리소스에서 지원되지 않음을 나타냅니다. 출처 서버는 405 응답에서 대상 리소스가 현재 지원하는 메서드 목록을 포함하는 Allow 헤더 필드를 생성해야 MUST 합니다.

405 응답은 휴리스틱하게 캐시 가능하며, 즉 메서드 정의나 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

15.5.7. 406 Not Acceptable

406 (Not Acceptable) 상태 코드는 대상 리소스가 요청에서 수신된 사전적 협상 헤더 필드들에 따라 사용자 에이전트에 허용 가능한 현재 표현을 가지고 있지 않으며, 서버가 기본 표현을 제공할 의사가 없음을 나타냅니다.

서버는 사용자가 가장 적합한 항목을 선택할 수 있도록 사용 가능한 표현 특성 및 해당 리소스 식별자들의 목록을 포함하는 콘텐츠를 생성하는 것이 SHOULD 합니다. 사용자 에이전트는 그 목록에서 자동으로 가장 적절한 선택을 할 수 MAY 있습니다. 다만 이 명세서는 그러한 자동 선택을 위한 표준을 정의하지 않습니다(자세한 내용은 Section 15.4.1 참조).

15.5.8. 407 Proxy Authentication Required

407 (Proxy Authentication Required) 상태 코드는 401 (Unauthorized)와 유사하지만, 클라이언트가 이 요청을 위해 프록시를 사용하려면 자신을 인증해야 함을 나타냅니다. 프록시는 해당 요청에 적용되는 챌린지를 포함하는 Proxy-Authenticate 헤더 필드를 전송해야 MUST 합니다(Section 11.7.1). 클라이언트는 새롭거나 교체된 Proxy-Authorization 헤더 필드로 요청을 반복할 수 MAY 있습니다(Section 11.7.2 참조).

15.5.9. 408 Request Timeout

408 (Request Timeout) 상태 코드는 서버가 기다릴 준비가 된 시간 내에 완전한 요청 메시지를 받지 못했음을 나타냅니다.

클라이언트에 전송 중인 미완료 요청이 있다면 클라이언트는 그 요청을 반복할 수 MAY 있습니다. 현재 연결이 사용 불가능하면(예: HTTP/1.1에서 요청 구분이 손실된 경우) 새 연결을 사용하게 됩니다.

15.5.10. 409 Conflict

409 (Conflict) 상태 코드는 요청이 대상 리소스의 현재 상태와 충돌하여 완료할 수 없음을 나타냅니다. 사용자가 충돌을 해결하고 요청을 재전송할 수 있는 상황에서 주로 사용됩니다. 서버는 충돌 원인을 사용자가 인식할 수 있도록 충분한 정보를 포함한 콘텐츠를 생성하는 것이 SHOULD 합니다.

충돌은 PUT 요청에 응답할 때 가장 자주 발생합니다. 예를 들어 버전 관리가 사용 중이고 PUT하는 표현이 이전(제3자)의 변경과 충돌하는 경우 출처 서버는 요청을 완료할 수 없음을 나타내기 위해 409 응답을 사용할 수 있습니다. 이 경우 응답 표현에는 수정 이력을 기반으로 차이를 병합하는 데 유용한 정보가 포함될 것입니다.

15.5.11. 410 Gone

410 (Gone) 상태 코드는 출처 서버에서 대상 리소스에 대한 접근이 더 이상 가능하지 않으며 이 상태가 영구적일 가능성이 높음을 나타냅니다. 출처 서버가 이 상태가 영구적인지 알 수 없거나 판별 수단이 없다면 대신 404 (Not Found)를 사용해야 합니다.

410 응답은 원격 링크를 제거하도록 알리는 등 웹 유지보수를 돕기 위해 주로 사용됩니다. 이는 기간 한정 프로모션 서비스나 출처 서버 사이트와 더 이상 관련이 없는 개인의 리소스 등에 흔히 발생합니다. 모든 영구적으로 사용 불가능한 리소스를 반드시 "gone"으로 표시하거나 일정 기간 보관할 필요는 없습니다 — 이는 서버 소유자의 재량입니다.

410 응답은 휴리스틱하게 캐시 가능하며, 즉 메서드 정의나 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

15.5.12. 411 Length Required

411 (Length Required) 상태 코드는 서버가 Content-Length를 정의하지 않은 요청을 수락하지 않음을 나타냅니다(Section 8.6). 클라이언트는 요청 본문의 길이를 포함하는 유효한 Content-Length 헤더 필드를 추가하여 요청을 반복할 수 MAY 합니다.

15.5.13. 412 Precondition Failed

412 (Precondition Failed) 상태 코드는 요청 헤더 필드에 주어진 하나 이상의 조건이 서버에서 검사되었을 때 거짓으로 평가되었음을 나타냅니다(Section 13). 이 응답 상태 코드는 클라이언트가 현재 리소스 상태(현재 표현 및 메타데이터)에 선행 조건을 부과하여 대상 리소스가 예상 상태에 있지 않으면 요청 메서드가 적용되는 것을 방지할 수 있게 합니다.

15.5.14. 413 Content Too Large

413 (Content Too Large) 상태 코드는 요청 콘텐츠가 서버가 처리하려는 한계보다 커서 서버가 요청을 처리하지 않겠음을 나타냅니다. 서버는 프로토콜 버전이 허용하면 요청을 종료할 수 MAY 있으며, 그렇지 않으면 연결을 닫을 수 MAY 있습니다.

조건이 일시적이라면 서버는 클라이언트가 다시 시도할 수 있는 시점을 나타내는 Retry-After 헤더 필드를 생성하는 것이 SHOULD 합니다.

15.5.15. 414 URI Too Long

414 (URI Too Long) 상태 코드는 대상 URI가 서버가 해석하려는 허용 길이보다 길어 요청을 서비스할 수 없음을 나타냅니다. 이 드문 조건은 클라이언트가 POST 요청을 GET으로 잘못 변환하여 긴 쿼리 정보를 포함시켰거나, 클라이언트가 리다이렉션 무한 루프에 빠졌거나, 공격자가 보안 취약점을 악용하려는 경우에 발생할 수 있습니다.

414 응답은 휴리스틱하게 캐시 가능하며, 즉 메서드 정의나 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

15.5.16. 415 Unsupported Media Type

415 (Unsupported Media Type) 상태 코드는 출처 서버가 이 메서드에 대해 대상 리소스에서 요청의 콘텐츠 형식을 지원하지 않기 때문에 요청을 처리하지 않음을 나타냅니다.

형식 문제는 요청의 지정된 Content-Type 또는 Content-Encoding 때문일 수 있으며, 데이터 자체를 검사한 결과일 수도 있습니다.

문제가 지원되지 않는 콘텐츠 코딩 때문이라면, 응답의 Accept-Encoding 헤더 필드(Section 12.5.3)를 사용하여 요청에서 수용되었을 가능성이 있는 콘텐츠 코딩을 나타내는 것이 바람직합니다.

반면 문제가 지원되지 않는 미디어 타입 때문이라면, 응답의 Accept 헤더 필드(Section 12.5.1)를 사용하여 요청에서 수용되었을 미디어 타입을 나타낼 수 있습니다.

15.5.17. 416 Range Not Satisfiable

416 (Range Not Satisfiable) 상태 코드는 요청의 Range 헤더에 포함된 범위 집합이 거부되었음을 나타냅니다. 이는 요청된 범위 중 어느 것도 만족 불가능하거나, 클라이언트가 과도한 수의 작은 또는 겹치는 범위를 요청했을 때(잠재적 서비스 거부 공격) 발생할 수 있습니다.

각 범위 단위는 자체 범위 집합이 만족 가능한지에 필요한 요건을 정의합니다. 예를 들어 Section 14.1.2는 bytes 범위 집합이 만족 가능한 조건을 정의합니다.

바이트 범위 요청에 대해 416 응답을 생성하는 서버는 선택된 표현의 현재 길이를 지정하는 Content-Range 헤더 필드를 생성하는 것이 SHOULD 합니다(Section 14.4 참조).

예:

HTTP/1.1 416 Range Not Satisfiable
Date: Fri, 20 Jan 2012 15:41:54 GMT
Content-Range: bytes */47022

15.5.18. 417 Expectation Failed

417 (Expectation Failed) 상태 코드는 요청의 Expect 헤더 필드(Section 10.1.1)에 주어진 기대 중 적어도 하나가 들어오는 서버들 중 하나 이상에서 충족될 수 없음을 나타냅니다.

15.5.19. 418 (Unused)

[RFC2324]는 HTTP의 남용을 풍자한 4월 1일자 RFC였으며; 그 중 하나의 남용은 애플리케이션 특정 418 상태 코드의 정의였고, 이는 농담으로 배포되어 충분히 널리 퍼져 향후 사용을 위한 코드로 사용할 수 없게 되었습니다.

따라서 418 상태 코드는 IANA HTTP 상태 코드 레지스트리에 예약되어 있습니다. 이는 현재 그 상태 코드가 다른 애플리케이션에 할당될 수 없음을 의미합니다. 향후 상황이 요구되면(예: 4NN 상태 코드 고갈) 재할당될 수 있습니다.

15.5.20. 421 Misdirected Request

421 (Misdirected Request) 상태 코드는 요청이 대상 URI에 대한 권한 있는 응답을 생성할 수 없거나 생성하기를 원치 않는 서버로 향해졌음을 나타냅니다. 출처 서버(또는 출처 서버를 대신하는 게이트웨이)는 서버가 구성된 origin과 일치하지 않거나 요청을 수신한 연결 컨텍스트와 일치하지 않는 대상 URI를 거부하기 위해 421을 보냅니다(Section 4.3.1, Section 7.4 참조).

421 응답을 수신한 클라이언트는 요청 메서드가 멱등인지 여부에 관계없이 다른 연결(예: 대상 리소스의 origin에 특정한 새 연결)이나 대체 서비스([ALTSVC])를 통해 요청을 재시도할 수 MAY 있습니다.

프록시는 421 응답을 생성해서는 MUST NOT 합니다.

15.5.21. 422 Unprocessable Content

422 (Unprocessable Content) 상태 코드는 서버가 요청 콘텐츠의 미디어 타입을 이해하고(따라서 415 (Unsupported Media Type)는 부적절함), 요청 콘텐츠의 문법이 올바르지만 포함된 지시사항을 처리할 수 없었음을 나타냅니다. 예를 들어 XML 요청 콘텐츠가 잘 구성되어(문법적으로 올바르지만) 의미상 오류가 있는 XML 지시사항을 포함하는 경우 이 상태 코드를 보낼 수 있습니다.

15.5.22. 426 Upgrade Required

426 (Upgrade Required) 상태 코드는 서버가 현재 프로토콜을 사용하여 요청을 수행하기를 거부하지만, 클라이언트가 다른 프로토콜로 업그레이드하면 수행할 의향이 있음을 나타냅니다. 426 응답을 생성하는 서버는 요구되는 프로토콜을 나타내는 Upgrade 헤더 필드를 전송해야 MUST 합니다(Section 7.8 참조).

예:

HTTP/1.1 426 Upgrade Required
Upgrade: HTTP/3.0
Connection: Upgrade
Content-Length: 53
Content-Type: text/plain

This service requires use of the HTTP/3.0 protocol.

15.6. 서버 오류 5xx

5xx (서버 오류) 클래스의 상태 코드는 서버가 오류를 인지했거나 요청된 메서드를 수행할 수 없음을 나타냅니다. HEAD 요청에 응답할 때를 제외하고, 서버는 오류 상황과 그것이 임시인지 영구한지를 설명하는 표현을 포함하는 것이 SHOULD 합니다. 사용자 에이전트는 포함된 표현을 사용자에게 표시해야 SHOULD 합니다. 이 상태 코드들은 모든 요청 메서드에 적용됩니다.

15.6.1. 500 Internal Server Error

500 (Internal Server Error) 상태 코드는 서버가 요청을 이행하는 동안 예기치 않은 조건이 발생했음을 나타냅니다.

15.6.2. 501 Not Implemented

501 (Not Implemented) 상태 코드는 서버가 요청을 이행하는 데 필요한 기능을 지원하지 않음을 나타냅니다. 서버가 요청 메서드를 인식하지 못하고 어떤 리소스에 대해서도 지원할 수 없을 때 적절한 응답입니다.

501 응답은 휴리스틱하게 캐시 가능하며, 즉 메서드 정의나 명시적 캐시 제어에 달리 표시되지 않는 한 캐시될 수 있습니다(자세한 내용은 Section 4.2.2 of [CACHING] 참조).

15.6.3. 502 Bad Gateway

502 (Bad Gateway) 상태 코드는 서버가 게이트웨이 또는 프록시로 동작하는 동안 요청을 이행하려고 액세스한 인바운드 서버로부터 무효한 응답을 수신했음을 나타냅니다.

15.6.4. 503 Service Unavailable

503 (Service Unavailable) 상태 코드는 서버가 일시적 과부하 또는 예정된 정비로 인해 현재 요청을 처리할 수 없음을 나타냅니다. 이 상태는 일정 시간 후에 완화될 가능성이 높습니다. 서버는 클라이언트가 재시도할 적절한 시간을 제안하기 위해 Retry-After 헤더 필드를 전송할 수 MAY 있습니다(Section 10.2.3 참조).

15.6.5. 504 Gateway Timeout

504 (Gateway Timeout) 상태 코드는 서버가 게이트웨이 또는 프록시로 동작하는 동안 요청을 완료하기 위해 필요한 상위 서버로부터 적시 응답을 받지 못했음을 나타냅니다.

15.6.6. 505 HTTP Version Not Supported

505 (HTTP Version Not Supported) 상태 코드는 서버가 요청 메시지에서 사용된 HTTP의 주(major) 버전을 지원하지 않거나 지원을 거부함을 나타냅니다. 서버는 클라이언트와 동일한 주(major) 버전으로 요청을 완료할 수 없음을 나타내며, 해당 버전을 지원하지 않는 이유 및 서버가 지원하는 다른 프로토콜을 설명하는 표현을 생성하는 것이 SHOULD 합니다.

16. HTTP 확장

HTTP는 메서드, 상태 코드, 필드 이름 및 인증 스킴이나 캐시 지시자처럼 정의된 필드 내의 추가 확장 지점 등 프로토콜의 새 버전을 도입하지 않고도 기능을 도입할 수 있는 여러 일반적인 확장 포인트를 정의합니다(예: Section 5.2.3의 Cache-Control 확장, [CACHING]). HTTP의 의미론은 버전으로 관리되지 않으므로 이러한 확장 지점은 영구적이며, 사용 중인 프로토콜 버전이 그 의미론에 영향을 주지 않습니다.

버전 독립적인 확장은 사용 중인 특정 프로토콜 버전에 의존하거나 상호작용하는 것을 지양해야 합니다. 불가피한 경우에는 확장이 버전 간 상호운용되도록 하는 방법을 신중히 검토해야 합니다.

추가로, 특정 HTTP 버전은 자체 확장 지점을 가질 수 있습니다. 예를 들어 HTTP/1.1의 전송 코딩(Section 6.1, [HTTP/1.1])이나 HTTP/2의 SETTINGS 또는 프레임 타입([HTTP/2]) 등이 그러합니다. 이러한 확장 지점은 해당 프로토콜 버전 고유의 것입니다.

버전 특정 확장은 해당 프로토콜 요소에 의해 명시적으로 허용되지 않는 한, 버전 독립적인 메커니즘이나 확장 지점(예: 메서드나 헤더 필드)의 의미론을 재정의하거나 수정할 수 없습니다. 예로 CONNECT 메서드(Section 9.3.6)가 이러한 동작을 허용합니다.

이러한 지침은 경로의 일부가 서로 다른 HTTP 버전을 구현하더라도 프로토콜이 올바르고 예측 가능하게 동작하도록 보장합니다.

16.1. 메서드 확장성

16.1.1. 메서드 레지스트리

"Hypertext Transfer Protocol (HTTP) Method Registry"는 IANA가 https://www.iana.org/assignments/http-methods에서 관리하며, 메서드 이름들을 등록합니다.

HTTP 메서드 등록에는 다음 필드들이 포함되어야 MUST 합니다:

  • 메서드 이름(참조: Section 9)
  • 안전 여부("yes" 또는 "no", 참조: Section 9.2.1)
  • 멱등성 여부("yes" 또는 "no", 참조: Section 9.2.2)
  • 명세 텍스트에 대한 포인터

이 네임스페이스에 값을 추가하려면 IETF 검토가 필요합니다(참조: [RFC8126], Section 4.8).

16.1.2. 새 메서드에 대한 고려사항

표준화된 메서드는 일반적입니다; 즉 특정 미디어 타입이나 특정 종류의 리소스, 애플리케이션에만 적용되는 것이 아니라 잠재적으로 모든 리소스에 적용될 수 있습니다. 따라서 새로운 메서드는 특정 애플리케이션이나 데이터 형식에 국한되지 않는 문서에 등록하는 것이 바람직합니다. 직교적인 기술은 직교적인 명세를 가질 자격이 있습니다.

메시지 구문 분석(Section 6)은 메서드 의미론과 독립적이어야 하므로(HEAD에 대한 응답을 제외), 새로운 메서드의 정의는 구문 분석 알고리즘을 변경하거나 요청 또는 응답 메시지에 콘텐츠의 존재를 금지할 수 없습니다. 새로운 메서드 정의는 Content-Length 헤더 필드 값을 "0"으로 요구하여 오직 0길이 콘텐츠만 허용한다고 명시할 수 있습니다.

마찬가지로, 새로운 메서드는 CONNECT(CONNECT)와 OPTIONS(OPTIONS)에 허용되는 호스트:포트 및 별표 형태의 요청 대상과 같은 특수한 요청 대상 형식을 사용할 수 없습니다(Section 7.1). 대상 URI에 대해 전체 URI(절대 형식)가 필요하므로 요청 대상은 절대형으로 전송되거나 다른 메서드와 동일한 방식으로 요청 컨텍스트에서 대상 URI가 재구성되어야 합니다.

새 메서드 정의는 그것이 안전한지(Section 9.2.1), 멱등인지(Section 9.2.2), 캐시 가능인지(Section 9.2.3), 요청 콘텐츠(있다면)에 어떤 의미론이 연관되는지, 그리고 헤더 필드나 상태 코드 의미론에 어떤 정제가 필요한지를 명시해야 합니다. 새로운 메서드가 캐시 가능하다면, 캐시가 언제 어떻게 응답을 저장하고 이후 요청을 만족시키는 데 사용할 수 있는지 설명해야 합니다. 또한 새로운 메서드가 조건부로 만들 수 있는지(Section 13.1) 여부와, 그렇다면 조건이 거짓일 때 서버가 어떻게 응답하는지 설명해야 합니다. 마찬가지로, 새로운 메서드가 부분 응답 의미론(Section 14.2)에 어떤 용도가 있을 수 있다면, 그것도 문서화해야 합니다.

16.2. 상태 코드 확장성

16.2.1. 상태 코드 레지스트리

"Hypertext Transfer Protocol (HTTP) Status Code Registry"는 IANA가 https://www.iana.org/assignments/http-status-codes에서 관리하며, 상태 코드 번호를 등록합니다.

등록에는 다음 필드들이 반드시 포함되어야 MUST 합니다:

  • 상태 코드(3자리)
  • 짧은 설명
  • 명세 텍스트에 대한 포인터

이 HTTP 상태 코드 네임스페이스에 값을 추가하려면 IETF 검토가 필요합니다(참조: [RFC8126], Section 4.8).

16.2.2. 새 상태 코드에 대한 고려사항

현재 상태 코드로 정의되지 않은 응답 의미론을 표현해야 할 필요가 있을 때 새 상태 코드를 등록할 수 있습니다. 상태 코드는 일반적이며, 특정 미디어 타입이나 리소스 종류, HTTP의 특정 응용에만 적용되는 것이 아닙니다. 따라서 새 상태 코드는 특정 응용에 한정되지 않는 문서에 등록하는 것이 바람직합니다.

새 상태 코드는 Section 15에 정의된 분류 중 하나에 속해야 합니다. 기존 파서가 응답 메시지를 처리할 수 있도록 새 상태 코드는 콘텐츠를 금지할 수 없지만 0-길이 콘텐츠를 요구할 수는 있습니다.

아직 널리 배포되지 않은 새 상태 코드 제안은 코드 번호를 조기에 할당하지 않도록 권고됩니다. 명확한 합의가 있을 때까지 특정 번호 대신 "4NN" 또는 "3N0" .. "3N9" 같은 표기를 사용하여 제안된 상태 코드의 클래스만 표시하는 것이 바람직합니다.

새 상태 코드의 정의에는 해당 상태 코드를 포함하는 응답을 유발할 요청 조건(예: 요청 헤더 필드 및/또는 메서드 조합)과 응답 헤더 필드에 대한 종속성(필드가 필수인지, 어떤 필드가 의미를 변경하는지, 새 상태 코드와 함께 사용될 때 어떤 필드 의미가 정제되는지)을 설명해야 합니다.

기본적으로 상태 코드는 그것이 발생한 응답에 해당하는 요청에만 적용됩니다. 상태 코드가 더 넓은 적용 범위(예: 해당 리소스에 대한 모든 요청 또는 서버에 대한 모든 요청)에 적용된다면 이는 명시적으로 지정되어야 합니다. 이렇게 할 때 모든 클라이언트가 새 상태 코드를 이해하지 못할 수 있으므로 일관되게 더 넓은 범위를 적용할 것을 기대할 수 없다는 점을 명시해야 합니다.

새 최종 상태 코드의 정의는 그것이 휴리스틱하게 캐시할 수 있는지 여부를 지정해야 합니다. 모든 최종 상태 코드 응답은 명시적 신선도 정보가 있으면 캐시될 수 있다는 점에 유의하십시오. 상태 코드가 휴리스틱 캐시 가능하도록 정의되면 명시적 신선도 정보 없이도 캐시될 수 있습니다. 마찬가지로 상태 코드의 정의는 must-understand 캐시 지시자가 사용될 경우 캐시 동작에 제약을 둘 수 있습니다. 자세한 내용은 [CACHING]를 참조하십시오.

마지막으로, 새 상태 코드 정의는 그 콘텐츠가 식별된 리소스와 어떤 암묵적 연관을 가지는지(Section 6.4.2)를 표시해야 합니다.

16.3. 필드 확장성

HTTP에서 가장 널리 사용되는 확장 포인트는 새 헤더 및 트레일러 필드를 정의하는 것입니다.

새 필드는 수신자가 이해할 경우 기존에 정의된 필드의 해석을 재정의하거나 강화하고, 요청 평가에 대한 선행 조건을 정의하거나, 응답의 의미를 정제하도록 정의될 수 있습니다.

하지만 필드를 정의한다고 해서 그것이 배포되거나 수신자에게 인식된다는 보장은 없습니다. 대부분의 필드는 수신자가 인식하지 못하는 필드를 안전하게 무시(그러나 하류로 전달)할 수 있을 것으로 설계됩니다. 다른 경우 발신자가 특정 필드를 이해함을 이전 통신(예: 프로토콜 버전 또는 이전 메시지에서 보낸 필드들)으로 표시하거나 특정 미디어 타입의 사용으로 신호할 수 있습니다. 또한 OPTIONS 요청이나 잘 알려진 URI([RFC8615])와의 상호작용을 통해 직접 지원 여부를 검사할 수 있다면, 그 검사 방법을 필드와 함께 정의할 수 있습니다.

16.3.1. 필드 이름 레지스트리

"Hypertext Transfer Protocol (HTTP) Field Name Registry"는 HTTP 필드 이름의 네임스페이스를 정의합니다.

누구나 HTTP 필드 등록을 요청할 수 있습니다. 새 HTTP 필드를 만들 때 고려할 사항은 Section 16.3.2을 참조하십시오.

"Hypertext Transfer Protocol (HTTP) Field Name Registry"는 https://www.iana.org/assignments/http-fields/에 있습니다. 등록 요청은 그곳의 지침을 따르거나 "ietf-http-wg@w3.org" 메일링 리스트로 이메일을 보내 요청할 수 있습니다.

필드 이름은 지정된 전문가(IESG 또는 위임자가 임명)가 조언을 바탕으로 등록합니다. 상태가 'permanent'인 필드는 Specification Required입니다(참조: [RFC8126], Section 4.6).

등록 요청은 다음 정보를 포함합니다:

Field name:
요청된 필드 이름. Section 5.1에 정의된 field-name 문법을 준수해야 MUST 하며, 문자, 숫자 및 하이픈('-') 문자만으로 제한하는 것이 바람직하며 첫 문자는 문자여야 SHOULD 합니다.
Status:
"permanent", "provisional", "deprecated", 또는 "obsoleted".
Specification document(s):
필드를 규정하는 문서에 대한 참조, 바람직하게는 문서를 검색할 수 있는 URI를 포함. 임시 등록의 경우 선택적이지만 권장됩니다. 관련 섹션을 표시할 수 있으나 필수는 아닙니다.

선택적으로:

Comments:
예약된 항목 등에 대한 추가 정보.

전문가(들)는 커뮤니티와 협의하여 레지스트리에 수집할 추가 필드를 정의할 수 있습니다.

표준으로 정의된 이름은 상태가 "permanent"입니다. 전문가(들)가 사용 중이며 적절히 커뮤니티와 협의한 경우 다른 이름도 permanent로 등록할 수 있습니다. 그렇지 않은 이름은 "provisional"로 등록되어야 합니다.

전문가(들)는 커뮤니티와 협의하여 임시 항목이 사용되지 않는다고 판단하면 이를 제거할 수 있습니다. 전문가(들)는 언제든 임시 항목의 상태를 permanent로 변경할 수 있습니다.

전문가(들)는 등록되지 않은 이름이 널리 배포되어 있고 그렇지 않으면 시기적절하게 등록되지 않을 가능성이 높다고 판단하면 제3자(전문가 포함)가 이름을 등록할 수 있도록 허용할 수 있습니다.

16.3.2. 새 필드에 대한 고려사항

HTTP 헤더 및 트레일러 필드는 프로토콜의 널리 사용되는 확장 포인트입니다. 임의로 사용될 수는 있으나, 광범위한 사용을 의도한 필드는 상호운용성을 보장하기 위해 신중하게 문서화되어야 합니다.

특히, 새 필드를 정의하는 명세 작성자는 다음 측면을 고려하고 적절한 경우 문서화하는 것이 권장됩니다:

  • 어떤 조건에서 필드를 사용할 수 있는지; 예: 응답에서만, 요청 또는 응답 모두에서, 특정 요청 메서드에 대한 응답에서만 등.
  • 필드 의미가 특정 요청 메서드나 상태 코드와 같이 문맥에 의해 추가로 정제되는지 여부.
  • 전달되는 정보의 적용 범위. 기본적으로 필드는 연관된 메시지에만 적용되지만, 일부 응답 필드는 리소스의 모든 표현이나 리소스 자체, 또는 더 넓은 범위에 적용되도록 설계될 수 있습니다. 응답 필드의 범위를 확장하는 명세는 콘텐츠 협상, 적용 기간, 다중 테넌트 서버 배포와 같은 문제를 신중히 고려해야 합니다.
  • 중개자가 필드 값을 삽입, 삭제 또는 수정할 수 있는 조건.
  • 필드가 트레일러에서 허용되는지 여부; 기본적으로 그렇지 않습니다(참조: Section 6.5.1).
  • 필드가 홉-바이-홉인지(즉 Connection 헤더에 필드 이름을 나열해야 하는지) 여부(참조: Connection, Section 7.6.1).
  • 프라이버시 관련 데이터 노출과 같은 추가 보안 고려사항이 있는지 여부.

요청 헤더 필드는 기본 동작이 적절하지 않은 경우 추가로 문서화해야 할 고려사항이 있습니다:

  • 해당 필드 이름을 응답의 Vary 헤더 필드에 나열하는 것이 적절한지(예: 요청 헤더 필드가 출처 서버의 콘텐츠 선택 알고리즘에 사용되는 경우; 참조: Section 12.5.5).
  • 필드가 PUT 요청에서 수신될 때 저장될 의도인지 여부(참조: Section 9.3.4).
  • 보안상의 우려로 인해 자동 리다이렉션 시 필드를 제거해야 하는지 여부(참조: Section 15.4).
16.3.2.1. 새 필드 이름에 대한 고려사항

새 필드를 정의하는 작성자는 짧지만 설명적인 필드 이름을 선택하는 것이 권장됩니다. 짧은 이름은 불필요한 데이터 전송을 줄이고, 설명적인 이름은 혼동과 더 넓은 용도로 이름을 선점하는 것을 방지합니다.

특정 용도로 제한된 필드(예: 단일 애플리케이션이나 사용 사례에 국한된 헤더)는 그 사용을 접두사로 포함하는 이름을 사용하는 것이 권장됩니다. 예: Foo Application이 Description 필드를 필요로 하면 "Foo-Desc"를 사용할 수 있습니다; "Description"은 너무 일반적이며 "Foo-Description"은 불필요하게 길다고 볼 수 있습니다.

필드 이름 문법은 어떤 토큰 문자도 허용하도록 정의되어 있지만, 실제로 일부 구현체는 허용하는 문자에 제한을 둡니다. 상호운용성을 위해 새 필드 이름은 영숫자, "-", "."에 제한하고 SHOULD 문자로 시작하는 것이 권장됩니다. 예를 들어 밑줄("_") 문자는 비-HTTP 게이트웨이 인터페이스를 통과할 때 문제가 될 수 있습니다(참조: Section 17.10).

필드 이름은 "X-" 접두사로 시작해서는 안 됩니다; 자세한 내용은 [BCP178]를 참조하십시오.

다른 접두사들은 HTTP 필드 이름에서 때때로 사용됩니다. 예: "Accept-"는 많은 콘텐츠 협상 헤더에서 사용되고, "Content-"는 Section 6.4에 설명된 대로 사용됩니다. 이러한 접두사는 필드 목적을 인식하는 데 도움이 될 뿐 자동 처리를 유발하지는 않습니다.

16.3.2.2. 새 필드 값에 대한 고려사항

새 HTTP 필드 정의의 주요 작업은 필드 값 문법의 명세입니다: 발신자가 무엇을 생성해야 하고, 수신자는 수신된 것에서 어떻게 의미를 추론해야 하는지 정의해야 합니다.

작성자는 새 필드 값 문법을 정의할 때 이 명세서의 ABNF 규칙이나 [RFC8941]의 규칙 중 하나를 사용하는 것이 권장됩니다(필수는 아님).

작성자는 여러 필드 라인의 조합이 필드에 어떤 영향을 미칠지 신중히 고려해야 합니다(참조: Section 5.3). 발신자가 잘못하여 여러 값을 보낼 수 있고, 중개자와 HTTP 라이브러리가 자동으로 결합을 수행할 수 있으므로 이는 단일 값만 예상되는 경우에도 적용됩니다.

따라서 작성자는 쉼표를 포함하는 값(예: quoted-string 규칙이나 [RFC8941]의 String 타입 또는 필드 특정 인코딩 등)을 구분하거나 인코딩하도록 권고합니다. 이는 필드 데이터 내의 쉼표가 리스트 값을 구분하는 쉼표와 혼동되지 않도록 보장합니다.

예를 들어 Content-Type 필드 값은 쉼표를 인용된 문자열 안에서만 허용하므로, 여러 값이 있을 때도 신뢰성 있게 파싱할 수 있습니다. 반면 Location 필드 값은 URI가 쉼표를 포함할 수 있기 때문에 단일 값 내부의 쉼표와 두 값의 구분을 신뢰성 있게 구별할 수 없어 모범 사례로 삼아서는 안 됩니다.

단일 값 필드(참조: Section 5.5)의 작성자는 다중 멤버가 존재하는 메시지를 처리하는 방법을 문서화할 것을 권고합니다(합리적 기본값은 필드를 무시하는 것이지만, 항상 옳은 선택은 아닐 수 있습니다).

16.4. 인증 스킴 확장성

16.4.1. 인증 스킴 레지스트리

"Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry"는 챌린지와 자격 증명에서 사용되는 인증 스킴 네임스페이스를 정의하며 https://www.iana.org/assignments/http-authschemes에서 관리됩니다.

등록에는 다음 필드들이 반드시 포함되어야 MUST 합니다:

  • 인증 스킴 이름
  • 명세 텍스트에 대한 포인터
  • 메모(선택)

이 네임스페이스에 값을 추가하려면 IETF 검토가 필요합니다(참조: [RFC8126], Section 4.8).

16.4.2. 새 인증 스킴에 대한 고려사항

HTTP 인증 프레임워크에는 새 인증 스킴의 동작을 제약하는 몇 가지 측면이 있습니다:

  • HTTP 인증은 상태 비저장(stateless)으로 가정됩니다: 요청을 인증하는 데 필요한 모든 정보는 요청 내에 제공되어야 MUST 하며, 서버가 이전 요청을 기억하는 것에 의존해서는 안 됩니다. 기저 연결에 바인딩되거나 그에 기반한 인증은 이 명세서의 범위를 벗어나며, 그 연결이 인증된 사용자 외의 어떤 당사자도 사용할 수 없도록 보장하는 조치가 취해지지 않는 한 본질적으로 결함이 있습니다(참조: Section 3.3).

  • 인증 매개변수 "realm"은 보호 영역을 정의하는 데 예약되어 있으므로(Section 11.5) 새 스킴은 그 정의와 호환되지 않게 "realm"을 사용해서는 MUST NOT 합니다.

  • "token68" 표기법은 기존 인증 스킴과의 호환을 위해 도입되었고 챌린지나 자격 증명에서 한 번만 사용할 수 있습니다. 따라서 새 스킴은 향후 확장이 불가능해지지 않도록 auth-param 구문을 사용하는 것이 바람직합니다.

  • 챌린지와 자격 증명의 구문 분석은 이 명세서에 의해 정의되며 새 인증 스킴이 이를 수정할 수 없습니다. auth-param 구문을 사용할 때 모든 매개변수는 token 및 quoted-string 문법을 모두 지원해야 하며(즉, quoted-string 처리가 필요), 구문 분석 후 필드 값에 대한 문법적 제약이 정의되어야 합니다. 이는 수신자가 모든 인증 스킴에 적용되는 일반 파서를 사용할 수 있도록 하기 위해 필요합니다.

    참고: "realm" 매개변수의 값 문법이 quoted-string으로 제한된 것은 반복하지 말아야 할 잘못된 설계 선택이었습니다.

  • 새 스킴 정의는 알려지지 않은 확장 매개변수 처리 방법을 정의해야 합니다. 일반적으로 "must-ignore" 규칙이 "must-understand" 규칙보다 바람직합니다. 그렇지 않으면 레거시 수신자가 존재하는 환경에서 새 매개변수를 도입하기 어렵습니다. 또한 새 매개변수를 정의하는 정책(예: "명세를 갱신" 또는 "이 레지스트리 사용")을 설명하는 것이 좋습니다.

  • 인증 스킴 정의는 해당 스킴이 원본 서버 인증(즉 WWW-Authenticate 사용)과/또는 프록시 인증(즉 Proxy-Authenticate 사용)에 사용할 수 있는지 여부를 문서화해야 합니다.

  • Authorization 헤더에 담긴 자격 증명은 사용자 에이전트에 특화되어 있으므로, 그것들이 나타나는 요청 범위 내에서 HTTP 캐시에 대해 "private" 캐시 응답 지시자와 동일한 효과를 가집니다(참조: Section 5.2.2.7 of [CACHING]).

    따라서 Authorization 헤더에 자격 증명을 담지 않는 새 인증 스킴(예: 새로 정의된 헤더 사용)은 캐싱을 명시적으로 금지해야 하며(예: "private" 사용을 의무화), 이를 명세에 명시해야 합니다.

  • Authentication-Info, Proxy-Authentication-Info 또는 기타 인증 관련 응답 헤더 필드를 사용하는 스킴은 관련 보안 고려사항을 문서화해야 합니다(참조: Section 17.16.4).

16.5. 범위 단위 확장성

16.5.1. 범위 단위 레지스트리

"HTTP Range Unit Registry"는 범위 단위 이름의 네임스페이스를 정의하고 해당 사양을 참조합니다. 이는 https://www.iana.org/assignments/http-parameters에서 관리됩니다.

HTTP Range Unit 등록에는 다음 필드들이 반드시 포함되어야 MUST 합니다:

  • 이름
  • 설명
  • 명세 텍스트에 대한 포인터

이 네임스페이스에 값을 추가하려면 IETF 검토가 필요합니다(참조: [RFC8126], Section 4.8).

16.5.2. 새 범위 단위에 대한 고려사항

페이지, 섹션, 레코드, 행 또는 시간 같은 형식 특정 경계와 같은 다른 범위 단위는 애플리케이션 특정 목적을 위해 HTTP에서 사용할 수 있으나 실제로 널리 사용되지는 않습니다. 대체 범위 단위를 구현하는 사람들은 그것들이 콘텐츠 코딩 및 범용 중개자와 어떻게 동작할지 고려해야 합니다.

16.6. 콘텐츠 코딩 확장성

16.6.1. 콘텐츠 코딩 레지스트리

"HTTP Content Coding Registry"는 IANA가 https://www.iana.org/assignments/http-parameters/에서 관리하며 content-coding 이름을 등록합니다.

콘텐츠 코딩 등록에는 다음 필드들이 반드시 포함되어야 MUST 합니다:

  • 이름
  • 설명
  • 명세 텍스트에 대한 포인터

콘텐츠 코딩의 이름은 전송 코딩 이름과 중복되어서는 MUST NOT 하며(동일한 인코딩 변환일 경우를 제외, 예: 섹션 8.4.1의 압축 코딩들), "HTTP Transfer Coding Registry"(https://www.iana.org/assignments/http-parameters/)와 겹치지 않아야 합니다.

이 네임스페이스에 값을 추가하려면 IETF 검토가 필요하며(참조: [RFC8126], Section 4.8) 콘텐츠 코딩의 목적(참조: Section 8.4.1)을 준수해야 MUST 합니다.

16.6.2. 새 콘텐츠 코딩에 대한 고려사항

새 콘텐츠 코딩은 가능한 한 자체 설명적이어야 하며, 선택적 매개변수는 전송 중에 손실될 수 있는 외부 메타데이터에 의존하지 말고 코딩 형식 자체 내에서 발견 가능하도록 하는 것이 바람직합니다.

16.7. 업그레이드 토큰 레지스트리

"Hypertext Transfer Protocol (HTTP) Upgrade Token Registry"는 Upgrade 헤더 필드에서 프로토콜을 식별하는 데 사용되는 프로토콜 이름 토큰의 네임스페이스를 정의합니다. 이 레지스트리는 https://www.iana.org/assignments/http-upgrade-tokens에서 관리됩니다.

등록된 각 프로토콜 이름은 연락처 정보 및 업그레이드 후 연결이 어떻게 처리되는지에 대한 선택적 사양 집합과 연관됩니다.

등록은 "선착순(First Come First Served)" 방식으로 이루어지며(참조: RFC8126 Section 4.4), 다음 규칙이 적용됩니다:

  1. 한 번 등록된 프로토콜 이름 토큰은 영구히 등록 상태를 유지합니다.
  2. 프로토콜 이름 토큰은 대소문자 구분이 없으며, 발신자가 생성할 권장 대소문자 표기가 함께 등록됩니다.
  3. 등록에는 책임 주체가 명명되어야 MUST 합니다.
  4. 등록에는 연락 담당자가 명명되어야 MUST 합니다.
  5. 등록은 해당 토큰과 연관된 명세 집합을 명명할 수 있습니다(선택). 그러한 명세는 공개적으로 이용 가능하지 않을 수도 있습니다.
  6. 등록 시점에 책임 주체는 그 토큰과 연관된 예상 "protocol-version" 토큰 집합을 명명하는 것이 SHOULD 합니다.
  7. 책임 주체는 언제든 등록을 변경할 수 MAY 있습니다. IANA는 모든 변경 기록을 보관하고 요청 시 제공할 것입니다.
  8. IESG는 프로토콜 토큰에 대한 책임을 재할당할 수 MAY 있습니다. 이는 일반적으로 책임 주체에 연락할 수 없을 때에만 사용됩니다.

17. 보안 고려사항

이 섹션은 개발자, 정보 제공자 및 사용자가 HTTP 의미론과 인터넷을 통한 정보 전송에 관련된 알려진 보안 문제를 이해하도록 돕기 위한 것입니다. 캐싱과 관련된 고려사항은 Section 7[CACHING]에서 다루며, HTTP/1.1 메시지 문법 및 파싱과 관련된 고려사항은 Section 11[HTTP/1.1]에서 다룹니다.

아래의 고려사항 목록은 전체를 망라하지 않습니다. HTTP 의미론과 관련된 대부분의 보안 문제는 프로토콜 자체의 보안이라기보다는 서버 측 애플리케이션(HTTP 인터페이스 뒤의 코드)을 보호하는 것, HTTP로 수신한 콘텐츠를 처리하는 사용자 에이전트의 보안, 또는 일반적인 인터넷 사용의 보안에 관한 것입니다. HTTP 작동의 근간이 되는 URI의 보안 고려사항은 Section 7[URI]에서 논의됩니다. 여러 조직이 웹 애플리케이션 보안에 대한 주제별 정보와 최신 연구 링크를 유지하고 있습니다(예: [OWASP]).

17.1. 권한(Authority) 확립

HTTP는 권한 있는 응답(authoritative response)의 개념에 의존합니다: 이는 대상 URI에 의해 식별된 출처(origin) 서버가(또는 그 지시에 따라) 응답 시점의 대상 리소스 상태를 고려하여 해당 요청에 대해 가장 적절하다고 판단한 응답입니다.

권한 구성요소(authority component)에 등록된 이름이 사용될 때, "http" URI 스킴(Section 4.2.1)은 사용자의 로컬 이름 해석 서비스에 권한 있는 응답을 어디서 찾을지 결정하도록 의존합니다. 이는 사용자 네트워크의 호스트 테이블, 캐시된 이름, 또는 이름 해석 라이브러리에 대한 어떤 공격도 "http" URI의 권한을 확립하는 공격 경로가 됨을 의미합니다. 마찬가지로 사용자가 선택한 DNS 서버와 그가 해석 결과를 얻는 서버 계층 구조는 주소 매핑의 진위에 영향을 줄 수 있습니다; DNSSEC([RFC4033])은 진위성 개선의 한 방법이며, 더 안전한 전송 프로토콜 위에서 DNS 요청을 수행하는 다양한 메커니즘도 진위성 향상에 도움이 됩니다.

더욱이, IP 주소를 획득한 이후에는 "http" URI에 대한 권한 확립이 인터넷 프로토콜 라우팅에 대한 공격에 취약해질 수 있습니다.

"https" 스킴(Section 4.2.2)은 협상된 연결이 안전하고 클라이언트가 통신 서버의 신원이 대상 URI의 authority 구성요소와 일치함을 올바르게 검증하는 경우(참조: Section 4.3.4) 이러한 잠재적 공격의 많은 부분을 방지하거나 드러내도록 의도되었습니다. 이러한 검증을 올바르게 구현하는 것은 어려울 수 있습니다(참조: [Georgiev]).

지정된 origin 서버에 대한 권한은 프로토콜 확장을 통해 위임될 수 있습니다; 예를 들어 [ALTSVC]와 같습니다. 마찬가지로 연결이 권한 있는 것으로 간주되는 서버 집합은 [RFC8336]처럼 프로토콜 확장으로 변경될 수 있습니다.

공유 프록시 캐시와 같은 비권한 출처(non-authoritative source)에서 응답을 제공하는 것은 성능과 가용성을 향상시키는 데 유용한 경우가 많지만, 그 출처를 신뢰하거나 신뢰할 수 없는 응답을 안전하게 사용할 수 있는 경우에만 유용합니다.

불행히도 사용자에게 권한을 전달하는 것은 어렵습니다. 예를 들어 피싱(phishing)은 사용자 권한 인식을 공격하는 것으로, 하이퍼텍스트에서 유사한 브랜드를 표시하거나 userinfo가 authority 구성요소를 혼동시키는 방식으로 그 인식을 속일 수 있습니다(참조: Section 4.2.1). 사용자 에이전트는 사용자가 조치를 취하기 전에 대상 URI를 쉽게 검사할 수 있게 하고, userinfo가 있을 경우 이를 도드라지게 표시하거나 거부하며, 참조 문서가 알려지지 않았거나 신뢰할 수 없는 출처일 때 저장된 자격 증명과 쿠키를 전송하지 않도록 해서 피싱 공격의 영향을 줄일 수 있습니다.

17.2. 중개자(Intermediaries)의 위험

HTTP 중개자는 본질적으로 경로상(on-path)에 위치하므로 공격에 취약합니다. 중개자가 실행되는 시스템이 손상되면 심각한 보안 및 프라이버시 문제가 발생할 수 있습니다. 중개자는 보안 관련 정보, 개별 사용자 및 조직에 관한 개인 정보, 사용자 및 콘텐츠 제공자에 속한 기밀 정보를 접근할 수 있습니다. 손상된 중개자나 보안 및 프라이버시 고려 없이 구현되거나 구성된 중개자는 광범위한 잠재적 공격의 수행에 이용될 수 있습니다.

공유 캐시를 포함하는 중개자는 특히 Section 7[CACHING]에 설명된 대로 캐시 오염(cache poisoning) 공격에 취약합니다.

구현자는 설계 및 코딩 결정, 운영자에게 제공하는 구성 옵션(특히 기본 구성)의 프라이버시 및 보안 영향에 대해 고려해야 합니다.

중개자는 그들을 운영하는 사람들과 그 정책만큼만 신뢰할 수 있으며; HTTP는 이 문제를 해결할 수 없습니다.

17.3. 파일 및 경로 이름 기반 공격

출처 서버는 대상 URI에서 리소스 표현으로의 매핑을 관리하기 위해 로컬 파일 시스템을 자주 사용합니다. 대부분의 파일 시스템은 악의적인 파일명이나 경로명에 대해 보호하도록 설계되지 않았습니다. 따라서 출처 서버는 대상 리소스를 파일, 폴더 또는 디렉터리로 매핑할 때 시스템에 특별한 의미가 있는 이름에 접근하지 않도록 주의해야 합니다.

예를 들어 UNIX, Microsoft Windows 및 기타 운영체제는 ".."를 현재 디렉터리 위의 디렉터리 수준을 나타내는 경로 구성요소로 사용하고, 시스템 장치로 데이터를 보내기 위한 특별한 이름의 경로나 파일명을 사용합니다. 유사한 명명 관례가 다른 유형의 저장 시스템에도 존재할 수 있습니다. 또한 로컬 저장 시스템은 잘못되었거나 예상치 못한 문자 처리, 분해된 문자 재조합, 대소문자 무시 이름의 표준화 등에서 사용자 친화성을 보안보다 우선시하는 경향이 있습니다.

이러한 특별한 이름을 이용한 공격은 보통 서비스 거부(예: 서버에게 COM 포트에서 읽게 지시) 또는 제공되면 안 되는 구성 및 소스 파일의 노출을 목표로 합니다.

17.4. 명령, 코드 또는 쿼리 주입 기반 공격

출처 서버는 종종 URI 내 매개변수를 시스템 서비스 식별, 데이터베이스 항목 선택, 또는 데이터 소스 선택의 수단으로 사용합니다. 그러나 요청에서 수신되는 데이터는 신뢰할 수 없습니다. 공격자는 명령 호출, 언어 인터프리터 또는 데이터베이스 인터페이스를 통해 전달될 때 명령, 코드 또는 쿼리로 잘못 해석될 수 있는 데이터를 요청의 어떤 요소(method, target URI, header fields, content) 안에 구성할 수 있습니다.

예를 들어 SQL 주입(SQL injection)은 일반적인 공격으로, 대상 URI나 헤더 필드(예: Host, Referer 등)의 일부 안에 추가 쿼리 언어를 삽입합니다. 수신된 데이터가 SELECT 문 안에서 직접 사용된다면, 그 쿼리 언어는 단순한 문자열 값 대신 데이터베이스 명령으로 해석될 수 있습니다. 이러한 구현 취약점은 매우 흔하지만 예방하기는 쉽습니다.

일반적으로 리소스 구현은 요청 데이터를 명령으로 처리되거나 해석되는 컨텍스트에서 사용하지 않아야 합니다. 매개변수는 고정 문자열과 비교되어 그 비교 결과에 따라 동작해야 하며, 신뢰할 수 없는 데이터를 처리하도록 준비되지 않은 인터페이스로 전달해서는 안 됩니다. 고정된 매개변수에 기반하지 않은 수신 데이터는 오해의 소지가 없도록 신중히 필터링하거나 인코딩해야 합니다.

유사한 고려사항은 로그 파일, 모니터링 도구 내에서 저장되어 나중에 처리되는 요청 데이터나, 임베디드 스크립트를 허용하는 데이터 형식 내에 포함된 경우에도 적용됩니다.

17.5. 프로토콜 요소 길이 기반 공격

HTTP는 주로 텍스트 기반의 구분 문자(delimited) 필드를 사용하므로, 파서들은 매우 긴(또는 매우 느린) 데이터 스트림을 전송하는 공격에 취약한 경우가 많습니다. 특히 사전 정의된 길이가 없는 프로토콜 요소를 기대하는 구현에서 그러합니다(참조: Section 2.3).

상호운용성을 촉진하기 위해 필드에 대한 최소 크기 제한에 관한 구체적 권고가 제시됩니다(참조: Section 5.4). 이들은 제한된 자원을 가진 구현체에서도 지원 가능하도록 선택된 최소 권고치이며, 대부분의 구현체는 훨씬 더 높은 제한을 선택할 것으로 예상됩니다.

서버는 대상 URI가 너무 긴 메시지(Section 15.5.15)나 요청 콘텐츠가 너무 큰 메시지(Section 15.5.14)를 거부할 수 있습니다. 용량 제한과 관련된 추가 상태 코드들은 HTTP의 확장으로 정의되어 왔습니다(참조: [RFC6585]).

수신자는 요청 메서드, 응답 상태 구문(status phrases), 필드 이름, 숫자 값, 청크 길이 등 다른 프로토콜 요소들을 처리하는 범위를 신중히 제한해야 합니다. 이러한 처리를 제한하지 않으면 버퍼 오버플로우나 산술 오버플로우로 인해 임의 코드 실행이 발생하거나 서비스 거부 공격에 취약성이 증가할 수 있습니다.

17.6. 공유 사전 기반 압축을 이용한 공격

암호화된 프로토콜에 대한 일부 공격은 동적 압축으로 인해 생기는 크기 차이를 이용해 기밀 정보를 노출합니다. 예를 들어 [BREACH]가 있습니다. 이러한 공격은 공격자가 제어하는 콘텐츠와 기밀 정보 사이에 중복성을 만들어내어, 동일한 사전을 사용하는 동적 압축 알고리즘이 공격자 제어 콘텐츠가 기밀 콘텐츠의 일부와 일치할 때 더 효율적으로 압축되는 점을 이용합니다.

HTTP 메시지는 TLS 압축, 콘텐츠 코딩, 전송 코딩, 그리고 다른 확장 또는 버전 특정 메커니즘을 포함하여 여러 방식으로 압축될 수 있습니다.

이 위험에 대한 가장 효과적인 완화책은 민감한 데이터에 대한 압축을 비활성화하거나, 민감한 데이터와 공격자 제어 데이터를 엄격히 분리하여 동일한 압축 사전을 공유하지 못하게 하는 것입니다. 신중한 설계로는 HPACK([HPACK])과 같이 제한된 사용 사례에서 취약하다고 간주되지 않는 방식으로 압축 체계를 설계할 수 있습니다.

17.7. 개인 정보의 노출

클라이언트는 사용자가 리소스와 상호작용하기 위해 제공한 정보(예: 사용자 이름, 위치, 우편 주소, 비밀번호, 암호 키 등)와 시간이 지남에 따른 사용자의 브라우징 활동(예: 방문 기록, 북마크 등)을 포함하여 많은 양의 개인 정보를 알게 되는 경우가 많습니다. 구현자는 개인 정보의 의도치 않은 노출을 방지해야 합니다.

17.8. 서버 로그 정보의 프라이버시

서버는 사용자의 요청에 관한 개인 데이터를 시간 경과에 따라 저장할 수 있는 위치에 있으며, 이는 사용자의 읽기 패턴이나 관심 주제를 식별할 수 있습니다. 특히 중개자에서 수집된 로그 정보는 여러 사이트에 걸친 사용자 에이전트 상호작용의 기록을 포함하는 경우가 많아 개별 사용자로 추적될 수 있습니다.

HTTP 로그 정보는 기밀성이 요구되는 성격을 가지며; 그 처리에는 법률 및 규정이 종종 적용됩니다. 로그 정보는 안전하게 저장되어야 하고 분석을 위한 적절한 지침이 따라야 합니다. 개별 항목 내 개인 정보의 익명화는 도움이 되지만, 일반적으로 다른 접근 특성과의 상관관계에 근거해 실제 로그 추적을 재식별하는 것을 완전히 방지하지는 못합니다. 따라서 특정 클라이언트에 키된 접근 추적은 키가 가명이라 하더라도 게시하기에 안전하지 않습니다.

도난 또는 우발적 공개의 위험을 최소화하기 위해 로그 정보는 보안, 감사 또는 사기 통제에 필요한 운영상의 필요가 없어지는 즉시 사용자 식별자, IP 주소 및 사용자가 제공한 쿼리 매개변수 등을 포함한 개인 식별 정보를 제거해야 합니다.

17.9. URI 내 민감한 정보의 노출

URI는 안전하게 보호되는 것이 아니라 공유되도록 설계되었습니다. URI는 종종 화면에 표시되고, 페이지 인쇄 시 템플릿에 추가되며, 다양한 보호되지 않은 즐겨찾기 목록에 저장됩니다. 많은 서버, 프록시 및 사용자 에이전트는 타사에게 보일 수 있는 위치에 대상 URI를 기록하거나 표시합니다. 따라서 URI에 민감하거나 개인 식별 가능하거나 노출 위험이 있는 정보를 포함하는 것은 현명하지 않습니다.

애플리케이션이 GET을 사용하는 양식의 쿼리 필드처럼 사용자 제공 정보를 이용해 클라이언트 측에서 대상 URI를 구성할 때, 노출되기에는 부적절한 민감한 데이터가 URI에 포함될 가능성이 있습니다. 이러한 경우 POST는 일반적으로 URI를 구성하지 않으므로 민감한 데이터를 요청 본문에 전송하기 때문에 선호되지만, 이는 캐싱을 방해하고 본래 안전한 요청을 안전하지 않은 메서드로 처리하게 할 수 있습니다. 대안으로는 사용자 제공 데이터를 URI를 구성하기 전에 변환하거나 민감하지 않은 일반 값만 포함하도록 필터링하는 방법이 있습니다. 또한 쿼리 결과를 다른(서버가 생성한) URI로 리다이렉트하면 이후 링크에서 민감한 데이터를 제거하고 향후 재사용을 위한 캐시 가능한 응답을 제공할 수 있습니다.

Referer 헤더 필드는 대상 사이트에 요청을 야기한 컨텍스트를 알려주므로, 사용자의 즉각적인 브라우징 기록 및 참조 리소스의 URI에 포함된 개인 정보를 드러낼 가능성이 있습니다. Referer 헤더 필드의 제한은 일부 보안 고려사항을 다루기 위해 Section 10.1.3에 설명되어 있습니다.

17.10. 필드 이름의 애플리케이션 처리

서버는 수신된 요청을 처리하고 응답용 콘텐츠를 생성하기 위해 비-HTTP 게이트웨이 인터페이스와 프레임워크를 자주 사용합니다. 역사적 이유로 이러한 인터페이스는 수신된 필드 이름을 외부 변수명으로 전달할 때 환경 변수에 적합한 이름 매핑을 사용하는 경우가 많습니다.

예를 들어 Common Gateway Interface(CGI)의 프로토콜 특화 메타변수 매핑은 Section 4.1.18[RFC3875]에 정의되어 있으며, CGI의 표준 변수 중 하나와 대응하지 않는 수신된 헤더 필드에 대해 적용됩니다; 매핑은 각 이름 앞에 "HTTP_"를 붙이고 하이픈("-")을 밑줄("_")로 변경하는 것으로 구성됩니다. 이 동일한 매핑은 많은 다른 애플리케이션 프레임워크에 의해 상속되어 플랫폼 간 애플리케이션 이동을 단순화합니다.

CGI에서는 수신된 Content-Length 필드가 메타변수 "CONTENT_LENGTH"로 전달되어 수신된 필드 값과 일치하는 문자열 값을 갖습니다. 반면에 "Content_Length"라는 이름의 수신된 헤더 필드는 프로토콜 특화 메타변수 "HTTP_CONTENT_LENGTH"로 전달되어, 애플리케이션이 기본 메타변수가 아닌 프로토콜 특화 메타변수를 실수로 읽을 경우 혼동을 초래할 수 있습니다. (이 과거 관행이 Section 16.3.2.1에서 밑줄을 포함한 새 필드 이름 생성을 권장하지 않는 이유입니다.)

불행히도 필드 이름을 다른 인터페이스 이름으로 매핑하면 매핑이 불완전하거나 모호할 경우 보안 취약점이 발생할 수 있습니다. 예를 들어 공격자가 "Transfer_Encoding"이라는 필드를 보낸다면, 단순한 인터페이스는 이를 "Transfer-Encoding" 필드와 동일한 변수명으로 매핑할 수 있으며, 이는 요청 스머글링(request smuggling) 취약점을 초래할 수 있습니다(참조: Section 11.2[HTTP/1.1]).

관련 위험을 완화하기 위해, 이러한 매핑을 수행하는 구현은 수신될 수 있는 전체 옥텟 범위(HTTP 문법에서 권장되지 않거나 금지된 문자 포함)에 대해 매핑을 모호성 없이 완전하게 만들 것을 권고합니다. 예를 들어 특이한 이름 문자를 가진 필드는 요청이 차단되거나 해당 특정 필드가 제거되거나 다른 접두사를 사용하여 다른 필드와 구분되도록 전달될 수 있습니다.

17.11. 리다이렉트 후 프래그먼트의 노출

URI 참조 내에서 사용되는 프래그먼트 식별자는 요청에 전송되지 않지만, 구현자는 그것이 사용자 에이전트와 응답의 결과로 실행되는 확장이나 스크립트에 의해 볼 수 있게 된다는 점을 알아야 합니다. 특히 리다이렉트가 발생하고 원래 요청의 프래그먼트 식별자가 Location에 있는 새 참조로 상속될 때(Section 10.2.2), 이는 한 사이트의 프래그먼트가 다른 사이트에 노출되는 효과를 가질 수 있습니다. 첫 번째 사이트가 프래그먼트에 개인 정보를 사용한다면, 다른 사이트로의 리다이렉트가 상속을 차단하도록 (비어 있을 수도 있는) 프래그먼트 구성요소를 포함하도록 해야 합니다.

17.12. 제품 정보의 노출

User-Agent (Section 10.1.5), Via (Section 7.6.3), 및 Server (Section 10.2.4) 헤더 필드는 종종 해당 발신자의 소프트웨어 시스템에 관한 정보를 드러냅니다. 이론적으로 이는 공격자가 알려진 보안 취약점을 악용하기 쉽게 만들 수 있지만, 실제로 공격자는 사용되는 소프트웨어 버전에 관계없이 가능한 모든 취약점을 시도하는 경향이 있습니다.

방화벽 뒤 네트워크를 통과하는 관문 역할을 하는 프록시는 방화벽 뒤에 있는 호스트를 식별할 수 있는 헤더 정보를 전송할 때 특별한 주의를 기울여야 합니다. Via 헤더 필드는 중개자가 민감한 기계 이름을 가명으로 대체할 수 있게 합니다.

17.13. 브라우저 핑거프린팅

브라우저 핑거프린팅은 고유한 특성 집합을 통해 특정 사용자 에이전트를 시간에 걸쳐 식별하는 기술들의 집합입니다. 이러한 특성은 기저 전송 프로토콜 사용, 기능 능력, 스크립팅 환경 등과 관련된 정보를 포함할 수 있으며, 여기서 특히 관심 있는 것은 HTTP를 통해 전달될 수 있는 고유한 특성들입니다. 핑거프린팅은 사용자 에이전트의 행동을 시간에 걸쳐 추적할 수 있게 하므로 프라이버시 문제로 간주됩니다([Bujlow]). 많은 범용 사용자 에이전트(즉 웹 브라우저)는 자신의 핑거프린트를 줄이기 위한 조치를 취해왔습니다.

서버에 대해 충분히 고유하여 핑거프린팅을 가능하게 하는 정보를 드러낼 수 있는 요청 헤더 필드들이 여러 있습니다. 가장 명백한 것은 From 헤더 필드이지만, 이는 일반적으로 사용자가 자기 식별을 원할 때만 전송될 것으로 예상됩니다. 마찬가지로 Cookie 헤더 필드는 재식별을 가능하게 하도록 고의로 설계되었으므로, 쿠키가 비활성화되거나 제한된 상황에서만 핑거프린팅 문제가 적용됩니다.

User-Agent 헤더 필드는 특히 다른 특성과 결합될 때 특정 장치를 고유하게 식별할 만큼 충분한 정보를 포함할 수 있습니다. 그러나 사용자가 가장 예상치 못한 고유 정보의 출처는 사전적 협상(proactive negotiation)(Section 12.1)이며, 여기에는 Accept, Accept-Charset, Accept-Encoding, 및 Accept-Language 헤더 필드가 포함됩니다.

핑거프린팅 문제 외에도 Accept-Language 헤더 필드의 자세한 사용은 사용자가 사적으로 여길 수 있는 정보를 드러낼 수 있습니다. 예를 들어 특정 언어 집합의 이해는 특정 민족 집단 소속과 강하게 상관될 수 있습니다. 이러한 프라이버시 손실을 제한하는 한 가지 접근법은 사용자 에이전트가 명시적으로 허용된 사이트에 대해서만 Accept-Language를 전송하고, Vary 헤더 필드가 언어 협상이 유용할 수 있음을 감지한 후 상호작용을 통해 허용을 받는 방식일 수 있습니다.

프라이버시를 향상시키기 위해 프록시를 사용하는 환경에서는 사용자 에이전트가 사전적 협상 헤더 필드 전송에 대해 보수적으로 행동해야 합니다. 높은 수준의 헤더 필드 구성 가능성을 제공하는 범용 사용자 에이전트는 너무 많은 세부 정보를 제공할 경우 발생할 수 있는 프라이버시 손실에 대해 사용자에게 알려야 합니다. 극단적인 프라이버시 조치로서 프록시는 전달되는 요청의 사전적 협상 헤더 필드를 필터링할 수 있습니다.

17.14. 밸리데이터(Validator) 보존

이 명세서에서 정의한 밸리데이터는 표현의 유효성을 보장하거나 악의적 변경을 막거나 경로상 공격을 탐지하기 위한 것이 아닙니다. 잘 작동하는 경우에는 캐시 업데이트와 낙관적 동시 쓰기를 더 효율적으로 해주지만, 최악의 경우 조건이 실패하여 클라이언트가 조건부 요청 없이 이루어지는 HTTP 교환과 비교해 더 해로운 응답을 받지 않도록 합니다.

엔터티 태그(entity tag)는 프라이버시 위험을 만들 수 있는 방식으로 악용될 수 있습니다. 예를 들어 사이트가 사용자 또는 사용자 에이전트에 고유한 의미적으로 무효한 엔터티 태그를 고의로 생성하여 긴 신선도 시간을 가진 캐시 가능한 응답으로 전송한 다음, 이후의 조건부 요청에서 그 엔터티 태그를 읽어 해당 사용자나 에이전트를 재식별할 수 있습니다. 이러한 식별 태그는 사용자가 원래 캐시 항목을 보유하는 한 지속적인 식별자가 될 수 있습니다. 표현을 캐시하는 사용자 에이전트는 사용자가 쿠키를 삭제하거나 개인 브라우징 모드로 전환하는 등 프라이버시 유지 조치를 수행할 때 캐시를 지우거나 교체하도록 보장해야 합니다.

17.15. Range를 이용한 서비스 거부(DoS) 공격

제한 없는 다중 범위 요청은 동일한 데이터의 많은 중첩 범위를 요청하는 데 필요한 노력은 매우 작지만, 그 요청된 데이터를 여러 부분으로 제공하려는 데 소비되는 시간, 메모리 및 대역폭은 막대하므로 서비스 거부 공격에 취약합니다. 서버는 두 개를 초과하는 중첩 범위나 단일 집합에서 많은 작은 범위를 요청하는 등 명백한 악의적 범위 요청을 무시하거나 병합하거나 거부해야 합니다. 특히 이유 없이 범위들이 순서 밖으로 요청될 때 그렇습니다. 멀티파트 범위 요청은 임의 접근(random access)을 지원하도록 설계되지 않았습니다.

17.16. 인증 관련 고려사항

HTTP 인증 주제 자체가 전부 보안 고려사항이므로, 아래의 고려사항 목록은 전체를 망라하지 않습니다. 또한 여기서는 인증 프레임워크 일반에 관한 보안 고려사항에 국한하며, 특정 인증 스킴에 대한 모든 잠재적 고려사항은 해당 스킴을 정의하는 명세에서 문서화되어야 합니다. 여러 조직이 웹 애플리케이션 보안에 관한 주제별 정보와 최신 연구 링크(예: [OWASP])를 유지하고 있으며, 실제로 사용되는 인증 스킴을 구현하고 사용하는 데 있어 일반적인 함정을 포함합니다.

17.16.1. 자격 증명 기밀성

HTTP 인증 프레임워크는 자격 증명의 기밀성을 유지하기 위한 단일 메커니즘을 정의하지 않습니다; 대신 각 인증 스킴은 전송 전에 자격 증명이 어떻게 인코딩되는지를 정의합니다. 이는 향후 인증 스킴 개발에 유연성을 제공하지만, 자체적으로 기밀성을 제공하지 않거나 재사용(replay) 공격에 충분히 대응하지 못하는 기존 스킴을 보호하기에는 불충분할 수 있습니다. 또한 서버가 사용자별 자격 증명을 기대하는 경우에는 자격 증명의 내용이 기밀로 유지되더라도 해당 교환은 사용자를 식별하는 효과를 가집니다.

HTTP는 필드의 기밀 전송을 제공하기 위해 기저 전송 또는 세션 수준 연결의 보안 특성에 의존합니다. 개별 사용자 인증에 의존하는 서비스는 자격 증명을 교환하기 전에 보호된 연결을 요구합니다(Section 4.2.2).

17.16.2. 유휴(Idle) 클라이언트와 자격 증명

기존 HTTP 클라이언트와 사용자 에이전트는 일반적으로 인증 정보를 무기한 보유하는 경향이 있습니다. HTTP는 출처 서버가 클라이언트에게 이러한 캐시된 자격 증명을 폐기하도록 지시할 수 있는 메커니즘을 제공하지 않습니다. 이는 프로토콜이 자격 증명이 어떻게 획득되거나 사용자 에이전트에 의해 어떻게 관리되는지 알지 못하기 때문입니다. 자격 증명의 만료 또는 철회 메커니즘은 인증 스킴 정의의 일부로 명시될 수 있습니다.

자격 증명 캐싱이 애플리케이션의 보안 모델과 충돌할 수 있는 상황에는 다음이 포함되지만 이에 국한되지 않습니다:

  • 장기간 유휴 상태였던 클라이언트가 이후 서버가 사용자에게 자격 증명을 다시 입력하도록 유도하고자 하는 경우.
  • 애플리케이션이 세션 종료 표시(예: 페이지의 "로그아웃" 또는 "커밋" 버튼)를 포함하는 경우, 그 이후 서버 측 애플리케이션은 클라이언트가 자격 증명을 보관할 더 이상의 이유가 없음을 "알게" 됩니다.

자격 증명을 캐시하는 사용자 에이전트는 사용자 제어 하에 캐시된 자격 증명을 쉽게 폐기할 수 있는 메커니즘을 제공하는 것이 권장됩니다.

17.16.3. 보호 영역(Protection Spaces)

"realm" 메커니즘에만 의존해 보호 영역을 설정하는 인증 스킴은 동일한 출처(origin) 서버의 모든 리소스에 자격 증명을 노출하게 됩니다. 리소스에 대해 성공적으로 인증 요청을 수행한 클라이언트는 동일한 출처 서버의 다른 리소스에 동일한 인증 자격 증명을 사용할 수 있습니다. 이로 인해 다른 리소스가 다른 리소스의 인증 자격 증명을 수집할 수 있는 가능성이 생깁니다.

이는 특히 출처 서버가 동일한 origin 아래에서 여러 당사자를 호스팅할 때 문제가 됩니다(참조: Section 11.5). 가능한 완화 전략에는 인증 자격 증명에 대한 직접 접근을 제한(예: Authorization 요청 헤더 필드의 내용 제공을 막음)하거나 각 당사자에 대해 서로 다른 호스트 이름(또는 포트 번호)을 사용하여 보호 영역을 분리하는 것이 포함됩니다.

17.16.4. 응답에 추가되는 인증 관련 필드

암호화되지 않은 채널을 통해 전송되는 응답에 정보를 추가하는 것은 보안과 프라이버시에 영향을 미칠 수 있습니다. Authentication-InfoProxy-Authentication-Info 헤더 필드의 존재만으로도 HTTP 인증이 사용 중임을 나타냅니다. 인증 스킴별 매개변수의 내용이 추가 정보를 노출할 수 있으므로 이는 해당 스킴 정의에서 고려되어야 합니다.

18. IANA 고려사항

다음 등록 항목들의 변경 제어자는 "IETF (iesg@ietf.org) - Internet Engineering Task Force"입니다.

18.1. URI 스킴 등록

IANA는 [BCP35]에 따라 "Uniform Resource Identifier (URI) Schemes" 레지스트리(https://www.iana.org/assignments/uri-schemes/)를 업데이트했으며, Section 4.2Table 2에 나열된 영구 스킴들을 포함했습니다.

18.2. 메서드 등록

IANA는 "Hypertext Transfer Protocol (HTTP) Method Registry"(https://www.iana.org/assignments/http-methods)를 업데이트했으며, Section 16.1.1의 등록 절차와 다음 표에 요약된 메서드 이름들을 반영했습니다.

표 7
메서드 안전한가 멱등성 섹션
CONNECT no no 9.3.6
DELETE no yes 9.3.5
GET yes yes 9.3.1
HEAD yes yes 9.3.2
OPTIONS yes yes 9.3.7
POST no no 9.3.3
PUT no yes 9.3.4
TRACE yes yes 9.3.8
* no no 18.2

"*"라는 메서드 이름은 일부 필드(예: "Access-Control-Request-Method")에서 와일드카드로 사용되는 것과 충돌할 수 있으므로 예약되어 있습니다.

18.3. 상태 코드 등록

IANA는 "Hypertext Transfer Protocol (HTTP) Status Code Registry"(https://www.iana.org/assignments/http-status-codes)를 업데이트했으며, Section 16.2.1의 등록 절차와 다음 표에 요약된 상태 코드 값을 반영했습니다.

표 8
설명 섹션
100 Continue 15.2.1
101 Switching Protocols 15.2.2
200 OK 15.3.1
201 Created 15.3.2
202 Accepted 15.3.3
203 Non-Authoritative Information 15.3.4
204 No Content 15.3.5
205 Reset Content 15.3.6
206 Partial Content 15.3.7
300 Multiple Choices 15.4.1
301 Moved Permanently 15.4.2
302 Found 15.4.3
303 See Other 15.4.4
304 Not Modified 15.4.5
305 Use Proxy 15.4.6
306 (Unused) 15.4.7
307 Temporary Redirect 15.4.8
308 Permanent Redirect 15.4.9
400 Bad Request 15.5.1
401 Unauthorized 15.5.2
402 Payment Required 15.5.3
403 Forbidden 15.5.4
404 Not Found 15.5.5
405 Method Not Allowed 15.5.6
406 Not Acceptable 15.5.7
407 Proxy Authentication Required 15.5.8
408 Request Timeout 15.5.9
409 Conflict 15.5.10
410 Gone 15.5.11
411 Length Required 15.5.12
412 Precondition Failed 15.5.13
413 Content Too Large 15.5.14
414 URI Too Long 15.5.15
415 Unsupported Media Type 15.5.16
416 Range Not Satisfiable 15.5.17
417 Expectation Failed 15.5.18
418 (Unused) 15.5.19
421 Misdirected Request 15.5.20
422 Unprocessable Content 15.5.21
426 Upgrade Required 15.5.22
500 Internal Server Error 15.6.1
501 Not Implemented 15.6.2
502 Bad Gateway 15.6.3
503 Service Unavailable 15.6.4
504 Gateway Timeout 15.6.5
505 HTTP Version Not Supported 15.6.6

18.4. 필드 이름 등록

본 규격서는 [RFC3864]에 정의된 메시지 헤더 필드에 대한 기존 등록 절차의 HTTP 관련 측면을 업데이트합니다. 이는 HTTP와 관련된 예전 절차를 대체하며, 새로운 등록 절차를 정의하고 HTTP 필드 정의를 별도의 레지스트리로 이동시킵니다.

IANA는 Section 16.3.1에 설명된 대로 "Hypertext Transfer Protocol (HTTP) Field Name Registry"라는 새 레지스트리를 생성했습니다.

IANA는 프로토콜이 'http'인 "Permanent Message Header Field Names" 및 "Provisional Message Header Field Names" 레지스트리(https://www.iana.org/assignments/message-headers/)에 있는 모든 항목을 이 레지스트리로 이동했으며 다음과 같은 변경을 적용했습니다:

  1. 'Applicable Protocol' 필드가 생략되었습니다.
  2. 'standard', 'experimental', 'reserved', 또는 'informational' 상태였던 항목들은 'permanent' 상태로 변경되었습니다.
  3. 상태가 없는 임시(Provisional) 항목들은 'provisional' 상태로 지정되었습니다.
  4. 명세 문서에서 상태를 정의하지 않은 영구 항목들은 'provisional' 상태로 지정되었습니다(전문가가 다른 상태가 더 적절하다고 판단하면 항목의 상태를 갱신할 수 있습니다).

IANA는 HTTP 필드 이름 등록이 이동했음을 나타내기 위해 "Permanent Message Header Field Names" 및 "Provisional Message Header Field Names" 레지스트리에 다음의 주석을 추가했습니다:

IANA는 다음 표에 나열된 필드 이름들로 "Hypertext Transfer Protocol (HTTP) Field Name Registry"를 업데이트했습니다.

표 9
필드 이름 상태 섹션 비고
Accept permanent 12.5.1
Accept-Charset deprecated 12.5.2
Accept-Encoding permanent 12.5.3
Accept-Language permanent 12.5.4
Accept-Ranges permanent 14.3
Allow permanent 10.2.1
Authentication-Info permanent 11.6.3
Authorization permanent 11.6.2
Connection permanent 7.6.1
Content-Encoding permanent 8.4
Content-Language permanent 8.5
Content-Length permanent 8.6
Content-Location permanent 8.7
Content-Range permanent 14.4
Content-Type permanent 8.3
Date permanent 6.6.1
ETag permanent 8.8.3
Expect permanent 10.1.1
From permanent 10.1.2
Host permanent 7.2
If-Match permanent 13.1.1
If-Modified-Since permanent 13.1.3
If-None-Match permanent 13.1.2
If-Range permanent 13.1.5
If-Unmodified-Since permanent 13.1.4
Last-Modified permanent 8.8.2
Location permanent 10.2.2
Max-Forwards permanent 7.6.2
Proxy-Authenticate permanent 11.7.1
Proxy-Authentication-Info permanent 11.7.3
Proxy-Authorization permanent 11.7.2
Range permanent 14.2
Referer permanent 10.1.3
Retry-After permanent 10.2.3
Server permanent 10.2.4
TE permanent 10.1.4
Trailer permanent 6.6.2
Upgrade permanent 7.8
User-Agent permanent 10.1.5
Vary permanent 12.5.5
Via permanent 7.6.3
WWW-Authenticate permanent 11.6.1
* permanent 12.5.5 (예약됨)

"*"라는 필드 이름은 Vary 헤더 필드(Section 12.5.5)에서의 특수 의미와 충돌할 수 있으므로 예약되어 있습니다.

IANA는 새 레지스트리에서 "Content-MD5" 항목의 상태를 'obsoleted'로 업데이트했으며, 해당 헤더 필드 정의에 대한 참조로 RFC2616 Section 14.15와 정의가 제거된 사실을 나타내는 RFC7231 Appendix B를 참조로 추가했습니다.

18.5. 인증 스킴 등록

IANA는 "Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry"(https://www.iana.org/assignments/http-authschemes)를 Section 16.4.1의 등록 절차로 업데이트했습니다. 이 문서에는 새로운 인증 스킴이 정의되어 있지 않습니다.

18.6. 콘텐츠 코딩 등록

IANA는 "HTTP Content Coding Registry"(https://www.iana.org/assignments/http-parameters/)를 Section 16.6.1의 등록 절차에 따라 업데이트했으며, 아래 표에 요약된 콘텐츠 코딩 이름들을 반영했습니다.

표 10
이름 설명 섹션
compress UNIX "compress" 데이터 형식 [Welch] 8.4.1.1
deflate "deflate" 압축 데이터([RFC1951]) 가 "zlib" 데이터 형식([RFC1950]) 안에 있는 형태 8.4.1.2
gzip GZIP 파일 형식 [RFC1952] 8.4.1.3
identity 예약어 12.5.3
x-compress 사용 중단(= compress의 별칭) 8.4.1.1
x-gzip 사용 중단(= gzip의 별칭) 8.4.1.3

18.7. 범위 단위 등록

IANA는 "HTTP Range Unit Registry"(https://www.iana.org/assignments/http-parameters/)를 Section 16.5.1의 등록 절차에 따라 업데이트했으며, 아래 표에 요약된 범위 단위 이름들을 반영했습니다.

표 11
범위 단위 이름 설명 섹션
bytes 옥텟의 범위 14.1.2
none 범위 요청을 지원하지 않음을 나타내는 키워드로 예약됨 14.3

18.8. 미디어 타입 등록

IANA는 "Media Types" 레지스트리(https://www.iana.org/assignments/media-types)를 업데이트했으며, "multipart/byteranges" 미디어 타입에 대한 등록 정보를 Section 14.6에 추가했습니다.

IANA는 "q" 매개변수에 관한 레지스트리 주석을 업데이트하여 이 문서의 Section 12.5.1로의 링크를 추가했습니다.

18.9. 포트 등록

IANA는 UDP 또는 TCP를 사용하는 80 및 443 포트의 서비스에 대해 "Service Name and Transport Protocol Port Number Registry"(https://www.iana.org/assignments/service-names-port-numbers/)를 업데이트했으며, 다음과 같이 조치했습니다:

  1. 이 문서를 "Reference"로 사용하도록 하고,
  2. 현재 지정되지 않은 경우 "Assignee"를 "IESG"로 하고 "Contact"을 "IETF_Chair"로 설정했습니다.

18.10. 업그레이드 토큰 등록

IANA는 "Hypertext Transfer Protocol (HTTP) Upgrade Token Registry"(https://www.iana.org/assignments/http-upgrade-tokens)를 Section 16.7에 설명된 등록 절차로 업데이트했으며, 다음 표에 요약된 업그레이드 토큰 이름들을 반영했습니다.

표 12
이름 설명 예상 버전 토큰 섹션
HTTP Hypertext Transfer Protocol any DIGIT.DIGIT (예: "2.0") 2.5

19. 참조문헌

19.1. 규범적 참조문헌

[CACHING]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “HTTP Caching”, STD 98, RFC 9111, DOI 10.17487/RFC9111, 2022년 6월.
[RFC1950]
Deutsch, P. and J-L. Gailly, “ZLIB Compressed Data Format Specification version 3.3”, RFC 1950, DOI 10.17487/RFC1950, 1996년 5월, <https://www.rfc-editor.org/info/rfc1950>.
[RFC1951]
Deutsch, P., “DEFLATE Compressed Data Format Specification version 1.3”, RFC 1951, DOI 10.17487/RFC1951, 1996년 5월, <https://www.rfc-editor.org/info/rfc1951>.
[RFC1952]
Deutsch, P., “GZIP file format specification version 4.3”, RFC 1952, DOI 10.17487/RFC1952, 1996년 5월, <https://www.rfc-editor.org/info/rfc1952>.
[RFC2046]
Freed, N. and N. Borenstein, “Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types”, RFC 2046, DOI 10.17487/RFC2046, 1996년 11월, <https://www.rfc-editor.org/info/rfc2046>.
[RFC2119]
Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, 1997년 3월, <https://www.rfc-editor.org/info/rfc2119>.
[RFC4647]
Phillips, A., Ed. and M. Davis, Ed., “Matching of Language Tags”, BCP 47, RFC 4647, DOI 10.17487/RFC4647, 2006년 9월, <https://www.rfc-editor.org/info/rfc4647>.
[RFC4648]
Josefsson, S., “The Base16, Base32, and Base64 Data Encodings”, RFC 4648, DOI 10.17487/RFC4648, 2006년 10월, <https://www.rfc-editor.org/info/rfc4648>.
[RFC5234]
Crocker, D., Ed. and P. Overell, “Augmented BNF for Syntax Specifications: ABNF”, STD 68, RFC 5234, DOI 10.17487/RFC5234, 2008년 1월, <https://www.rfc-editor.org/info/rfc5234>.
[RFC5280]
Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, “Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile”, RFC 5280, DOI 10.17487/RFC5280, 2008년 5월, <https://www.rfc-editor.org/info/rfc5280>.
[RFC5322]
Resnick, P., Ed., “Internet Message Format”, RFC 5322, DOI 10.17487/RFC5322, 2008년 10월, <https://www.rfc-editor.org/info/rfc5322>.
[RFC5646]
Phillips, A., Ed. and M. Davis, Ed., “Tags for Identifying Languages”, BCP 47, RFC 5646, DOI 10.17487/RFC5646, 2009년 9월, <https://www.rfc-editor.org/info/rfc5646>.
[RFC6125]
Saint-Andre, P. and J. Hodges, “Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)”, RFC 6125, DOI 10.17487/RFC6125, 2011년 3월, <https://www.rfc-editor.org/info/rfc6125>.
[RFC6365]
Hoffman, P. and J. Klensin, “Terminology Used in Internationalization in the IETF”, BCP 166, RFC 6365, DOI 10.17487/RFC6365, 2011년 9월, <https://www.rfc-editor.org/info/rfc6365>.
[RFC7405]
Kyzivat, P., “Case-Sensitive String Support in ABNF”, RFC 7405, DOI 10.17487/RFC7405, 2014년 12월, <https://www.rfc-editor.org/info/rfc7405>.
[RFC8174]
Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, 2017년 5월, <https://www.rfc-editor.org/info/rfc8174>.
[TCP]
Postel, J., “Transmission Control Protocol”, STD 7, RFC 793, DOI 10.17487/RFC0793, 1981년 9월, <https://www.rfc-editor.org/info/rfc793>.
[TLS13]
Rescorla, E., “The Transport Layer Security (TLS) Protocol Version 1.3”, RFC 8446, DOI 10.17487/RFC8446, 2018년 8월, <https://www.rfc-editor.org/info/rfc8446>.
[URI]
Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax”, STD 66, RFC 3986, DOI 10.17487/RFC3986, 2005년 1월, <https://www.rfc-editor.org/info/rfc3986>.
[USASCII]
American National Standards Institute, “Coded Character Set -- 7-bit American Standard Code for Information Interchange”, ANSI X3.4, 1986.
[Welch]
Welch, T., “A Technique for High-Performance Data Compression”, IEEE Computer 17(6), DOI 10.1109/MC.1984.1659158, 1984년 6월, <https://ieeexplore.ieee.org/document/1659158/>.

19.2. 참고(정보 제공) 문헌

[ALTSVC]
Nottingham, M., McManus, P., and J. Reschke, “HTTP Alternative Services”, RFC 7838, DOI 10.17487/RFC7838, 2016년 4월, <https://www.rfc-editor.org/info/rfc7838>.
[BCP13]
Freed, N. and J. Klensin, “Multipurpose Internet Mail Extensions (MIME) Part Four: Registration Procedures”, BCP 13, RFC 4289, DOI 10.17487/RFC4289, 2005년 12월.
Freed, N., Klensin, J., and T. Hansen, “Media Type Specifications and Registration Procedures”, BCP 13, RFC 6838, DOI 10.17487/RFC6838, 2013년 1월.
<https://www.rfc-editor.org/info/bcp13>
[BCP178]
Saint-Andre, P., Crocker, D., and M. Nottingham, “Deprecating the "X-" Prefix and Similar Constructs in Application Protocols”, BCP 178, RFC 6648, DOI 10.17487/RFC6648, 2012년 6월.
<https://www.rfc-editor.org/info/bcp178>
[BCP35]
Thaler, D., Ed., Hansen, T., and T. Hardie, “Guidelines and Registration Procedures for URI Schemes”, BCP 35, RFC 7595, DOI 10.17487/RFC7595, 2015년 6월.
<https://www.rfc-editor.org/info/bcp35>
[BREACH]
Gluck, Y., Harris, N., and A. Prado, “BREACH: Reviving the CRIME Attack”, 2013년 7월, <http://breachattack.com/resources/BREACH%20-%20SSL,%20gone%20in%2030%20seconds.pdf>.
[Bujlow]
Bujlow, T., Carela-Español, V., Solé-Pareta, J., and P. Barlet-Ros, “A Survey on Web Tracking: Mechanisms, Implications, and Defenses”, DOI 10.1109/JPROC.2016.2637878, In Proceedings of the IEEE 105(8), 2017년 8월.
Barth, A., “HTTP State Management Mechanism”, RFC 6265, DOI 10.17487/RFC6265, 2011년 4월, <https://www.rfc-editor.org/info/rfc6265>.
[Err1912]
RFC Errata, Erratum ID 1912, RFC 2978, <https://www.rfc-editor.org/errata/eid1912>.
[Err5433]
RFC Errata, Erratum ID 5433, RFC 2978, <https://www.rfc-editor.org/errata/eid5433>.
[Georgiev]
Georgiev, M., Iyengar, S., Jana, S., Anubhai, R., Boneh, D., and V. Shmatikov, “The Most Dangerous Code in the World: Validating SSL Certificates in Non-Browser Software”, DOI 10.1145/2382196.2382204, In Proceedings of the 2012 ACM Conference on Computer and Communications Security (CCS '12), pp. 38-49, 2012년 10월.
[HPACK]
Peon, R. and H. Ruellan, “HPACK: Header Compression for HTTP/2”, RFC 7541, DOI 10.17487/RFC7541, 2015년 5월, <https://www.rfc-editor.org/info/rfc7541>.
[HTTP/1.0]
Berners-Lee, T., Fielding, R., and H. Frystyk, “Hypertext Transfer Protocol -- HTTP/1.0”, RFC 1945, DOI 10.17487/RFC1945, 1996년 5월, <https://www.rfc-editor.org/info/rfc1945>.
[HTTP/1.1]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “HTTP/1.1”, STD 99, RFC 9112, DOI 10.17487/RFC9112, 2022년 6월.
[HTTP/2]
Thomson, M., Ed. and C. Benfield, Ed., “HTTP/2”, RFC 9113, DOI 10.17487/RFC9113, 2022년 6월, <https://www.rfc-editor.org/info/rfc9113>.
[HTTP/3]
Bishop, M., Ed., “HTTP/3”, RFC 9114, DOI 10.17487/RFC9114, 2022년 6월, <https://www.rfc-editor.org/info/rfc9114>.
[ISO-8859-1]
International Organization for Standardization, “Information technology -- 8-bit single-byte coded graphic character sets -- Part 1: Latin alphabet No. 1”, ISO/IEC 8859-1:1998, 1998.
[Kri2001]
Kristol, D., “HTTP Cookies: Standards, Privacy, and Politics”, ACM Transactions on Internet Technology 1(2), 2001년 11월, <http://arxiv.org/abs/cs.SE/0105018>.
[OWASP]
The Open Web Application Security Project, <https://www.owasp.org/>.
[REST]
Fielding, R., “Architectural Styles and the Design of Network-based Software Architectures”, Doctoral Dissertation, University of California, Irvine, 2000년 9월, <https://roy.gbiv.com/pubs/dissertation/top.htm>.
[RFC1919]
Chatel, M., “Classical versus Transparent IP Proxies”, RFC 1919, DOI 10.17487/RFC1919, 1996년 3월, <https://www.rfc-editor.org/info/rfc1919>.
[RFC2047]
Moore, K., “MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text”, RFC 2047, DOI 10.17487/RFC2047, 1996년 11월, <https://www.rfc-editor.org/info/rfc2047>.
[RFC2068]
Fielding, R., Gettys, J., Mogul, J., Frystyk, H., and T. Berners-Lee, “Hypertext Transfer Protocol -- HTTP/1.1”, RFC 2068, DOI 10.17487/RFC2068, 1997년 1월, <https://www.rfc-editor.org/info/rfc2068>.
[RFC2145]
Mogul, J., Fielding, R., Gettys, J., and H. Frystyk, “Use and Interpretation of HTTP Version Numbers”, RFC 2145, DOI 10.17487/RFC2145, 1997년 5월, <https://www.rfc-editor.org/info/rfc2145>.
[RFC2295]
Holtman, K. and A. Mutz, “Transparent Content Negotiation in HTTP”, RFC 2295, DOI 10.17487/RFC2295, 1998년 3월, <https://www.rfc-editor.org/info/rfc2295>.
[RFC2324]
Masinter, L., “Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)”, RFC 2324, DOI 10.17487/RFC2324, 1998년 4월 1일, <https://www.rfc-editor.org/info/rfc2324>.
[RFC2557]
Palme, J., Hopmann, A., and N. Shelness, “MIME Encapsulation of Aggregate Documents, such as HTML (MHTML)”, RFC 2557, DOI 10.17487/RFC2557, 1999년 3월, <https://www.rfc-editor.org/info/rfc2557>.
[RFC2616]
Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, “Hypertext Transfer Protocol -- HTTP/1.1”, RFC 2616, DOI 10.17487/RFC2616, 1999년 6월, <https://www.rfc-editor.org/info/rfc2616>.
[RFC2617]
Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S., Leach, P., Luotonen, A., and L. Stewart, “HTTP Authentication: Basic and Digest Access Authentication”, RFC 2617, DOI 10.17487/RFC2617, 1999년 6월, <https://www.rfc-editor.org/info/rfc2617>.
[RFC2774]
Nielsen, H., Leach, P., and S. Lawrence, “An HTTP Extension Framework”, RFC 2774, DOI 10.17487/RFC2774, 2000년 2월, <https://www.rfc-editor.org/info/rfc2774>.
[RFC2818]
Rescorla, E., “HTTP Over TLS”, RFC 2818, DOI 10.17487/RFC2818, 2000년 5월, <https://www.rfc-editor.org/info/rfc2818>.
[RFC2978]
Freed, N. and J. Postel, “IANA Charset Registration Procedures”, BCP 19, RFC 2978, DOI 10.17487/RFC2978, 2000년 10월, <https://www.rfc-editor.org/info/rfc2978>.
[RFC3040]
Cooper, I., Melve, I., and G. Tomlinson, “Internet Web Replication and Caching Taxonomy”, RFC 3040, DOI 10.17487/RFC3040, 2001년 1월, <https://www.rfc-editor.org/info/rfc3040>.
[RFC3864]
Klyne, G., Nottingham, M., and J. Mogul, “Registration Procedures for Message Header Fields”, BCP 90, RFC 3864, DOI 10.17487/RFC3864, 2004년 9월, <https://www.rfc-editor.org/info/rfc3864>.
[RFC3875]
Robinson, D. and K. Coar, “The Common Gateway Interface (CGI) Version 1.1”, RFC 3875, DOI 10.17487/RFC3875, 2004년 10월, <https://www.rfc-editor.org/info/rfc3875>.
[RFC4033]
Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, “DNS Security Introduction and Requirements”, RFC 4033, DOI 10.17487/RFC4033, 2005년 3월, <https://www.rfc-editor.org/info/rfc4033>.
[RFC4559]
Jaganathan, K., Zhu, L., and J. Brezak, “SPNEGO-based Kerberos and NTLM HTTP Authentication in Microsoft Windows”, RFC 4559, DOI 10.17487/RFC4559, 2006년 6월, <https://www.rfc-editor.org/info/rfc4559>.
[RFC5789]
Dusseault, L. and J. Snell, “PATCH Method for HTTP”, RFC 5789, DOI 10.17487/RFC5789, 2010년 3월, <https://www.rfc-editor.org/info/rfc5789>.
[RFC5905]
Mills, D., Martin, J., Ed., Burbank, J., and W. Kasch, “Network Time Protocol Version 4: Protocol and Algorithms Specification”, RFC 5905, DOI 10.17487/RFC5905, 2010년 6월, <https://www.rfc-editor.org/info/rfc5905>.
[RFC6454]
Barth, A., “The Web Origin Concept”, RFC 6454, DOI 10.17487/RFC6454, 2011년 12월, <https://www.rfc-editor.org/info/rfc6454>.
[RFC6585]
Nottingham, M. and R. Fielding, “Additional HTTP Status Codes”, RFC 6585, DOI 10.17487/RFC6585, 2012년 4월, <https://www.rfc-editor.org/info/rfc6585>.
[RFC7230]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing”, RFC 7230, DOI 10.17487/RFC7230, 2014년 6월, <https://www.rfc-editor.org/info/rfc7230>.
[RFC7231]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content”, RFC 7231, DOI 10.17487/RFC7231, 2014년 6월, <https://www.rfc-editor.org/info/rfc7231>.
[RFC7232]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests”, RFC 7232, DOI 10.17487/RFC7232, 2014년 6월, <https://www.rfc-editor.org/info/rfc7232>.
[RFC7233]
Fielding, R., Ed., Lafon, Y., Ed., and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Range Requests”, RFC 7233, DOI 10.17487/RFC7233, 2014년 6월, <https://www.rfc-editor.org/info/rfc7233>.
[RFC7234]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Caching”, RFC 7234, DOI 10.17487/RFC7234, 2014년 6월, <https://www.rfc-editor.org/info/rfc7234>.
[RFC7235]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Authentication”, RFC 7235, DOI 10.17487/RFC7235, 2014년 6월, <https://www.rfc-editor.org/info/rfc7235>.
[RFC7538]
Reschke, J., “The Hypertext Transfer Protocol Status Code 308 (Permanent Redirect)”, RFC 7538, DOI 10.17487/RFC7538, 2015년 4월, <https://www.rfc-editor.org/info/rfc7538>.
[RFC7540]
Belshe, M., Peon, R., and M. Thomson, Ed., “Hypertext Transfer Protocol Version 2 (HTTP/2)”, RFC 7540, DOI 10.17487/RFC7540, 2015년 5월, <https://www.rfc-editor.org/info/rfc7540>.
[RFC7578]
Masinter, L., “Returning Values from Forms: multipart/form-data”, RFC 7578, DOI 10.17487/RFC7578, 2015년 7월, <https://www.rfc-editor.org/info/rfc7578>.
[RFC7615]
Reschke, J., “HTTP Authentication-Info and Proxy-Authentication-Info Response Header Fields”, RFC 7615, DOI 10.17487/RFC7615, 2015년 9월, <https://www.rfc-editor.org/info/rfc7615>.
[RFC7616]
Shekh-Yusef, R., Ed., Ahrens, D., and S. Bremer, “HTTP Digest Access Authentication”, RFC 7616, DOI 10.17487/RFC7616, 2015년 9월, <https://www.rfc-editor.org/info/rfc7616>.
[RFC7617]
Reschke, J., “The 'Basic' HTTP Authentication Scheme”, RFC 7617, DOI 10.17487/RFC7617, 2015년 9월, <https://www.rfc-editor.org/info/rfc7617>.
[RFC7694]
Reschke, J., “Hypertext Transfer Protocol (HTTP) Client-Initiated Content-Encoding”, RFC 7694, DOI 10.17487/RFC7694, 2015년 11월, <https://www.rfc-editor.org/info/rfc7694>.
[RFC8126]
Cotton, M., Leiba, B., and T. Narten, “Guidelines for Writing an IANA Considerations Section in RFCs”, BCP 26, RFC 8126, DOI 10.17487/RFC8126, 2017년 6월, <https://www.rfc-editor.org/info/rfc8126>.
[RFC8187]
Reschke, J., “Indicating Character Encoding and Language for HTTP Header Field Parameters”, RFC 8187, DOI 10.17487/RFC8187, 2017년 9월, <https://www.rfc-editor.org/info/rfc8187>.
[RFC8246]
McManus, P., “HTTP Immutable Responses”, RFC 8246, DOI 10.17487/RFC8246, 2017년 9월, <https://www.rfc-editor.org/info/rfc8246>.
[RFC8288]
Nottingham, M., “Web Linking”, RFC 8288, DOI 10.17487/RFC8288, 2017년 10월, <https://www.rfc-editor.org/info/rfc8288>.
[RFC8336]
Nottingham, M. and E. Nygren, “The ORIGIN HTTP/2 Frame”, RFC 8336, DOI 10.17487/RFC8336, 2018년 3월, <https://www.rfc-editor.org/info/rfc8336>.
[RFC8615]
Nottingham, M., “Well-Known Uniform Resource Identifiers (URIs)”, RFC 8615, DOI 10.17487/RFC8615, 2019년 5월, <https://www.rfc-editor.org/info/rfc8615>.
[RFC8941]
Nottingham, M. and P-H. Kamp, “Structured Field Values for HTTP”, RFC 8941, DOI 10.17487/RFC8941, 2021년 2월, <https://www.rfc-editor.org/info/rfc8941>.
[Sniffing]
WHATWG, “MIME Sniffing”, <https://mimesniff.spec.whatwg.org>.
[WEBDAV]
Dusseault, L., Ed., “HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)”, RFC 4918, DOI 10.17487/RFC4918, 2007년 6월, <https://www.rfc-editor.org/info/rfc4918>.

부록 A. 수집된 ABNF

아래에 수집된 ABNF에서, 목록 규칙은 Section 5.6.1에 따라 확장됩니다.

Accept = [ ( media-range [ weight ] ) *( OWS "," OWS ( media-range [
 weight ] ) ) ]
Accept-Charset = [ ( ( token / "*" ) [ weight ] ) *( OWS "," OWS ( (
 token / "*" ) [ weight ] ) ) ]
Accept-Encoding = [ ( codings [ weight ] ) *( OWS "," OWS ( codings [
 weight ] ) ) ]
Accept-Language = [ ( language-range [ weight ] ) *( OWS "," OWS (
 language-range [ weight ] ) ) ]
Accept-Ranges = acceptable-ranges
Allow = [ method *( OWS "," OWS method ) ]
Authentication-Info = [ auth-param *( OWS "," OWS auth-param ) ]
Authorization = credentials

BWS = OWS

Connection = [ connection-option *( OWS "," OWS connection-option )
 ]
Content-Encoding = [ content-coding *( OWS "," OWS content-coding )
 ]
Content-Language = [ language-tag *( OWS "," OWS language-tag ) ]
Content-Length = 1*DIGIT
Content-Location = absolute-URI / partial-URI
Content-Range = range-unit SP ( range-resp / unsatisfied-range )
Content-Type = media-type

Date = HTTP-date

ETag = entity-tag
Expect = [ expectation *( OWS "," OWS expectation ) ]

From = mailbox

GMT = %x47.4D.54 ; GMT

HTTP-date = IMF-fixdate / obs-date
Host = uri-host [ ":" port ]

IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT
If-Match = "*" / [ entity-tag *( OWS "," OWS entity-tag ) ]
If-Modified-Since = HTTP-date
If-None-Match = "*" / [ entity-tag *( OWS "," OWS entity-tag ) ]
If-Range = entity-tag / HTTP-date
If-Unmodified-Since = HTTP-date

Last-Modified = HTTP-date
Location = URI-reference

Max-Forwards = 1*DIGIT

OWS = *( SP / HTAB )

Proxy-Authenticate = [ challenge *( OWS "," OWS challenge ) ]
Proxy-Authentication-Info = [ auth-param *( OWS "," OWS auth-param )
 ]
Proxy-Authorization = credentials

RWS = 1*( SP / HTAB )
Range = ranges-specifier
Referer = absolute-URI / partial-URI
Retry-After = HTTP-date / delay-seconds

Server = product *( RWS ( product / comment ) )

TE = [ t-codings *( OWS "," OWS t-codings ) ]
Trailer = [ field-name *( OWS "," OWS field-name ) ]

URI-reference = <URI-reference, see [URI], Section 4.1>
Upgrade = [ protocol *( OWS "," OWS protocol ) ]
User-Agent = product *( RWS ( product / comment ) )

Vary = [ ( "*" / field-name ) *( OWS "," OWS ( "*" / field-name ) )
 ]
Via = [ ( received-protocol RWS received-by [ RWS comment ] ) *( OWS
 "," OWS ( received-protocol RWS received-by [ RWS comment ] ) ) ]

WWW-Authenticate = [ challenge *( OWS "," OWS challenge ) ]

absolute-URI = <absolute-URI, see [URI], Section 4.3>
absolute-path = 1*( "/" segment )
acceptable-ranges = range-unit *( OWS "," OWS range-unit )
asctime-date = day-name SP date3 SP time-of-day SP year
auth-param = token BWS "=" BWS ( token / quoted-string )
auth-scheme = token
authority = <authority, see [URI], Section 3.2>

challenge = auth-scheme [ 1*SP ( token68 / [ auth-param *( OWS ","
 OWS auth-param ) ] ) ]
codings = content-coding / "identity" / "*"
comment = "(" *( ctext / quoted-pair / comment ) ")"
complete-length = 1*DIGIT
connection-option = token
content-coding = token
credentials = auth-scheme [ 1*SP ( token68 / [ auth-param *( OWS ","
 OWS auth-param ) ] ) ]
ctext = HTAB / SP / %x21-27 ; '!'-'''
 / %x2A-5B ; '*'-'['
 / %x5D-7E ; ']'-'~'
 / obs-text

date1 = day SP month SP year
date2 = day "-" month "-" 2DIGIT
date3 = month SP ( 2DIGIT / ( SP DIGIT ) )
day = 2DIGIT
day-name = %x4D.6F.6E ; Mon
 / %x54.75.65 ; Tue
 / %x57.65.64 ; Wed
 / %x54.68.75 ; Thu
 / %x46.72.69 ; Fri
 / %x53.61.74 ; Sat
 / %x53.75.6E ; Sun
day-name-l = %x4D.6F.6E.64.61.79 ; Monday
 / %x54.75.65.73.64.61.79 ; Tuesday
 / %x57.65.64.6E.65.73.64.61.79 ; Wednesday
 / %x54.68.75.72.73.64.61.79 ; Thursday
 / %x46.72.69.64.61.79 ; Friday
 / %x53.61.74.75.72.64.61.79 ; Saturday
 / %x53.75.6E.64.61.79 ; Sunday
delay-seconds = 1*DIGIT

entity-tag = [ weak ] opaque-tag
etagc = "!" / %x23-7E ; '#'-'~'
 / obs-text
expectation = token [ "=" ( token / quoted-string ) parameters ]

field-content = field-vchar [ 1*( SP / HTAB / field-vchar )
 field-vchar ]
field-name = token
field-value = *field-content
field-vchar = VCHAR / obs-text
first-pos = 1*DIGIT

hour = 2DIGIT
http-URI = "http://" authority path-abempty [ "?" query ]
https-URI = "https://" authority path-abempty [ "?" query ]

incl-range = first-pos "-" last-pos
int-range = first-pos "-" [ last-pos ]

language-range = <language-range, see [RFC4647], Section 2.1>
language-tag = <Language-Tag, see [RFC5646], Section 2.1>
last-pos = 1*DIGIT

mailbox = <mailbox, see [RFC5322], Section 3.4>
media-range = ( "*/*" / ( type "/*" ) / ( type "/" subtype ) )
 parameters
media-type = type "/" subtype parameters
method = token
minute = 2DIGIT
month = %x4A.61.6E ; Jan
 / %x46.65.62 ; Feb
 / %x4D.61.72 ; Mar
 / %x41.70.72 ; Apr
 / %x4D.61.79 ; May
 / %x4A.75.6E ; Jun
 / %x4A.75.6C ; Jul
 / %x41.75.67 ; Aug
 / %x53.65.70 ; Sep
 / %x4F.63.74 ; Oct
 / %x4E.6F.76 ; Nov
 / %x44.65.63 ; Dec

obs-date = rfc850-date / asctime-date
obs-text = %x80-FF
opaque-tag = DQUOTE *etagc DQUOTE
other-range = 1*( %x21-2B ; '!'-'+'
 / %x2D-7E ; '-'-'~'
 )

parameter = parameter-name "=" parameter-value
parameter-name = token
parameter-value = ( token / quoted-string )
parameters = *( OWS ";" OWS [ parameter ] )
partial-URI = relative-part [ "?" query ]
path-abempty = <path-abempty, see [URI], Section 3.3>
port = <port, see [URI], Section 3.2.3>
product = token [ "/" product-version ]
product-version = token
protocol = protocol-name [ "/" protocol-version ]
protocol-name = token
protocol-version = token
pseudonym = token

qdtext = HTAB / SP / "!" / %x23-5B ; '#'-'['
 / %x5D-7E ; ']'-'~'
 / obs-text
query = <query, see [URI], Section 3.4>
quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
qvalue = ( "0" [ "." *3DIGIT ] ) / ( "1" [ "." *3"0" ] )

range-resp = incl-range "/" ( complete-length / "*" )
range-set = range-spec *( OWS "," OWS range-spec )
range-spec = int-range / suffix-range / other-range
range-unit = token
ranges-specifier = range-unit "=" range-set
received-by = pseudonym [ ":" port ]
received-protocol = [ protocol-name "/" ] protocol-version
relative-part = <relative-part, see [URI], Section 4.2>
rfc850-date = day-name-l "," SP date2 SP time-of-day SP GMT

second = 2DIGIT
segment = <segment, see [URI], Section 3.3>
subtype = token
suffix-length = 1*DIGIT
suffix-range = "-" suffix-length

t-codings = "trailers" / ( transfer-coding [ weight ] )
tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
 "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
time-of-day = hour ":" minute ":" second
token = 1*tchar
token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" )
 *"="
transfer-coding = token *( OWS ";" OWS transfer-parameter )
transfer-parameter = token BWS "=" BWS ( token / quoted-string )
type = token

unsatisfied-range = "*/" complete-length
uri-host = <host, see [URI], Section 3.2.2>

weak = %x57.2F ; W/
weight = OWS ";" OWS "q=" qvalue

year = 4DIGIT

부록 B. 이전 RFC로부터의 변경사항

B.1. RFC 2818로부터의 변경사항

없음.

B.2. RFC 7230로부터의 변경사항

HTTP의 설계 목표, 역사, 아키텍처, 적합성 기준, 프로토콜 버저닝, URI, 메시지 라우팅 및 헤더 필드를 소개하는 섹션들이 여기에 이동되었습니다.

의미론적 적합성에 대한 요구사항은 구현별 실패를 무시하거나 우회할 수 있는 허용으로 대체되었습니다. (Section 2.2)

대체 서비스와 반드시 TCP 기반이 아닌 보안 연결을 고려하여 "http" 및 "https" URI에 대한 출처(origin)와 출처 서버에 대한 권한 있는 접근 설명이 확장되었습니다. (섹션 4.2.1, 4.2.2, 4.3.1, 및 7.3.3)

대상 URI 스킴의 의미를 확인하고 관련 요구사항을 충족하지 않는 요청을 거부하도록 검사하는 명시적 요구사항이 추가되었습니다. (Section 7.4)

미디어 타입, 미디어 범위 및 Expectation의 매개변수는 하나 이상의 후행 세미콜론을 통해 비어 있을 수 있습니다. (Section 5.6.6)

"필드 값(field value)"은 이제 여러 필드 라인이 쉼표로 결합된 후의 값을 가리키도록 정의되었습니다 — 이는 가장 일반적 사용 사례입니다. 단일 헤더 라인의 값을 지칭하려면 "field line value"를 사용하십시오. (Section 6.3)

트레일러 필드의 의미론은 이제 청크 전송 코딩의 세부에 국한되지 않습니다. 트레일러 필드는 발신자가 해당 필드를 트레일러로 생성할 수 있음을 알고 있는 경우에만 트레일러로 생성되도록 더 제한되었고, 수신자가 해당 필드 정의가 병합을 허용하고 병합 방법을 정의하는 경우에만 헤더 섹션으로 병합될 수 있도록 허용됩니다. 그 외의 경우 구현체는 트레일러 필드를 별도로 저장하거나 병합 대신 폐기하도록 권장됩니다. (Section 6.5.1)

요청 URI의 절대형식이 출처 서버에 의해 Host 헤더 필드보다 우선한다는 점이 프록시 처리와 일치하도록 명시적으로 표현되었습니다. (Section 7.2)

Via 필드의 "received-by" 문법은 호스트에 대한 URI 문법 변경으로 인해 RFC 7230에서 확장되었으나, Via에 바람직하지 않은 변경이 포함되어 있었습니다. 단순성을 위해 received-by 산출물에서 uri-host를 제거했으며, 이는 pseudonym 문법으로 포괄될 수 있습니다. 특히 이 변경은 received-by의 호스트 이름에 허용되는 문자 집합에서 쉼표를 제거했습니다. (Section 7.6.3)

B.3. RFC 7231로부터의 변경사항

구현체가 지원해야 하는 최소 URI 길이가 이제 권고됩니다. (Section 4.1)

다음 사항이 명확해졌습니다: 필드 값의 CR 및 NUL은 거부되거나 SP로 매핑되어야 하며, 소비되기 전에 필드 값의 선행 및 후행 공백은 제거되어야 합니다. (Section 5.5)

미디어 타입, 미디어 범위 및 Expectation의 매개변수는 하나 이상의 후행 세미콜론을 통해 비어 있을 수 있습니다. (Section 5.6.6)

HTTP 메시지의 추상 데이터 타입이 도입되어, 메시지 구성요소와 그 의미론을 HTTP 버전 전반에서의 추상으로 정의하고 메시지가 구문 분석된 후의 내용을 반영하도록 했습니다. 이는 콘텐츠(전달되는 것)에 대한 요구사항과 메시지 문법(전달되는 방법)에 대한 요구사항을 구분하기 쉽게 하며 초기 프로토콜 버전의 제한을 향후 HTTP에 고정시키는 것을 피합니다. (Section 6)

"payload" 및 "payload body"라는 용어는 다른 곳에서의 사용과 더 잘 정렬하고 HTTP/2 및 HTTP/3의 프레임 페이로드와의 혼동을 피하기 위해 "content"로 대체되었습니다. (Section 6.4)

"effective request URI"라는 용어는 "target URI"로 대체되었습니다. (Section 7.1)

클라이언트 재시도에 대한 제약이 구현 동작을 반영하도록 완화되었습니다. (Section 9.2.2)

GET, HEAD 및 DELETE의 요청 본문이 상호 운용되지 않는다는 사실이 명확해졌습니다. (섹션 9.3.1, 9.3.2, 및 9.3.5)

PUT에 대한 요청 수식으로 Content-Range 헤더 필드의 사용이 허용되었습니다. (Section 9.3.4)

OPTIONS 메서드 설명에서 Content-Length 설정에 관한 불필요한 요구사항이 제거되었습니다. (Section 9.3.7)

TRACE 응답에서 "message/http" 미디어 타입을 사용하라는 규범적 요구사항이 제거되었습니다. (Section 9.3.8)

호환성을 위해 Expect에 대한 리스트 기반 문법이 복원되었습니다. (Section 10.1.1)

AcceptAccept-Encoding은 응답 메시지에서 허용됩니다; 후자는 [RFC7694]에서 도입되었습니다. (Section 12.3)

"Accept Parameters"(accept-params 및 accept-ext ABNF 산출물)는 Accept 필드 정의에서 제거되었습니다. (Section 12.5.1)

Accept-Charset 필드는 이제 더 이상 권장되지 않습니다. (Section 12.5.2)

Vary 헤더 필드에서 다른 값이 있을 때의 "*" 의미에 대한 설명이 명확해졌습니다. (Section 12.5.5)

범위 단위(range units)는 대소문자 구분 없이 비교됩니다. (Section 14.1)

Accept-Ranges 필드의 사용은 출처 서버에 국한되지 않습니다. (Section 14.3)

리다이렉트된 요청을 생성하는 과정이 명확해졌습니다. (Section 15.4)

301, 302, 307 상태 코드와 더 가깝게 정의되도록 상태 코드 308(이전에는 [RFC7538]에 정의됨)이 추가되었습니다. (Section 15.4.9)

상태 코드 421(이전에는 RFC7540의 섹션에서 정의됨)이 일반적 적용 가능성 때문에 추가되었습니다. 421은 더 이상 휴리스틱하게 캐시 가능하지 않으며, 응답이 연결에 특정하므로(대상 리소스에 특정한 것이 아님) 휴리스틱 캐시 가능성에서 제외됩니다. (Section 15.5.20)

상태 코드 422(이전에는 WEBDAV의 섹션에 정의됨)가 일반적 적용 가능성 때문에 추가되었습니다. (Section 15.5.21)

B.4. RFC 7232로부터의 변경사항

이전의 HTTP 개정판들은 Last-Modified가 강력한 밸리데이터인지 판단하기 위해 임의의 60초 제한을 두었으나, 이는 Date와 Last-Modified 값이 서로 다른 시계 또는 응답 준비 중 약간 다른 시간에 생성될 수 있다는 가능성을 보호하기 위한 것이었습니다. 이 규격서는 이를 완화하여 합리적 재량을 허용합니다. (Section 8.8.2.2)

If-Match 및 If-Unmodified-Since에 관한 에지 케이스 요구사항이 제거되었습니다. 이 요구사항은 변경 요청이 이미 적용되어 검증에 실패할 때 2xx 응답에 밸리데이터를 포함하지 않도록 요구하는 내용이었습니다. (섹션 13.1.113.1.4)

If-Unmodified-Since가 수정 시간 개념이 없는 리소스에는 적용되지 않는다는 사실이 명확해졌습니다. (Section 13.1.4)

선행 조건은 이제 요청 콘텐츠가 처리되기 전에 평가될 수 있으며, 그렇지 않으면 응답이 성공적일 때까지 기다릴 필요가 없습니다. (Section 13.2)

B.5. RFC 7233로부터의 변경사항

range-unit 및 ranges-specifier 문법을 재구성하여 바이트와 기타(확장) 범위 단위 간의 인위적 구분을 단순화하고 줄였습니다. other-range-unit의 중복 문법을 제거하고 범위 단위를 일반적으로 token으로 정의하며 확장 항목을 range-spec의 범위로 옮겼습니다. 이는 쉼표로 구분되는 리스트 문법의 역할을 모든 범위 집합(확장 범위 단위를 포함)에서 명확히 하며, 확장 문법을 range specifiers로 옮김으로써 바이트 범위에 특화된 프로토콜을 별도로 명세할 수 있게 합니다.

이제 확장 메서드에 대해 Range 처리를 정의할 수 있게 되었습니다. (Section 14.2)

부분 PUT을 수행하기 위한 요청 수식자로서 Content-Range 헤더 필드의 사용에 대해 설명했습니다. (Section 14.5)

B.6. RFC 7235로부터의 변경사항

없음.

B.7. RFC 7538로부터의 변경사항

없음.

B.8. RFC 7615로부터의 변경사항

없음.

B.9. RFC 7694로부터의 변경사항

본 규격서는 [RFC7694]에서 정의된 확장을 포함하되, 예제와 배포 고려사항은 생략했습니다.

감사의 글

현 편집자들을 제외하고, 다음 인물들은 HTTP의 초기 측면 및 핵심 명세에 기여한 점에 대해 특별한 인정을 받아야 합니다: Marc Andreessen, Tim Berners-Lee, Robert Cailliau, Daniel W. Connolly, Bob Denny, John Franks, Jim Gettys, Jean-François Groff, Phillip M. Hallam-Baker, Koen Holtman, Jeffery L. Hostetler, Shel Kaphan, Dave Kristol, Yves Lafon, Scott D. Lawrence, Paul J. Leach, Håkon W. Lie, Ari Luotonen, Larry Masinter, Rob McCool, Jeffrey C. Mogul, Lou Montulli, David Morris, Henrik Frystyk Nielsen, Dave Raggett, Eric Rescorla, Tony Sanders, Lawrence C. Stewart, Marc VanHeyningen, and Steve Zilles.

이 문서는 다음을 포함하여 과거 HTTP 명세들에 기여된 여러 공헌을 바탕으로 작성되었습니다: [HTTP/1.0], [RFC2068], [RFC2145], [RFC2616], [RFC2617], [RFC2818], [RFC7230], [RFC7231], [RFC7232], [RFC7233], [RFC7234], and [RFC7235]. 해당 문서들에 포함된 감사의 글은 여전히 적용됩니다.

2014년 이후, 다음 기여자들은 버그 보고, 유의미한 질문 제기, 문안 초안 또는 검토, 이슈 평가 등을 통해 이 명세를 개선하는 데 도움을 주었습니다:

Alan Egerton, Alex Rousskov, Amichai Rothman, Amos Jeffries, Anders Kaseorg, Andreas Gebhardt, Anne van Kesteren, Armin Abfalterer, Aron Duby, Asanka Herath, Asbjørn Ulsberg, Asta Olofsson, Attila Gulyas, Austin Wright, Barry Pollard, Ben Burkert, Benjamin Kaduk, Björn Höhrmann, Brad Fitzpatrick, Chris Pacejo, Colin Bendell, Cory Benfield, Cory Nelson, Daisuke Miyakawa, Dale Worley, Daniel Stenberg, Danil Suits, David Benjamin, David Matson, David Schinazi, Дилян Палаузов (Dilyan Palauzov), Eric Anderson, Eric Rescorla, Éric Vyncke, Erik Kline, Erwin Pe, Etan Kissling, Evert Pot, Evgeny Vrublevsky, Florian Best, Francesca Palombini, Igor Lubashev, James Callahan, James Peach, Jeffrey Yasskin, Kalin Gyokov, Kannan Goundan, 奥 一穂 (Kazuho Oku), Ken Murchison, Krzysztof Maczyński, Lars Eggert, Lucas Pardue, Martin Duke, Martin Dürst, Martin Thomson, Martynas Jusevičius, Matt Menke, Matthias Pigulla, Mattias Grenfeldt, Michael Osipov, Mike Bishop, Mike Pennisi, Mike Taylor, Mike West, Mohit Sethi, Murray Kucherawy, Nathaniel J. Smith, Nicholas Hurley, Nikita Prokhorov, Patrick McManus, Piotr Sikora, Poul-Henning Kamp, Rick van Rein, Robert Wilton, Roberto Polli, Roman Danyliw, Samuel Williams, Semyon Kholodnov, Simon Pieters, Simon Schüppel, Stefan Eissing, Taylor Hunt, Todd Greer, Tommy Pauly, Vasiliy Faronov, Vladimir Lashchev, Wenbo Zhu, William A. Rowe Jr., Willy Tarreau, Xingwei Liu, Yishuai Li, and Zaheduzzaman Sarker.

색인

1 2 3 4 5 A B C D E F G H I K L M N O P R S T U V W X

Authors' Addresses

Roy T. Fielding (editor)
Adobe
345 Park Ave
San Jose, CA 95110
United States of America
Email: fielding@gbiv.com
URI: https://roy.gbiv.com/
Mark Nottingham (editor)
Fastly
Prahran
Australia
Email: mnot@mnot.net
URI: https://www.mnot.net/
Julian Reschke (editor)
greenbytes GmbH
Hafenweg 16
48155 Münster
Germany
Email: julian.reschke@greenbytes.de
URI: https://greenbytes.de/tech/webdav/