[HTTP] 엔티티와 인코딩
2021. 11. 1. 21:37
엔티티와 인코딩
[TOC]
- HTTP가 보장하는 것
- 객체는 올바르게 식별되므로 브라우저나 다른 클라이언트는 콘텐츠를 바르게 처리할 수 있다.
- 객체는 올바르게 압축이 풀릴것이다.
- 객체는 항상 최신이다.
- 사용자의 요구를 만족할 것이다
- 네트워크 사이를 빠르고 효율적으로 이동할 것이다.
- 조작되지 않고 온전하게 도착할 것이다.
- 위의 것들을 모두 보장하기 위해 HTTP는 콘텐츠를 나르기 위한 잘 라벨링된 엔티티를 사용함
- 이번 장 포인트
- HTTP 데이터를 담는 컨테이너인 HTTP메시지 엔티티 포맷과 동작방식
- 어떻게 HTTP가 엔티티 본문의 크기를 기술하며, 크기를 측정하기 위해 HTTP가 무엇을 요구하는지
- 클라이언트가 콘텐츠를 바르게 처리할 수 있도록 제공되는 엔티티 헤더들
- 디코딩 가능한 콘텐츠 인코딩전송 인코딩, 청크 인코딩
- 태그, 라벨, 시간, 체크섬
- 콘텐츠의 버전 번호처럼 동작하는 검사기들
- 객체를 최신으로 유지하기 위해 설계된 HTTP 헤더 필드들
- 데이터를 재개하고 싶을 때의 요청방식
15.1 메시지는 컨테이너, 엔티티는 화물
- HTTP 메시지를 인터넷 운송 시스템의 컨테이너라고 생각한다면, HTTP 엔티티는 메시지의 실질적인 화물이다.
- '실제로' 사용자에게 필요한 정보라는 의미
- HTTP 엔티티 헤더는 3장에서 자세하게 다뤘었다.
15.1.1 엔티티 본문
- 엔티티 본문은 가공되지 않은 데이터만 담고 있다.
- 가공된 데이터는 헤더에 담겨있음
- 가공되어 있지 않기 때문에 정보를 헤더에 담을 필요가 있다.
- 엔티티 본문은 헤더 필드의 끝을 의미하는 빈 CRLF 줄 바로 다음부터 시작한다.
15.2 Content-Length : 엔티티의 길이
- Content-Length 헤더는 메시지의 엔티티 본문의 크기를 바이트 단위로 나타냄
- 어떻게 인코딩 되었든 상관없이 크기를 표현할 수 있음
- 메시지를 청크 인코딩으로 전송하지 않는 이상, 엔티티 본문을 포함한 메시지에서는 필수적으로 있어야함
15.2.1 잘림 검출
- Content-Length가 있어야 커넥션이 정삭적으로 닫힌 것인지 전송 중에 서버에 충돌이 발생한 것인지 구분가능하다.
- 메시지 잘림은 캐싱 프록시 서버에 특히 취약함
- 잘린 메시지를 캐시하는 위험을 줄이기 위해, 캐싱 프록시 서버는 명시적으로 Content-Length 헤더를 갖고 있지 않은 HTTP 본문은 보통캐시하지 않음
15.2.2 잘못된 Content-Length
- Content-Length가 잘못된 값을 담고 있을 경우 아예 빠진 것보다도 큰 피해를 유발할 수 있음
- HTTP/1.1 사용자 에이전트는 잘못된 길이를 받고 그 사실을 인지했을 때 사용자에게 알려주게 되어있음
- *추가조사 해보기 *
15.2.3 Content-Length와 지속 커넥션(Persistent Connection)
- Content-Length는 지속 커넥션을 위해 필수다.
- Content-Length 헤더는 클라이언트에게 메시지 하나가 어디서 끝나고 다음 시작은 어디인지 알려줌
- 청크 인코딩을 사용하는 경우를 제외하고는 필수적인 상황이다. (지속 커넥션에서)
15.2.4 콘텐츠 인코딩
- HTTP는 보안을 강화하거나 압축을 통해 공간을 절약할 수 있도록, 엔티티 본문을 인코딩할 수 있게 해준다.
- 만약 본문의 콘텐츠가 인코딩되어 있다면, Content-Length 헤더는 인코딩되지 않은 원본의 길이가 아닌 인코딩된 본문의 길이를 바이트 단위로 정의함
15.2.5 엔티티 본문 길이 판별을 위한 규칙
- 엔티티 본문의 길이와 끝나는 위치를 바르게 판별하는 상황별 규칙
- 본문을 갖는 것이 허용되지 않는 특정 타입의 HTTP 메시지에서는, 본문 계산을 위한 Content-Length 헤더가 무시됨
- 이런 메시지의 Content-Length는 실제 본문 길이를 서술하지 않음
- 가장 중요한 예시는 HEAD 응답이다.
- 본문이 없어야 한다.
- 메시지가 Transfer-Encoding 헤더를 포함하고 있다면, 메시지가 커넥션이 닫혀서 먼저 끝나지 않는 이상 엔티티는 '0바이트 청크'라 불리는 특별한 패턴으로 끝나야함
- 추후 전송 인코딩과 청크 인코딩 부분에서 다룰 예정
- Content-Length 헤더를 갖는다면, Transfer-Encoding 헤더가 존재하지 않는 이상 본문의 값을 담는다.
- 메시지가 'multipart/byteranges' 미디어타입을 사용하고 엔티티 길이가 별도로 정의되지 않았다면, 멀티파트 메시지의 각 부분은 각자가 스스로의 크기를 정의함
- 위의 어떤 규칙도 해당하지 않는다면, 엔티티는 커넥션이 닫힐 때 끝남
15.4 미디어 타입과 차셋(Charset)
- Content-Type 헤더 필드는 엔티티 본문의 MIME 타입을 기술한다.
미디어 타입 | 설명 |
---|---|
text/html | 엔티티 본문은 HTML 문서 |
text/plain | 엔티티 본문은 플레인 텍스트 문서 |
image/gif | 엔티티 본문은 GIF 이미지 |
image/jpeg | 엔티티 본문은 JPEG 이미지 |
audio/x-wav | 엔티티 본문은 WAV 음향 데이터를 포함 |
model/vml | 엔티티 본문은 삼차원 VRML 모델 |
application/vnd.ms-powerpoint | 엔티티 본문은 마이크로소프트 파워포인트 프레젠테이션 |
multipart/byteranges | 엔티티 본문은 여러 부분으로 나뉘는데, 각 부분은 전체 문서의 특정 범위를 담고 있다. |
message/http | 엔티티 본문은 오나전한 HTTP 메시지를 담고있다. |
15.5. 콘텐츠 인코딩
- HTTP 어플리케이션은 때때로 콘텐츠를 보내기 전에 인코딩을 하려고 한다.
- 큰 HTML 문서를 전송하기 전에 서버는 전송시간을 줄이기 위해 압출을 할 수있다.
- 서버는 허가받지 않은 제 3자가 볼 수 없도록 콘텐츠를 암호화하거나 뒤섞어서 보낼 수도 있다.
- 보통 발송하는 쪽에서 콘텐츠에 적용함
15.5.1 콘텐츠 인코딩 과정
- 웹 서버가 원본 Content-Type과 Content-Length 헤더를 수반한 원본 응답메시지 생성
- 콘텐츠 인코딩 서버가 인코딩된 메시지 생성
- Type은 같지만 Length가 다름
- Content-Encoding 헤더를 인코딩된 메시지에 추가해 디코딩 할 수 있게 한다.
- 수신 측 프로그램은 인코딩된 메시지를 받아서 디코딩하고 원본을 얻음
15.5.2 콘텐츠 인코딩 유형
- HTTP는 몇가지 표준 콘텐츠 인코딩 유형을 정의하고 확장 인코딩으로 인코딩을 추가하는 것도 허용함
콘텐츠 인코딩 값 | 설명 |
---|---|
gzip | 엔티티에 GNU zip 인코딩이 적용되었음을 의미한다. |
compress | 엔티티에 대해 유닉스 파일 압축 프로그램인 compress가 실행되었음을 의미 |
deflate | 엔티티가 zlib 포맷으로 압축되었음을 의미 |
identity | 엔티티에 어떤 인코딩도 수행되지 않았음을 의미 Content-Encoding 헤더가 존재하지 않는다면 이 값인 것으로 간주 |
- gzip이 가장 효율적이고 널리 쓰이는 압축 알고리즘
15.5.3 Accept-Encoding 헤더
- 서버에서 클라이언트가 지원하지 않는 인코딩을 사용하는 것을 막기 위해, 클라이언트는 자신이 지원하는 인코딩 목록을 Accept-Encding 요청 헤더를 통해 전달한다.
- 이 헤더를 포함하지 않는다면 서버는 클라이언트가 어떤 인코딩이든 받아들일 수 있는것으로 간주
15.6 전송 인코딩과 청크 인코딩
- 콘텐츠 인코딩된 메시지는 단지 메시지의 엔티티 부분만 인코딩 한다.
- 전송 인코딩된 메시지에서는 인코딩은 전체 메시지에 대해 적용되어 메시지 자체의 구조를 바꿈
15.6.1 안전한 전송
- 전송 인코딩은 다른 프로토콜에서도 네트워크를 통한 '안전한 전송'을 위해 존재했다.
- HTTP에서 전송된 메시지의 본문이 문제를 일으킬 수 있는 이유는 몇가지 밖에 없다.
- 알 수 없는 크기
- 보안
15.6.2 Transfer-Encoding 헤더
- 전송 인코딩을 제어하고 서술하기 위해 정의된 헤더는 단 두개 뿐이다.
- Transfer-Encoding
- 안전한 전송을 위해 어떤 인코딩이 메시지에 적용되었는지 알려줌
- TE
- 어떤 확장된 전송 인코딩을 사용할 ㅅ ㅜ있는지 서버에게 알려주기 위해 요청헤더에 사용
15.6.3 청크 인코딩
- 청크 인코딩은 메시지를 일정 크기의 청크 여럿으로 쪼갠다.
- 서버는 각 청크를 순차적으로 보낸다.
- 청크 인코딩을 이용하면 메시지를 보내기 전에 전체 크기를 알 필요가 없어진다.
- 청크 인코딩은 전송 인코딩의 한 형태이며 본문이 아닌 메시지의 속성임에 주목하자
- 청크와 지속 커넥션
- 클라이언트와 서버 사이의 커넥션이 지속적이지 않다면, 클라이언트는 자신이 읽고 있는 본문의 크기를 알아야함
- 클라이언트는 서버가 커넥션을 닫을때 까지를 본문으로 간주하고 읽을 것이다.
- 지속커넥션에서는 Content-Length 헤더가 필수다.
- 하지만 동적으로 생성되는 콘텐츠에서 Content-Length를 예측하기 어렵다.
- 이런 경우에 청크 인코딩은 서버가 본문을 여러 처으로 쪼개 보낼 수 있게 해줌으로써 해결책을 제시함
- 크기가 0인 청크를 끝으로 인식할 때까지 계속 청크를 보냄
15.6.4 콘텐츠와 전송 인코딩의 조합
- 콘텐츠 인코딩과 전송 인코딩은 동시에 사용될 수 있음
- 콘텐츠 인코딩 후에 청크로 나눠 데이터 전송이 가능함
15.6.5 전송 인코딩 규칙
- 전송 인코딩이 메시지 본문에 적용될 때, 몇 가지 규칙이 반드시 적용되어야 함
- 전송 인코딩의 집합은 반드시 'chunked'를 포함해야함
- 청크 전송 인코딩이 사용되었다면, 메시지 본문에 적용된 마지막 전송 인코딩이 존재해야함
- 청크 전송 인코딩은 반드시 메시지 본문에 한 번 이상 적용되어야 한다.
15.7 시간에 따라 바뀌는 인스턴스
- 웹 객체는 정적이지 않음
- 시간에 따라 받는 인스턴스는 달라진다.
- HTTP 프로토콜은 어떤 특정한 종류의 요청이나 응답을 다루는 방법들을 정의하는데, 인스턴스 조작이라 한다.
- 대표적인 두가지는 범위 요청과 델타 인코딩
15.8 검사기와 신선도
- 클라이언트가 서버에게 자신이 갖고 있는 버전을 말해주고 검사기를 사용해 자신의 사본 버전이 더 이상 유효하지 않을 때만 사본을 보내달라고 요청 할 수 있다.
- 세 가지 주요 개념
- 신선도
- 검사기
- 조건
15.8.1 신선도
- 서버는 클라이언트에게 얼마나 오랫동안 콘텐츠를 캐시하고 그것이 신선하다고 가정할 수 있는지에 대한 정보를 줄 것이다.
- 서버는 Expires나 Cache-Control 헤더를 통해 이렇나 정보를 제공함
- 이 부분은 7장에서 자세히 다루었음
15.8.2 조건부 요청과 검사기
- 캐시의 사본이 요청되었을 때 그것이 더 이상 신선하지 않다면 캐시는 자신이 갖고 있는 사본을 신선한 것으로 바꿔야할 필요가 있음
- HTTP는 클라이언트에게 리소스가 바뀐 경우메나 사본을 요청하는 조건부 요청 기능을 제공함
- 특정 조건이 참일 때에만 수행됨
- 이 부분도 7장을 다시 살펴보면 된다.
15.9 범위 요청
- 범위 요청을 이용하면, HTTP 클라이언트는 받다가 실패한 엔티티를 일부 혹은 범위로 요청함으로써 다운로드가 중된된 시점에서 재개할 수 있음
Get /bigfile.html HTTP/1.1
Host : www.joes-hardware.com
Range: bytes=4000-
User-Agent: Mozilla/4.61 [en] (WinNt; I)
...
- 이 형식의 범위 요청은, 클라이언트가 처음의 4,000 바이트만 받고 실패했을 때 사용할 수 있음
- Range 헤더는 또한 여러 범위로 요청을 하기위해 사용될 수 있음
15.10 델타 인코딩
- 델타 인코딩은 객체 전체가 아닌 변경된 부분에 대해서만 통신하여 전송량을 최적화하는, HTTP 프로토콜의 확장이다.
- 델타 인코딩은 일종의 인스턴스 조작인데, 어떤 객체의 특정 인스턴스들에 대한 클라이언트와 서버 사이의 정보 교환에 의존하기 때문이다.
'CS > 네트워크' 카테고리의 다른 글
[NETWORK] telnet과 ssh 차이 (0) | 2023.03.09 |
---|---|
OSI 7 Layer (0) | 2021.12.29 |
[HTTP] 기본 인증 (0) | 2021.10.19 |
[HTTP] 클라이언트 식별과 쿠키 (0) | 2021.10.18 |
[HTTP] HTTP 2.0 (0) | 2021.10.17 |