[HTTP완벽가이드] 15. 엔터티와 인코딩

15. 엔터티와 인코딩

엔터티의 정의와 포맷
엔터티의 컨텐츠 인코딩과 전송 인코딩
항상 최신으로 유지하되, 변경이 일어난 일부분만 가져오게 하는 기법들

엔터티

HTTP 메시지 중, 본문에 해당하는 정보를 담고 있는 부분

엔티티 헤더와 엔티티 본문으로 구성되어 있으며
엔터티 본문은 전달하고자 하는 리소스의 로우 데이터(컨텐츠 인코딩을 안 했다면)이며
엔터티 헤더는 엔터티 본문에 대하 부연설명이 있다.
엔티티 본문은 엔터티 본문의 타입과 관계없이 항상 헤더 다음에 오는 빈 줄(CRLF) 뒤에 온다.

Content-Length

메시지 엔터티 본문의 크기를 바이트 단위로 나타냄
본문이 잘리지 않고 정상적으로 수신되었음을 확인하는 최소한의 정보이며
지속 커넥션에서 전송되는 메시지의 크기와 범위를 알려주는 역할을 한다.
본문이 없는 경우를 제외하고(예 HEAD 메서드) 꼭 있어야 한다. (단, 청크인코딩 제외)

엔티티 요약

Content-MD5 헤더값에는
전송 인코딩 전의 본문(컨텐츠 인코딩이 되었을 수 있음)에 대해 MD5 알고리즘을 적용한 결과가 담김
종단간 무결성을 보장하기 위해 중간에 있는 프록시, 캐시 등의 서버에서는 적용하지 않음
자주 사용되지는 않음

미디어 타입과 Charset

엔티티 본문에 대한 MIME 타입을 기술

텍스트

Content-Type: text/html
Content-Type: text/html; charset=iso-8859-4 # 텍스트 문자 인코딩 등 부가적인 정보를 ; 다음에 매개변수로 넣을 수 있음

멀티파트 미디어 타입

여러 개의 엔터티 정보를 한 번에 전달할 수 있음
구분자가 있어 각각의 엔터티 정보들을 구분할
가변 길이의 폼 제출 시, 또는 범위 응답을 하는 경우 사용

# 폼 데이터인 경우 예시 
# 입력폼 submit-name과 files가 화면에 존재한다. 
Content-Type: multipart/form-data; boundary=AaB03x # 구분자 
--AaB03x # 구분자로 폼 데이터들을 구분 
Content-Disposition: form-date; name="submit-name" # 폼데이터 각각의 정보 
Sally
--AaB03x
Content-Disposition: form-date; name="files"
Content-Type: multipart/mixed; boundary=BbC04y # 파일이 여러 개인 경우 boundary를 추가
--BbC04y
Content-Disposition: form-date; name="files" filename="essayfile.txt" # 각각의 파일을 적음 
Content-Type: text/plain
...contents of essayfile.txt
--BbC04y
Content-Disposition: form-date; name="files" filename="imagefile.gif"
Content-Type: image/gif
...contents of imagefile.gif
--BbC04y
--AaB03x
Content-Type: multipart/x-byteranges; boundary=range-boundary

--[range-boundary]--
Content-Type: text/plain
Content-Range: bytes 0-174/1441

컨텐츠 내용들......
--[range-boundary]--

컨텐츠 인코딩

컨텐츠를 압축하거나 암호화하기 위해 사용
컨텐츠 인코딩 후에는 Content-Length의 값을 인코딩된 본문의 길이로 업데이트
클라이언트가 디코딩할 수 없는 방식으로 컨텐츠를 인코딩하는 것을 방지하기 위해
Allow-Encoding 헤더로 클라이언트가 처리할 수 있는 인코딩 방법을 전달 (만약 없다면, 모두 가능하다고 여김)
이 때, q값으로 처리할 수 있는 방법 간의 선호도를 기록할 수 있음

컨텐츠 타입에 따라 어떤 인코딩 방법은 적용할 수 없을 수 있음
메시지 전체가 아닌 본문에만 적용

전송 인코딩과 청크 인코딩

컨텐츠 타입에 영향을 받지 않고, 메시지 전체에 적용한다.

전송인코딩

데이터의 끝을 알려주어 안심하고 메시지 연결을 끊을 수 있게 하거나
보안을 적용하기 위해 사용(단, SSL과 같은 유명하 전송 계층 보안 방식이 있기 때문에 전송 인코딩 보안은 흔치 않음)

Transfer-Encoding 헤더로 서버가 전송 인코딩을 처리한 방법을 알려주고
TE 헤더로 클라이언트가 처리할 수 있는 전송 인코딩 방법을 알려준다.

청크 인코딩

메시지를 일정 크기의 청크로 쪼개어 순차적으로 보낸다.
메시지 전체 크기를 알 필요가 없고, 청크 하나에 대한 크기 정보를 갖고 있다.
청크 인코딩은 길이 0인 청크로 끝나는 데,
지속 커넥션에서 마지막 청크를 통해 본문이 끝났음을 알 수 있다.

서버는 청크 인코딩을 처리할 수 없는 경우, 411 Length Required로 응답해야 한다.

메시지를 동적으로 생성하면 메시지 본문 전체를 다 보내기 전에는 메시지의 길이를 알 수 없다.
trailer를 사용하면 시작 시점에는 알 수 없는 정보를 보낼 수 있다.

기타

컨텐츠 인코딩 후 전송 인코딩을 하고, 전송 디코딩 후 컨텐츠 디코딩을 한다
서버가 처리할 수 없는 전송인코딩을 받았으 경우, 501 Unimplemented로 응답해야 한다.

시간에 따라 바뀌는 인스턴스

웹 객체는 정적이지 않고, 시간에 따라 바뀐다.
웹 객체 요청 시, 최신 버전인 지 확인하고
최신 버전이 아닌 경우, 변경된 부분만 요청하여 트래픽을 아낄 수 있다.

검사기와 신선도

범위 요청

Range 헤더로 일부만 요청하여 딱 필요한 부분만 받을 수 있다.
전체 응답 중 일부만 실패했을 때, 한 번에 여러 서버에 요청해 데이터를 가져올 때 등에 활용할 수 있다.
Accept-Range 헤더로 서버가 처리할 수 있는 범위의 단위를 알려준다.

델타 인코딩

객체 전체가 아닌 변경된 부분만 받아와서 전송량을 최적화하는 방법
A-IM 헤더로 클라이언트가 처리할 수 있느 델타 방법을 할려주고
IM 헤더로 서버가 적용하 델타 방법을 알려준다.
구현하기 까다롭고, 델타를 확인하기 위해 각각의 버전을 알아야 하므로
디스크 공간이 더 많이 든다.
이는 전송량 최적화의 장점을 무의미하게 만든다.