3장 HTTP 정보는 HTTP 메시지에 있다.
HTTP 통신에는 클라이언트에서 서버로 보내는 리퀘스트와 서버에서 클라이언트로 보내는 리스폰스가 있다.
3.1 HTTP 메시지
HTTP에서 교환하는 정보를 HTTP 메시지라고 하고 리퀘스트측 메시지는 리퀘스트 메시지, 리스폰스측 메시지는 리스폰스 메시지라고 한다.
HTTP 메시지는 복수행의 데이터로 구성된 텍스트 문자열이고 크게 구분하면 메시지 헤더와 메시지 바디로 구분되며 개행 문자(CR+LF)로 메시지 헤더와 메시지 바디를 구분한다. 메시지 바디가 항상 존재하는 것은 아님(GET, DELETE등)
- 메시지 헤더: 서버와 클라이언트가 꼭 처리해야 하는 리퀘스트와 리스폰스 내용과 속성등
- 메시지 바디: 꼭 전송되는 데이터 그 자체
3.2 리퀘스트 메시지와 리스폰스 메시지의 구조
리퀘스트 메시지와 리스폰스 메시지의 헤더 내부에는 다음과 같은 데이터로 구성되어 있다.
- 리퀘스트 라인: 리퀘스트에 사용되는 메소드와 리퀘스트 URI와 사용되는 HTTP 버전
- 상태라인: 리스폰스 결과를 나타내는 상태 코드와 설명, 사용하는 HTTP 버전
- 헤더 필드: 리퀘스트와 리스폰스의 여러 조건과 속성들을 나타내는 각종 헤더 필드, 일반 헤더 필드, 리퀘스트 헤더 필드, 리스폰스 헤더 필드, 엔티티 헤더 필드등 4종류가 있다.
- 그 외: HTTP의 헤더 필드에는 RFC에 없는 것도 포함될 수 있다. (서비스마다 임의로 넣어 놓는 것)
3.3 인코딩으로 전송 효율을 높이다
HTTP로 데이터를 전송할 때 인코딩을 실시함으로써 전송 효율을 높일 수 있다.
인코딩을 하면 다량의 액세스를 효율 좋게 처리할 수 있다. 단지, 컴퓨터에서 인코딩 처리를 해야하기 때문에 CPU 등의 리소스는 더 많이 소비하게 된다.
3.3.1 메시지 바디와 엔티티 바디의 차이
- 메시지: HTTP 통신의 기본 단위로 옥텟 시퀀스로 구성되고 통신을 통해서 전송된다.
- 엔티티: 리퀘스트랑 리스폰스의 페이로드로 전송되는 정보로 엔티티 헤더 필드와 엔티티 바디로 구성된다.
HTTP 메시지 바디의 역할은 리퀘스트랑 리스폰스에 관한 엔티티 바디를 운반하는 일이다. 기본적으로 메시지 바디와 엔티티 바디는 같지만 전송 코딩이 적용된 경우에는 엔티티 바디의 내용은 달라진다.
3.3.2 압축해서 보내는 콘텐츠 코딩
보내는 데이터를 압축하기 위해 HTTP에는 콘텐츠 코딩이라는 기능이 구현되어 있다. 콘텐츠 코딩은 엔티티에 적용하는 인코딩이고 엔티티 정보를 유지한채 압축한다. 콘텐츠 코딩된 엔티티는 수신한 클라이언트 측에서 디코딩한다.
주요 콘텐츠 압축
- gzip(GNU zip)
- compress(UNIX의 표준 압축)
- deflate(zlib)
- identity(인코딩 없음)
3.3.3 분해해서 보내는 청크 전송 코딩
HTTP 통신에서는 리퀘스트했었던 리소스 전부에서 엔티티 바디의 전송이 완료되지 않으면 브라우저에 표시되지 않는다. 사이즈가 큰 데이터를 전송하는 경우에 데이터를 분할해서 조금씩 표시할 수 있는데, 이렇게 엔티티 바디를 분할하는 기능을 청크 전송 코딩이라고 부른다.
청크 전송 코딩은 엔티티 바디를 청크로 분해하고 청크 사이즈를 16진수로 사용해서 단락을 표시하고 엔티티 바디 끝에는 “0(CR+LF)”를 기록해둔다.
청크 전송 코딩된 엔티티 바디는 수신한 클라이언트 측에서 원래의 엔티티 바디로 디코딩한다.
3.4 여러 데이터를 보내는 멀티파트
메일처럼 내용, 파일등을 함꼐 보내는 경우 MIME(Multipurpose Internet Mail Extensions)으로 불리는 메일로 텍스트나 영상, 이미지와 같은 데이터를 다루기 위한 기능을 사용하고 있다.
MIME은 이미지 등의 바이너리 데이터를 아스키 문자열에 인코딩하는 방법과 데이터 종류를 나타내는 방법을 규정하고 있다. 이 MIME의 확장 사양에 있는 멀티파트라고 하는 여러 다른 종류의 데이터를 수용하는 방법을 사용하고 있는 것.
HTTP도 멀티파트에 대응하고 있어 하나의 메시지 바디 내부에 엔티티를 여러 개 포함시켜 보낼 수 있고 주로 이미지나 텍스트 파일등을 업로드할 때 사용되고 있다.
멀티파트에는 다음과 같은 것들이 있다.
- multipart/form-data: Web 폼으로부터 파일 업로드에 사용된다.
- multipart/byteranges: 상태코드 206(Partial Content) 리스폰스 메시지가 복수 범위의 내용을 포함하는 때에 사용된다.
- multipart/form-data
Content-Type: multipart/form-data; boundary=AaB03x
--AaB03x
Content-Disposition: form-data; name="field1"
JoeBlow
--AaB03x
Content-Disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain
(file1.txt데이터)
--AaB03x--
- multipart/byteranges
HTTP/1.1 206 Partial Content
Date: Fri, ...
Last_Modified: Fri, 31 Aug ...
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPERATES
--THIS_STRING_SEPERATES
Content-Type: application/pdf
Content-Range: bytes 500-999/8000
...(지정한 범위의 데이터)...
--THIS_STRING_SEPERATES
Content-Type: application/pdf
Content-Range: bytes 7000-7999/8000
...(지정한 범위의 데이터)...
--THIS_STRING_SEPERATES--
HTTP 메시지로 멀티파트를 사용할 때는 Content-Type 헤더 필드를 사용한다.
멀티파트 각각의 엔티티를 구분하기 위해 “boundary” 문자열을 사용한다.
엔티티의 선두에는 “boundary” 문자열 앞에 “—”를 삽입하고 마지막에는 문자열 뒤에 “—”를 삽입해서 마무리한다.
멀티파트는 파트마다 헤더 필드가 포함되고 파트를 내부에 포함할 수도 있다.
3.5 일부분만 받는 레인지 리퀘스트
예전에 인터넷이 느렸을때는 대용량 이미지와 데이터를 다운로드 하기 어려운 문제가 있었다.
이러한 문제를 해결하기 위해서 리줌(resume)이라는 기능이 필요하게 되었다. 리줌을 통해 이전에 다운로드를 한 곳에서부터 다운로드를 재개할 수 있다.
이 기능을 구현하기 위해서는 엔티티의 범위를 지정해서 다운로드 받을 수 있어야 한다. 이와 같이 범위를 지정하여 리퀘스트하는 것을 레인지 리퀘스트(Range Request)라고 한다.
레인지 리퀘스트를 할 때는 Range 헤더 필드를 사용해서 리소스의 바이트 레인지를 지정한다.
Range: bytes = 5001-10000
Range: bytes=5001-
Range: bytes=-3000, 5000-7000
레인지 리퀘스트에 대한 리스폰스는 상태코드 206 Partial Content라는 리스폰스 메시지가 돌아온다.
복수 범위의 레인지 리퀘스트에 대한 리스폰스는 multipart/byteranges로 리스폰스가 돌아온다.
서버가 레인지 리퀘스트를 지원하지 않는 경우에는 200 OK라는 리스폰스 메시지로 완전한 엔티티가 돌아온다.
3.6 최적의 콘텐츠를 돌려주는 콘텐츠 네고시에이션
사용자의 언어에 따라서 각각 영어판 웹 페이지와 한국어판 웹 페이지를 표시하는 구조를 콘텐츠 네고시에이션이라고 부른다. 콘텐츠 네고시에이션은 제공하는 리소스를 언어와 문자 세트, 인코딩 방식 등을 기준으로 판단하고 있다. 판단 기준은 리퀘스트 메시지에 포함된 다음과 같은 리퀘스트 헤더 필드이다.
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
- Content-Language
- 서버 구동형 네고시에이션(Server-driven Negotiation)
- 서버 측에서 콘텐츠 네고시에이션을 하는 방식이다.
- 서버 측에서 리퀘스트 헤더 필드의 정보를 참고해서 자동적으로 처리한다.
- 브라우저가 보내는 정보를 근거로 하기 때문에 유저에게 정말로 적절한 것이 선택되었는지는 모른다.
- 에이전트 구동형 네고시에이션(Agent-driven Negotiation)
- 클라이언트 측에서 콘텐츠 네고시에이션을 하는 방식이다.
- 브라우저에 표시된 선택지 중에서 유저가 수동으로 선택한다.
- 트랜스페어런트 네고시에이션(Transparent Negotiation)
- 서버 구동형과 에이전트 구동형을 혼합한 것이다.
'TIL > 개발' 카테고리의 다른 글
[리팩토링 2판 스터디] 3회차 정리 (0) | 2023.12.16 |
---|---|
그림으로 배우는 Http & Network Basic - 4장 (0) | 2023.12.15 |
Partial Prerendering(PPR)은 어떤 렌더링 방식일까? (0) | 2023.12.10 |
그림으로 배우는 Http & Network Basic - 2장 (0) | 2023.12.06 |
그림으로 배우는 Http & Network Basic - 1장 (0) | 2023.12.06 |