메시지는 컨테이너, 엔터티는 화물
HTTP 메시지를 인터넷 운송 시스템의 컨테이너라고 생각한다면, HTTP 엔터티는 메시지의 실질적인 화물이다. HTTP/1.1은 10가지 주요 엔터티 헤더 필드를 정의한다.
- Content-Type : 엔터티에 의해 전달된 객체의 종류
- Content-Length : 전달되는 메시지의 길이나 크기
- Content-Language : 전달되는 객체와 가장 잘 대응되는 자연어
- Content-Encoding : 객체 데이터에 대해 행해진 변형(압축 등)
- Content-Location : 요청 시점을 기준으로, 객체의 또 다른 위치
- Content-Range : 엔터티가 부분 엔터티라면, 이 헤더는 이 엔터티가 전체에서 어느 부분에 해당하는지 정의한다.
- Content-MD5 : 엔터티 본문의 콘텐츠에 대한 체크섬
- Last-Modified : 서버에서 콘텐츠가 생성/수정된 날
- Expires : 엔터티 데이터가 더 이상 신선하지 않은 것으로 간주되기 시작하는 날짜와 시각
- Allow : 허용되는 요청 메서드
- ETag : 인스턴스에 대한 고유 한 검사기. 엔터티 헤더로 정의되어 있지는 않지만 엔터티와 관련된 많은 동작을 위해 중요한 헤더
- Cache-Control : 어떻게 이 문서가 캐시될 수 있는지에 대한 지시자. 엔터티 헤더로 정의되어 있지는 않음.
엔터티 본문
엔터티 본문은 가공되지 않은 데이터만을 담고 있다. 엔터티 본문은 빈 CRLF 줄 다음부터 시작한다. 이것은 콘텐츠가 텍스트, 바이너리, 문서, 이미지, 압축여부, 언어에 상관없이 고정 위치이다.
Content-Length: 엔터티의 길이
Content-Length 헤더는 메시지의 엔터티 본문의 크기를 바이트 단위로 나타낸다. gzip으로 압축된 텍스트 파일이라면 압축된 후의 크기로 표현된다. Content-Length는 메시지가 잘렸는지 감지할 때와 지속 커넥션을 공유하는 메시지를 올바르게 분할하고자 할 때 필요하기 때문에 필수적으로 있어야 한다.
잘림 검출
Content-Length가 없다면 커넥션이 정상적으로 닫힌 것인지 메시지 전송 중에 서버 충돌이 발생한 것인지 구분하지 못하기 때문에 필요하다. 메시지 잘림은 캐싱 프락시 서버에서 특히 취약하다. 캐시가 잘린 메시지를 수신했지만 잘렸다는 것을 인식하지 못했다면 결함이 있는 콘텐츠를 계속 제공할 위험이 있기 때문이다. 때문에 이러한 위험을 줄이고자 캐싱 프락시 서버는 Content-Length 헤더를 가지고 있지 않은 HTTP 본문은 보통 캐시하지 않는다.
잘못된 Content-Length
잘못된 값을 담고 있을 경우 더 큰 피해를 유발할 수 있기 때문에 몇몇 클라이언트/서버/프락시들은 오동작을 탐지하고 교정을 시도한다.
Content-Length와 지속 커넥션
Content-Length는 클라이언트에게 메시지 하나가 어디서 끝나고 다음 시작은 어디인지 알려준다. 클라이언트가 커넥션이 닫힌 위치를 근거로 메시지의 끝을 인식하는 것은 불가능하기 때문에 지속 커넥션에서는 Content-Length가 필수다. Content-Length 헤더 없는 지속 커넥션을 마주하는 경우는 청크 인코딩을 사용할 때인데, 헤더가 생성되는 시점에서 엔터티 전체의 크기를 알 수 없다하더라도 서버는 청크 인코딩을 이용해 엔터티를 잘 정의된 크기의 조각들로 전송할 수 있다.
콘텐츠 인코딩
HTTP는 보안을 강화하거나 압축을 통해 공간을 절약할 수 있도록 엔터티 본문을 인코딩할 수 있게 해준다. 본문 콘텐츠가 인코딩되어 있는 경우, 원본의 길이가 아닌 인코딩된 본문의 길이를 바이트 단위로 정의한다.
엔터티 본문 길이 판별을 위한 규칙
1. 본문을 갖는 것이 허용되지 않는 HTTP 메시지에서는 본문 계산을 위한 Content-Length 헤더가 무시된다.
2. 메시지가 Transfer-Encoding 헤더를 포함하고 있다면 메시지가 커넥션이 닫혀서 먼저 끝나지 않는 이상 엔터티는 '0 바이트 청크'라 불리는 특별한 패턴으로 끝나야 한다.
3. 메시지가 Content-Length 헤더를 갖는다면 본문의 길이를 담는다. Transfer-Encoding 헤더를 갖고 있다면 반드시 Content-Length 헤더는 무시해야 한다. 전송 인코딩은 엔터티 본문을 표현하고 전송하는 방식을 바꿀 것이기 때문이다.
4. 메시지가 'multipart/byteranges' 미디어 타입을 사용하고 엔터티 길이가 정의되지 않았다면 멀티파트 메시지의 각 부분은 각자가 스스로의 크기를 정의할 것이다.
5. 1~4에 해당되지 않는다면 엔터티는 커넥션이 닫힐 때 끝난다.
6. HTTP/1.0 애플리케이션과의 호환을 위해, 엔터티 본문을 갖고 있는 HTTP/1.1 요청은 반드시 유효한 Content-Length 헤더도 갖고 있어야 한다. HTTP/1.1 명세에 따르면, 본문은 있지만 Content-Length가 없는 경우 메시지의 길이를 판별할 수 없다면 400 Bad Request 응답을 보내고, 유효한 Content-Length를 요구하고 싶다면 411 Length Required 응답을 보내도록 조언한다.
엔터티 요약(digest)
불완전한 트랜스코딩 프락시나 버그 많은 중개자 프락시 등의 이유로 메시지의 일부분이 전송 중에 변형되는 일이 일어날 수 있다. 엔터티 본문 데이터에 대한 의도하지 않은 변경을 감지하기 위해 최초 엔터티가 생성될 때 송신자는 데이터에 대한 체크섬을 생성할 수 있고, 수신자는 모든 의도하지 않은 엔터티의 변경을 잡아내기 위해 체크섬으로 기본적인 검사를 할 수 있다.
Content-MD5 헤더는 서버가 엔터티 본문에 MD5 알고리즘을 적용한 결과를 보내기 위해 사용된다. 응답을 처음 만든 서버만이 Content-MD5 헤더를 계산해서 보내며 중간에 있는 프락시와 캐시는 무결성을 지키기 위해 헤더를 변경하거나 추가하지 않는다. MD5는 문서의 위치를 알아내고 중복 저장을 방지하기 위한 해시 테이블의 키로 이용될 수 있다. 하지만 Content-MD5 헤더는 그다지 자주 전송되지는 않는다.
'개발' 카테고리의 다른 글
[99클럽] 알고리즘 TIL: 백준 10798번 세로읽기 - JavaScript (1) | 2025.01.18 |
---|---|
[React] React 19에 추가된 핵심 기능 (13) | 2025.01.16 |
[HTTP 완벽 가이드] 14장 보안 HTTP 14.5~14.9 (0) | 2025.01.15 |
[항해 플러스] 프론트엔드 3기 수료 후기 (4) | 2025.01.11 |
[HTTP 완벽 가이드] 14장 보안 HTTP 14.1~14.4 (0) | 2025.01.10 |