KKanging

[http 완벽 가이드] 15장 엔터티와 인코딩 본문

cs/http

[http 완벽 가이드] 15장 엔터티와 인코딩

천방지축 개발자 2023. 8. 20. 21:45

 

이 내용은 http 완변 가이드란 책을 읽고 정리한 내용입니다.

 

더 자세한 내용이 궁금하시면 책을 직접 읽어보시는 걸 추천합니다.

 

15장 엔터티와 인코딩

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

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

1.1 엔터티 본문

  • 엔터티 본문은 가공되지 않은 데티터만을 담고 있다.
  • 엔터티에 대한 다른 정보들은 모두 헤더에 담겨있다.

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

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

2.1 잘림 검출

  • Content-Length 로 메시지의 끝을 확인한다.
  • 만약 잘못되었거나 청크 인코딩으로 전송되지 않았는데 포함안되어있으면 오류를 발생한다.
  • 캐시는 명시적으로 Content-Length가 없으면 캐싱하지 않는다.

2.2 잘못된 Content-Length

  • 위에서 설명 했듯이 잘못된 Content-Length는 큰 피해를 발생하기에 몇몇 클라이언트,서버 ,프락시 들은 서버가 이러한 오동작을 했는지 탐지하고 교정을 시도한다.

2.3 Content-Length와 지속 커넥션

  • Content-Length은 지속 커넥션을 위해 필수다.
  • 지속 커넥션은 Content-Length을 기준으로 커넥션을 끊기 때문에 없으면 메시지의 끝을 인식못하고 큰 피해를 낳는다.
  • 만약 청크 인코딩으로 전송한다면 Content-Length가 없어도 된다.
    • 청크 인코딩은 밑에 6절에 설명한다.

2.4 콘텐츠 인코딩

  • HTTP는 보안을 강화하거나 압축을 통해 공간을 절약할 수 있도록, 엔터티 본문을 인코딩할 수 있게 해준다.
  • 본문이 인코딩 되어 있으면
  • Content-Length는 인코딩 된 본문의 길이를 표현해야한다.

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

  1. 본문을 갖는 것이 허용되지 않는 특정 타입의 HTTP 메시지에서는, 본문 계산을 위한 Content-Length가 무시된다. 이 경우 Content-Length헤더는 부가정보에 불과하며, 실제 본문 길이를 서술하지 않는다.
  2. 메시지가 Transfer-Encoding헤더를 포함하고 있다면, 메시지가 커넥션이 닫혀서 먼저 끝나지 않는 이상 엔터티는 '0바이트 청크'라 불리는 특별한 패턴으로 끝나야 한다.
  3. 만약 Content-Length헤더 필드와 identity가 아닌 Transfer-Encoding 헤더 필드를 갖고 있는 메시지를 받았다면 반드시 Content-Length헤더를 무시해야. 왜냐하면 전송 인코딩은 엔터티 본문을 표현하고 전송하는 방식을 바꿀 것이기 때문이다.
  4. 메시지가 'multipart/byteranges' 미디어 타입을 사용하고 엔터티 길이가 별도로 전의되지 않았다면, 멀티파트 메시지의 각 부분은 각자가 스스로의 크기를 정의할 것이다
  5. 위의 어떤 규칙에도 해당되지 않는다면, 엔터티는 커넥션이 닫힐 때 끝난다.
  6. HTTP/1.1 애플리케이션과의 호환을 위해, 엔터티 본문을 갖고 있는 HTTP/1.1 요청은 반드시 유효한 Content-Length헤더도 갖고 있어야 한다.

3. 엔터티 요약

  • HTTP는 신뢰가는 TCP/IP 커넥션으로 통신을 하지만 불안전한 트랜스코딩 프락시나 버그 많은 중개자 프락시를 비롯한 여러 가지 이유로 메시지의 일부분이 전송 중에 변형되는 일이 발생한다.
  • •엔터티 본문 데이터 변경을 감지하기 위해, 최초 엔터티가 생성될 때 송신자는 데이터에 대한 체크섬을 생성할 수 있으며 수신자는 엔터티 변경을 잡아내기 위해 체크섬으로 기본적인 검사를 할 수 있다.

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

  • Content-Type은 엔터티 본문의 MIME 타입을 기술한다.
  • 주요 MIME타입의 종류이다.
미디어 타입 설명
text/html HTML 문서
text/plain 플레인 텍스트 문서
image/gif GIF 이미지
image/jpeg JPEG 이미지
audio/x-wav WAV 음향 데이터를 포함
model/vrml 삼차원 VRML 모델
application/vnd.ms-powerpoint 마이크로소프트 파워포인트 프레젠테이션
mulipart/byteranges 여러 부분으로 나뉘는데, 각 부분은 전체 문서의 특정 범위를 담고 있다.
message/http 완전한 HTTP 메시지

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

  • 엔터티의 비트 집합을 텍스트 파일의 글자들로 변환하기 위한 'charset'매개변수는 Content-Type헤더의 내용 유형을 더 자세히 지정한다
Content-Type: text/html; charset=iso-8859-4

4.2 멀티파트 미디어 타입

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

5. 콘텐츠 인코딩

  • HTTP 애플리케이션은 떄떄로 콘텐츠를 보내기 전에 인코딩을 하려고 한다.
  • 큰 HTML 문서를 전송하기 전에 서버는 전송 시간을 줄이기 위해 압축을 할 수 있다.
  • 서버는 허가 받지 않은 제 삼자가 볼 수 없도록 콘텐츠를 암호화하거나 뒤섞어서 보낼 수 있다.

5.1 콘텐츠 인코딩 과정

  1. 웹 서버가 원본 Content-Type과 Content-Length 헤더를 수반한 원본 응답 메시지를 생성한다
  2. 콘텐츠 인코딩 서버가 인코딩된 메시지를 생성한다. 콘텐츠 인코딩 서버는 Content-Encoding헤더를 인코딩된 메시지에 추가하여, 수신 측 애플리케이션이 그것을 디코딩할 수 있도록 한다.
  3. 수신 측 프로그램은 인코딩된 메시지를 받아서 디코딩하고 원본을 얻는다.
  • 본문이 인코딩 되어도 Content-Type 헤더가 메시지에 존재할 수 있고 또한 그래야 한다.
  • Content-Length 헤더는 이제 인코딩된 본문의 길이를 나타낸다는 것을 기억해야 한다.

5.2 콘텐츠 인코딩 유형

  • 콘텐츠 인코딩 토큰들
콘텐츠 인코딩 값 설명
gzip 엔터티에 GNU zip 인코딩이 적용되었음을 의미한다
compress 엔터티에 대해 유닉스 파일 압축 프로그램인 'compress'가 실행되었음을 의미한다
deflate 엔터티가 zlib 포맷으로 압축되었음을 의미한다
identity 엔터티에 어떤 인코딩도 수행되지 않았음을 의미한다. Content-Encoding 헤더가 존재하지 않는다면 이 값인 것으로 간주한다.

5.3 Accept-Encoding 헤더

  • 서버에서 클라이언트가 지원하지 않는 인코딩을 사용하는 것을 막기 위해, 클라이언트는 자신이 지원하는 인코딩의 목록을 Accept-Encoding 요청 헤더를 통해 전달한다.
  • 만약 HTTP 요청에 Accept-Encoding 헤더를 포함하지 않는다면, 서버는 클라이언트가 어떤 인코딩이든 받아들일 수 있는 것으로 간주한다.
  • 클라이언트는 각 인코딩에 Q(quality)값을 매개변수로 더해 선호도를 나타낼 수 있다. 토큰 '*'은 '그 외 모두'를 의미한다.
  • identity 인코딩 토큰은 오직 Accept-Encoding 헤더에만 존재할 수 있고 클라이언트에 의해 다른 콘텐츠 인코딩 알고리즘에 대한 상대적 선호도를 정의하는 데 이용할 수 있다.

6. 전송 인코딩과 청크 인코딩

  • 이전 절에서는 메시지 본문에 적용된 가역적 변환인 콘텐츠 인코딩에 대해 논의했다.
  • 이 절에서는 전송 인코딩에 대해 논의한다.
  • 전송 인코딩 또한 엔터티 본문에 적용되는 가역적 변환이지만, 그들은 구조적인 이유 때문에 적용되는 것이며 콘텐츠의 포맷과는 독립적이다.

Transfer-Encoding 헤더

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

청크 인코딩

  • 청크 인코딩은 메시지를 일정 크기의 청크 여럿으로 쪼갠다.
  • 서버는 각 청크를 순차적으로 보낸다.
  • 청크 인코딩을 이용하면 메시지를 보내기 전에 전체 크기를 알 필요가 없어진다.
  • 청크 인코딩이 전송 인코딩의 한 형태이며 따라서 본문이 아닌 메시지의 속성임에 주목하라.
  • 청크 인코딩을 사용하면 지속 커넥션에서 Content-Length 없이도 마지막 1 청크당 아직 보내질 엔터티의 양을 같이 보내기에 마지막에 보내지는 청크는 0 을 보내고 그것을 확인하고 지속 커넥션은 끝을 알 수 있다.

전송 인코딩 규칙

  • 전송 인코딩의 집합은 반드시 'chunked'를 포함해야 한다. 유일한 예외는 메시지가 커넥션의 종료로 끝나는 경우뿐이다.
  • 청크 전송 인코딩이 사용되었다면, 메시지 본문에 적용된 마지막 전송 인코딩이 존재해야 한다.
  • 청크 전송 인코딩은 반드시 메시지 본문에 한 번 이상 적용되어야 한다.

7. 델타 인코딩

  • 만료된 웹 페이지에 대해 새 페이지 전체를 보내는 대신 변경된 부분만 서버가 보낸다면 클라이언트는더 빨리 페이지를 얻을 수 있다.