Chapter 15 - 엔터티와 인코딩

📌 읽으면서 밑줄친 내용 그대로 옮겨 적음. *이 붙은 문장은 생각.
  • HTTP 메시지를 인터넷 운송 시스템의 컨테이너라고 생각한다면, HTTP 엔터티는 메시지의 실질적인 화물이다.
  • 엔터티 본문은 가공되지 않은 데이터만을 담고 있다.
  • 엔터티 본문은 헤더 필드의 끝을 의미하는 빈 CRLF 줄 바로 다음부터 시작한다.
  • Content-Length 헤더는 메시지의 엔터티 본문의 크기를 바이트 단위로 나타낸다.
  • Content-Length는 서버 충돌로 인해 메시지가 잘렸는지 감지하고자 할 때와 지속 커넥션을 공유하는 메시지를 올바르게 분할하고자 할 때 필요하다.
  • 클라이언트는 메시지 잘림을 검출하기 위해 Content-Length를 필요로 한다.
    • 어떻게?
  • 엔티티 본문의 길이와 끝나는 위치를 바르게 판별하는 상황별 규칙
    1. 본문을 갖는 것이 허용되지 않는 특정 타입의 HTTP 메시지에서는, 본문 계산을 위한 Content-Length 헤더가 무시된다.
    2. 메시지가 Transfer-Encoding 헤더를 포함하고 있다면, 메시지가 커넥션이 닫혀서 먼저 끝나지 않는 이상 엔터티는 '0바이트 청크'라 불리는 특별한 패턴으로 끝나야 한다.
    3. 메시지가 Content-Length 헤더를 갖는다면(그리고 메시지 유형이 엔터티 본문을 허용한다면), Transfer-Encoding 헤더가 존재하지 않는 이상 Content-Length 값은 본문의 길이를 담게 된다.
    4. 메시지가 'multipart/byteranges' 미디어 타입을 사용하고 엔터티 길이가 별도로 정의되지 않았다면(Content-Length 헤더로), 멀티파트 메시지의 각 부분은 각자가 스스로의 크기를 정의할 것이다.
    5. 위의 어떤 규칙에도 해당되지 않는다면, 엔터티는 커넥션이 닫힐 때 끝난다.
    6. HTTP/1.0 애플리케이션과의 호환을 위해, 엔터티 본문을 갖고 있는 HTTP/1.1 요청은 반드시 유효한 Content-Length 헤더도 갖고 있어야 한다(서버가 HTTP/1.1과 호환된다고 알려져 있지 않다면).
  • HTTP가 일반적으로 TCP/IP와 같이 신뢰할 만한 전송 프로토콜 위에서 구현됨에도 불구하고, 불완전한 트랜스코딩 프락시나 버그 많은 중개자 프락시를 비롯한 여러가지 이유로 메시지의 일부분이 전송 중에 변형되는 일이 일어난다. 엔터티 본문 데이터에 대한 의도하지 않은(혹은 달갑지 않은) 변경을 감지하기 위해, 최초 엔터티가 생성될 때 송신자는 데이터에 대한 체크섬을 생성할 수 있으며, 수신자는 모든 의도하지 않은 엔터티의 변경을 잡아내기 위해 그 체크섬으로 기본적인 검사를 할 수 있다.
  • Content-MD5 헤더는, 콘텐츠 인코딩의 적용은 끝났지만 전송 인코딩은 아직 적용하지 않은 엔터티 본문에 대한 MD5를 담고 있다.
  • Content-Type 헤더 필드는 엔터티 본문의 MIME 타입을 기술한다.
  • Content-Type의 값은 인터넷 할당 번호 관리기관(Internet Assigned Numbers Authority, IANA)에 등록된 표준화된 MIME 타입이다.
  • Content-Type 헤더는 내용 유형을 더 자세히 지정하기 위한 선택적인 매개변수도 지원한다. 엔터티의 비트 집합을 텍스트 파일의 글자들로 변환하기 위한 'charset' 매개변수가 그 대표적인 예이다.
  • 서버에서 클라이언트가 지원하지 않는 인코딩을 사용하는 것을 막기 위해, 클라이언트는 자신이 지원하는 인코딩의 목록을 Accept-Encoding 요청 헤더를 통해 전달한다.
    • 클라이언트는 각 인코딩에 Q(quality) 값을 매개변수로 더해 선호도를 나타낼 수 있다.
  • Transfer-Encoding 헤더
    • Transfer-Encoding: 안전한 전송을 위해 어떤 인코딩이 메시지에 적용되었는지 수신자에게 알려준다.
    • TE: 어떤 확장된 전송 인코딩을 사용할 수 있는지 서버에게 알려주기 위해 요청 헤더에 사용한다.
  • 청크 인코딩은 메시지를 일정 크기의 청크 여럿으로 쪼갠다. 서버는 각 청크를 순차적으로 보낸다. 청크 인코딩을 이용하면 메시지를 보내기 전에 전체 크기를 알 필요가 없어진다. 본문이 동적으로 생성됨에 따라, 서버는 그중 일부를 버퍼에 담은 뒤 그 한 청크를 그것의 크기와 함께 보낼 수 있다. 본문 전체를 모두 보낼 때까지 이 단계를 반복한다.
  • 델타 인코딩은 객체 전체가 아닌 변경된 부분에 대해서만 통신하여 전송량을 최적화하는, HTTP 프로토콜의 확장이다.
  • 델타 인코딩은 전송 시간을 줄일 수 있지만 구현하기가 까다로울 수 있다.

알게된 점

  • 멀티파트 폼을 제출할 때의 엔터티 본문
    • 이전까지는 key: value 형태로 전송하는 줄 알았음
  • 청크 인코딩
  • 델타 인코딩

관련해서 같이 이야기 나누고 싶은 점

  • Content-Length 자주 쓰시나요? 용도로 봐서는 검증 단계에서 주로 쓰일 것 같은데, 로직에서 이를 체크하는 걸 써본 적은 없고 응답값 잘 나올 때 확인 용도로 가끔 쓰는 편이라서요. (= 잘 안 쓴다는 뜻..)
  • https://stackoverflow.com/questions/44602192/how-to-use-urlsessionstreamtask-with-urlsession-for-chunked-encoding-transfer
    • 스트리밍 관련해서 쓰이나봅니다. 안해봐서 신기하네요.