본문 바로가기

HTTP

[HTTP] 엔터티와 인코딩

 

HTTP는 메시지가 올바르게 수송되고, 식별되고, 추출되고, 처리되는 것을 보장한다.

  • 객체는 올바르게 식별되어 콘텐츠를 바르게 처리한다. (Content-Type 미디어포맷, Content-Language 헤더)
  • 객체는 올바르게 압축이 풀린다. (Content-Length, Content-Encoding 헤더)
  • 객체는 항상 최신이다. (엔터티 검사기, 캐시 만료 제어)
  • 사용자의 요구를 만족 (Accept 관련 헤더)
  • 네트워크 사이를 빠르고 효율적으로 이동 (범위 요청, 델타 인코딩)
  • 조작되지 않는다. (전송 인코딩 헤더, Content-MD5 체크섬)

#1. 메시지는 컨테이너, 엔터티는 화물

HTTP 메세지를 인터넷 운송 시스템의 컨테이너라고 생각한다면, HTTP 엔터티는 메시지의 실질적인 화물이다.

메시지 엔터티는 엔터티 헤더와 엔터티 본문으로 이루어진다.

 

HTTP/1.1의 10가지 주요 엔터티 헤더 필드

  • Content-Type : 엔터티에 의해 전달된 객체의 종류
  • Content-Length : 전달되는 메시지의 길이나 크기
  • Content-Language : 전달되는 객체와 가장 잘 대응되는 자연어
  • Content-Encoding : 객체 데이터에 대해 행해진 변형(압축 등)
  • Content-Location : 요청 시점을  기준으로 객체의 또 다른 위치
  • Content-Range : 엔터티가 부분 엔터티라면 헤더는 이 엔터티가 전체에서 어느 부분에 해당하는지 정의
  • Content-MD5 : 엔터티 본문의 콘텐츠에 대한 체크섬
  • Last-Modified : 서버에서 이 콘텐츠가 생성 혹은 수정된 날
  • Expires : 엔터티 데이터가 더 이상 신선하지 않은 것으로 간주되기 시작하는 날짜와 시각
  • Allow : 리소스에 대해 어떤 요청 메서드가 허용되는지 (GET과 HEAD)
  • Etag : 인스턴스에 대한 고유한 검사기, 엔터티 헤더로 정의하지 않지만 엔터티와 관련된 많은 동작을 함
  • Cache-Control : 어떻게 문서가 캐시 될 수 있는지에 대한 지시자, 엔터티 헤더로 정의되어 있지는 않음

엔터티 본문

엔터티 본문은 가공되지 않은 데이터만을 담고 있다. 엔터티 본문은 헤더 필드의 끝을 의미하는 빈 CRIF 줄 바로 다음부터 시작한다. 


#2. Content-Length : 엔터티의 길이

Content-Length 헤더는 메시지의 엔터티 본문의 크기를 바이트 단위로 나타낸다. Content-Length 헤더는 메시지를 청크 인코딩으로 전송하지 않는 이상 엔터티 본문을 포함한 메시지에서는 필수적으로 있어야 한다.


잘림 검출

Content-Length가 없다면 클라이언트는 커넥션이 정상적으로 닫힌 것인지 메시지 전송 중에 서버에 충돌이 발생한 것인지 구분하지 못한다. 클라이언트는 메시지 잘림을 검출하기 위해 Content-Length를 필요로 한다.


잘못된 Content-Length

Content-Length가 잘못된 값을 담고 있을 경우 아예 빠진 것보다도 큰 피해를 유발할 수 있다.


Content-Length와 지속 커넥션

Content-Length는 지속 커넥션을 위해 필수다. Content-Length 헤더는 클라이언트에게 메시지 하나가 어디서 끝나고 다음 시작은 어디인지 알려준다.


콘텐츠 인코딩

본문의 콘텐츠가 인코딩되어 있다면 Content-Length 헤더는 인코딩 되지 않은 원본의 길이가 아닌 인코딩 된 본문의 길이를 바이트 단위로 정의한다.


엔터티 본문 길이 판별을 위한 규칙

  • 본문을 갖는 것이 허여되지 않는 특정 타입의 메시지에서는 Content-Length 헤더가 무시된다.
  • 메시지가 Transfer-Encoding 헤더가 포함되어 있다면 '0 바이트 청크' 패턴으로 끝나야 한다.
  • Transfer-Encoding 헤더 존재하지 않으면 본문의 길이, 존재한다면 Content-Length 헤더 무시
  • multipart/byteranges 미디어 타입을 사용하고 엔터티 길이가 정의되지 않았다면 멀티파트 메시지의 각 부분은 각자가 스스로의 크기를 정의한다.
  • 규칙에 해당되지 않는다면 엔터티는 커넥션이 닫힐 때 끝난다.
  • HTTP/1.0 애플리케이션과 호환을 위해 엔터티 본문을 갖고 있는 HTTP/1.1 요청은 반드시 유효한 Content-Length 헤더를 가져야 한다.

#3. 미디어 타입과 차셋(Charset)

클라이언트 애플리케이션은 콘텐츠를 적절히 해독하고 처리하기 위해 MIME 타입을 이용한다. MIME 타입은 주 미디어 타입(텍스트, 이미지, 오디오 등)으로 시작해서 뒤이어 빗금( / ), 그리고 미디어 타입을 더 구체적으로 서술하는 부 타입(subtype)으로 구성된다.

미디어 타입 설명
text/html HTML 문서
text/plain 플레인 텍스트 문서
image/gif GIF 이미지
image/jpeg JPEG 이미지
audio/x-wav WAV음향 데이터를 포함
model/vrml 삼차원 VRML 모델
application/vnd.ms-powerpoint MS 파워포인트 프레젠테이션
multipart/byteranges 본문이 여러 부분으로 나뉨, 부분은 바이트 단위를 담는다.
message/http 본문은 완전한 HTTP 메시지를 담고 있다.

Content-Type 헤더가 원본 엔터티 본문의 미디어 타입을 명시하는 것은 중요하다.


텍스트 매체를 위한 문자 인코딩

엔터티의 비트 집합을 텍스트 파일의 글자들로 변환하기 위해 'charset' 매개변수를 사용한다.

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


멀티파트 미디어 타입

MIME "멀티파트" 이메일 메시지는 서로 붙어있는 여러 개의 메시지를 포함하고 하나의 복합 메시지로 보내진다. 각 구성요소는 자족적으로 자신에 대해 서술하는 헤더를 포함한다.


멀티파트 폼 제출

HTTP 폼을 채워서 제출하면 가변 길이 텍스트 필드와 업로드될 객체는 각각이 멀티파트 본문을 구성하는 하나의 파트가 되어 보내진다. 멀티파트 본문은 여러 다른 종류와 길이의 값으로 채워진 폼을 허용한다.


#4. 콘텐츠 인코딩

 

콘텐츠 인코딩 과정

  1. 웹 서버가 원본 Content-Type과 Content-Length 헤더를 수반한 원본 응답 메시지를 생성
  2. 콘텐츠 인코딩 서버가 인코딩 된 메시지를 생성
  3. 인코딩된 메시지는 Content-Type은 같지만 Conten-Length는 다름, Content-Encoding 헤더를 메시지에 추가
  4. 수신 측 프로그램은 인코딩된 메시지를 받아서 디코딩하고 원본을 얻음

콘텐츠 인코딩의 예


콘텐츠 인코딩 유형

gzip, compress, deflate 인코딩은 전송되는 메시지의 크기를 정보의 손실 없이 줄이기 위한 무손실 압축 알고리즘이다. 이 중 gzip은 가장 효율적이고 많이 쓰인다.

idntity 인코딩 값은 엔터티에 어떤 인코딩도 수행되지 않았음을 의미한다. Content-Encoding 헤더가 존재하지 않는다면 이 값인 것으로 간주된다.


Accept-Encoding 헤더

서버에서 클라이언트가 지원하지 않는 인코딩을 사용하는 것을 막기 위해 클라이언트는 자신이 지원하는 인코딩 목록을 Accept-Encoding 요청 헤더를 통해 전달한다. 클라이언트는 각 인코딩에 Q(quality) 값을 매개변수로 더해 선호도를 나타낼 수 있다.

만약 HTTP 요청에 Accept-Encoding 헤더를 포함하지 않는다면 서버는 클라이언트가 어떤 인코딩이든 받아들일 수 있는 것으로 간주한다.


#5. 전송 인코딩과 청크 인코딩

콘텐츠 인코딩 된 메시지는 단지 메시지의 엔터티 부분만 인코딩한다. 전송 인코딩된 메시지에서는 인코딩은 전체 메시지의 구조를 바꾼다.

콘텐츠 인코딩과 전송 인코딩

 

전송 인코딩은 다른 프로토콜에서도 네트워크를 통한 '안전한 전송'을 위해 존재했다. 


Transfer-Encoding 헤더

전송 인코딩을 제어하고 서술하기 위해 정의된 헤더는 단 두 개뿐이다.

  • Transfer-Encoding : 안전한 전송을 위해 어떤 인코딩이 메시지에 적용되었는지 수신자에게 알려준다.
  • TE : 어떤 확장된 전송 인코딩을 사용할 수 있는지 서버에게 알려주기 위해 요청 헤더에 사용한다.

최신 HTTP 명세는 오직 하나의 전송 인코딩, 청크 인코딩만을 정의했다. TE 헤더는 어떤 형태의 전송 인코딩을 선호하는지 표현하는 Q 값을 갖는다. HTTP/1.1 명세는 청크 인코딩에 대해 Q 값이 0.0을 갖는 것을 금지한다.


청크 인코딩

  • 청크 인코딩은 메시지를 일정 크기의 청크 여럿으로 쪼갠다. 
  • 서버는 각 청크를 순차적으로 보낸다.
  • 청크 인코딩을 이용하면 메시지를 보내기 전에 전체 크기를 알 필요가 없어진다.
  • 청크 인코딩은 전송 인코딩의 한 형태이고 본문이 아닌 메시지의 속성이다. (멀티파트 인코딩은 본문의 속성)

청크 인코딩된 메시지의 구조


전송 인코딩 규칙

전송 인코딩이 메시지 본문에 적용될 때 적용되어야 할 규칙

  • 전송 인코딩의 집합은 반드시 'chunked'를 포함해야 한다.
  • 청크 전송 인코딩이 사용되었다면 메시지 본문에 적용된 마지막 전송 인코딩이 존재해야 한다.
  • 청크 전송 인코딩은 반드시 메시지 본문에 한 번 이상 적용되어야 한다.

전송 인코딩은 HTTP/1.1에서 소개된 비교적 새로운 기능, 전송 인코딩을 구현한 서버는 비 HTTP/1.1 애플리케이션에 전송 인코딩 된 메시지를 보내지 않도록 주의해야 한다.


#6. 시간에 따라 바뀌는 인스턴스

웹 객체는 정적이지 않다. 같은 URL은 시간에 따라 다른 버전의 객체를 가리킬 수 있다.

인스턴스는 시간에 따른 스냅숏이다.

HTTP 프로토콜은 어떤 특정한 종류의 요청이나 응답을 다루는 방법들을 정의하는데 이것은 인스턴스 조작이라고 하며 객체의 인스턴스에 적용한다. 대표적인 두 가지가 범위 요청과 델타 인코딩이다.


#7. 범위 요청과 델타 인코딩

 

범위 요청

HTTP는 클라이언트가 문서의 일부분이나 특정 범위만 요청할 수 있도록 해준다. 범위 요청은 객체의 특정 인스턴스를 클라이언트와 서버 사이에서 교환하는 것이기 때문에 인스턴스 조작의 일종이라는 것에 주의해야 한다. 범위 요청은 오직 클라이언트와 서버가 같은 버전의 문서를 갖고 있을 때만 의미가 있다.


델타 인코딩

델타 인코딩은 객체 전체가 아닌 변경된 부분에 대해서만 통신하여 전송량을 최적화하는 HTTP 프로토콜 확장이다. 델타 인코딩은 전송 시간을 줄일 수 있지만 구현하기가 까다로울 수 있다.

변경이 잦고 많은 사람이 접근하는 페이지에서 델타 인코딩을 지원하는 서버는 자신이 제공하는 페이지가 변경되는 매 순간의 사본을 모두 유지하고 있어야 한다. 그래야 클라이언트가 요청을 보냈을 때 그 클라이언트가 갖고 있는 사본과 최신 사본 간의 차이점을 알아낼 수 있기 때문이다.

문서를 제공하는데 걸리는 시간이 줄어드는 대신 서버는 문서의 과거 사본을 모두 유지하기 위해 디스크 공간을 더 늘려야 한다. 이는 전송량 감소로 얻은 이득을 무의미하게 만든다.


 

참고 자료

  • HTTP완벽가이드 , 인사이트