본문 바로가기

Protocol

HTTP Chunked Message를 알아보자

# if 0

두달간의 노예 일상을 이제야 끝나고,,

너무 오랜만에 들여다본 블로그,, 

개발자로 지내고 있지만,, 일하고 싶지는 않은 그런 삶,,

 

갑작스럽게 HTTP 프로토콜을 구현해야할 일이 생겨서,

규격 참고하고 구글링 하며 공부한 주제로 오늘은,, 해볼까 합니다,,

#endif


HTTP 라는 단어는 많이 들어보셨을거라고 생각합니다 

그 중에서, Chunked 라는 단어는 조금 생소할 수도 있는데

규격대로만 생각한다면 그리 어렵지 않은 (구현은 까다로울 겁니다..)

HTTP Chunked Message를 알아보도록 할겁니다,,

 

- 아주아주 간단한 HTTP Protocol 설명

- HTTP Header와 Body를 읽는 방법

- HTTP Chunked Message란 무엇인가


1. HTTP(HyperText Transfer Protocol) Protocol 

Chunked Message(청크 메시지ㅋ)를 알아보기 전에, 기본 개념인 HTTP를 다뤄보려고 한다

인터넷 창을 키고, 어떤 사이트에 들어갈 때 흔히 볼 수 있는 형식이 있다

 

예시) http://www.mutpp.tistory.com 

 

여기서 사용하는 http가 그 HTTP 맞습니다....

약자를 풀어보면, HyperText라는 것을 전송하는 프로토콜인데,

Hyper Text는

 

그냥 Text라고만 이해하고 넘어가자,, 

쉽게 생각하면, 텍스트를 전송하기 위한 프로토콜이다~ 이말이다

 

위키백과를 참고하면, (한번 다 읽어보는걸 추천)

위키백과: HTTP(HyperText Transfer Protocol, 문화어: 초본문전송규약, 하이퍼본문전송규약)는 W3 상에서 정보를 주고받을 수 있는 프로토콜이다. 주로 HTML 문서를 주고받는 데에 쓰인다. 주로 TCP를 사용하고 HTTP/3 부터는 UDP를 사용하며, 80번 포트를 사용한다. 1996년 버전 1.0, 그리고 1999년 1.1이 각각 발표되었다.
HTTP는 클라이언트와 서버 사이에 이루어지는 요청/응답(request/response) 프로토콜이다. 예를 들면, 클라이언트인 웹 브라우저가 HTTP를 통하여 서버로부터 웹페이지(HTML)나 그림 정보를 요청하면, 서버는 이 요청에 응답하여 필요한 정보를 해당 사용자에게 전달하게 된다. 이 정보가 모니터와 같은 출력 장치를 통해 사용자에게 나타나는 것이다.
HTTP를 통해 전달되는 자료는 http:로 시작하는 URL(인터넷 주소)로 조회할 수 있다.

 

위키백과를 조금만 정리해보자면,

- W3 (흔히 쓰는 WWW) 상에서 정보를 주고 받을 수 있는 프로토콜

   → 인터넷에서 우리가 보고 있는! 정보를 보여줄 수 있고

- TCP 또는 UDP 사용, HTTP 포트는 80번 포트 사용

- HTTP 메시지를 보내는 Server와 Client가 있음

- http:로 시작하는 인터넷 주소에서 확인할 수 있음

 

여기까지만 알고 넘어가면 청크 메시지도 이해할 수 있다

원래 규격이나 프로토콜은 아 그런게 있구나~ 라고 배경지식만 가져도 

이미 반은 읽은거나 다름 없다 ㅋ

더 자세한 내용은 RFC 규격을 참고하는게 좋다 (첨부링크 참고)

 

2. HTTP Header와 Body를 읽는 방법

(1) 왜 Header와 Body를 사용할까?

HTTP 헤더(header)와 바디(body)란 그렇다면 무엇인가...

말 그대로 머리와 몸으로 분리 되어 있는 구조를 의미하는데,

서버와 클라이언트의 HTTP 통신 메시지를 예를 들어보자면,

 

HTTP 통신 예시(이렇게 깔끔할 수가)

위 그림과 같은데, 자세히보면 클라이언트와 서버의 메시지 형식이 조금 다른 것을 볼 수 있다

하지만! 헤더와 바디의 구성으로 되어있는건 동일하다

 

근데 그냥 헤더랑 바디 나눌 필요 없이 한번에 보내면 안되나..?;;;; 라는 생각이 들 수 있는데

왜 구분할까를 TCP 소켓 통신을 예로 들어서 설명하자면, ( 지극히 나의 생각이다 )

 

TCP 통신 Flow

위 그림은 아마 어디서 한번쯤은 봤을 법한 그림이다

TCP 통신시에 실제 운영체제를 통해 메시지를 전송할 때, send() ( 또는 write() )를 통해 보내고,

recv() ( 또는 read() )를 통해 메시지를 수신하는데,

이 때 보낼/받을 메시지의 크기를 파라미터로 넣어주게 되어 있다

내가 보낼 때 8192만큼 보낼래~~ 해도 받는 쪽에서는 9000만큼, 2000만큼 읽을 수 있다

상대방이 얼만큼 보내고 받을지 모른다는 얘기

 

크기가 큰 (ex. 동영상/웹페이지 등등) 메시지를 보낼 때, 한번에 받을 수 없을 수도 있을테고

얼만큼 읽어야하는지도 모른다! 라는 것이다

그래서 헤더에 내가 보낼 메시지(바디)의 크기는 이만큼이야~를 먼저 알려주고 (Content-Length)

그 후에 보낼 데이터를 보내는 용도로 사용된다 (머리부터 들이민다)

 

 

(2) Request 메시지 

 

* Request 메시지 형식

{HEADER} CRLF
CRLF
{BODY}

위에서 설명한 헤더와 Body는 CRLF CRLF 라는 것으로 구분되어있다

 

cf) CRLF 의미 (새줄 문자)

- CR: Carriage Return (\r)

- LF: Line Feed (\n)

HTTP 메시지를 보면 끝에 공백으로 보이는 부분이 있을 것이다 바로 그것이다

 

헤더만 좀더 자세히 뜯어보면 아래와 같다

 

* Request 메시지 - Header 구성

/* Header 구성임 */
1. {METHOD 이름} SP {요청하는 URI} SP {HTTP Version} CRLF
2. {Header 1번째} CRLF
N. {Header N번째} CRLF
CRLF
/* ~ Header 구성임 */
1. {BODY}

cf) SP 의미

SP: Space (" ")  띄어쓰기임ㅋ

 

cf) Request Line

1번째 줄에 있는 → method + " " + 요청하는 URI + " " + HTTP 프로토콜 버전 

요 구성을 Request Line이라고 한다

 

HTTP 메시지는 예시를 보면 이해가 잘 될 것이다

 

세상에는 좋은 자료가 참 많다

( 사실 Method의 종류에는 뭐가 있는지 (ex. POST, GET 등등), VESION은 뭔지 

헤더에는 어떤 종류가 있고, 필수로 들어가야하는 항목 (ex. Content-Length)  등등에 대해

HTTP에서는 얘기할게 너~~~~무 많으니 생략한다.)

 

 

(3) Response 메시지

 

* Response 메시지 형식

1. {HTTP 버전} SP {Status Code} SP {Status Message} CRLF
2. {Header 1번째} CRLF
N. {Header N번째} CRLF
CRLF
1. {Body 있거나 없거나}

 

cf) Status Line

Request의 첫번째 줄에 있는 Request Line이 있듯이,

Response의 첫번째 줄은 Status Line이라고 한다

 

Response도 예시를 보면 아래와 같다

Response 메시지

Response를 서버로부터 수신하면, Status Line에 있는 상태 값과 에러 코드를 보고

이후 로직을 결정할 수 있다

(200 OK 이면 잘 처리했다고 로그를 남긴다던가,, 401 에러면 Digest 인증 헤더를 붙여서 다시 보낸다던가)

 

세상에 있는 HTTP error 코드는 규격에 정의가 되어있으니, 걱정안해도 된다

(첨부파일 참고)

3. HTTP Chunked Message

포스팅 주제였는데 이제야 등장한 Chunked 메시지..

 

예쓰,,덩어리....

chunk라는 단어 자체의 뜻은 "덩어리"를 뜻한다

HTTP Body로 오는 메시지들이 덩어리된 형태로 오는 것을 의미한다

 

Body에 있는 메시지가 지속적으로 와야하는 경우나 (ex. 세션을 유지해야 할 경우)

메시지의 크기가 많이 클 경우에 보통 사용된다고 한다

 

메시지가 크면 클 수록 한번에 보내기에 부담스러울 것이기에..

분할하여 메시지를 보내는 것이다

그러면 어떻게! 나눠서 메시지를 보내고 받을 수 있을까.

 

(1) Chunked Body 메시지 형식

 

청크 메시지는 Header는 똑같이 오고, Body가 나눠져서 오는 메시지인데

차이점은?

 

- 일반 Body 메시지 길이: Header에 있는 Content-Length 헤더에 적혀있음

- 청크 Body 메시지 길이: 각 청크마다 길이가 적혀있음

 

Boby의 길이를 알려주기 위해, Content-Length라는 헤더에 그 값이 있는데,

청크 메시지는 분할돼서 오기 때문에 각 덩어리(ㅋ)마다 길이를 표기를 해준다

 

아래는 예시이다

 

짜잔 (출처는 이미지 클릭)

생각보다 간단하쥬?

Chunk #1만 보면

Chunk #1 예시 (출처는 이미지 클릭)

"27 <CR><LF>"를 자세히 보자.

위에서 헤더와 바디를 보았을 때 두 번의 CRLF로 구분된다라고 설명하였는데,

청크 메시지도 CRLF를 사용하여 청크 헤더와 청크 바디를 구분할 수 있다!

 

그리고, We hole these... 어쩌구에 있는 청크 바디의 글자를 세어보면 27이 아니어서 당황할텐데,

이유는 hex로 표기 되어서 그런거니까 당황하지 말자

(string 형의 hex 문자를 int형으로 바꾸는 것은 참고 자료에 달아놓겠음)

 

또한, 청크 바디 길이는 CRLF의 길이는 제외한 길이다..

 

그리고, Body 부분에 보이는 

 

Transfer-encoding

 Transfer-encoding 헤더는 이제 Chunked로 된 메시지가 올거야 ~~ 를 알려주는 헤더로,

청크 메시지가 오기 전에 볼 수 있다

 

그러면 마지막으로 오는 Chunk 메시지가 언젠가는 올텐데, (안올 수도 있고^^7)

 

Last message

마지막 메시지는 0 임을 표시하고 온다.

 

 

(2) Multipart Type과 Boundary Header

 

앞서 설명했던 HTTP 헤더에는 뒤에 올 바디 메시지의 길이를 명시하는 것 뿐만 아니라

뒤에 올 메시지의 타입은 어떤 것이 오는지에 대해서도 갖고 있다

메시지의 타입을 나타내는 헤더는 → Content-Type 헤더 이다

 

왜 이런게 필요한지는 인코딩과 MIME 개념 설명이 필요하다

 

cf) Content-Type 헤더는 MIME Type에 포함되는 헤더

* MIME(Multipurpose Internet Mail Extensions)

 

보통 많이 봤을 Content-Type은 application/json 같은 타입이다

(아주아주 여러 종류가 있음, 첨부링크 참고)

 

이 Content-Type의 종류 중 하나가 multipart라는 것인데,

어떤 메시지들이 multi로 올 것이니 준비해~~ 라는 역할을 한다

 

엇,,, 그러면 만약 json 메시지도 오고.. XML 메시지도 오고.. 이걸 어떻게 구분할까? 

라는 생각이 들텐데, 그래서 Multipart 메시지는 메시지 part를 구분할 수 있는

"boundary"라는 파라미터를 같이 데리고 다닌다

 

Content-type: multipart/mixed; boundary="simple boundary" 

 

이런 형태로! boundary 파라미터에 있는 "simple boundary"로 메시지가 구분돼 ~~ 라는 뜻

또한, boundary는 MIME 규격에 따르면, "--" 요 하이픈 문자열이 같이 온다

마지막 boundary는 양 옆에 --이 추가되어, "--simple boundary--" 모양이다

 

*MIME 규격 7.2.1 Multipart: The common syntax
The encapsulation boundary is defined as a line consisting entirely of two hyphen characters ("-", decimal code 45) followed by the boundary parameter value from the Content-Type header field.

또한 Boundary 간은 CRLF로 구분하면 된다.. (CRLF 진짜 싫다)

아래는 예시이다

 

Content-type: multipart/{type}; boundary="simple boundary" 

11
--simple boundary 

43
--simple boundary
Content-type:application/json; charset=utf-8

{
	"test": "hi"
}
--simple boundary 

....

 


HTTP 프로토콜은 너무 광범위해서 내가 정리하고 싶은 부분만 정리하기가

너무 힘든 프로토콜이다

아 그냥 이런 개념도 있구나~ 정도만 알고가도 충분한 듯하다

 

좀더 상세한 개념 설명은 다음의 나에게 맡기는걸로

 

 


ko.wikipedia.org/wiki/HTTP

 

HTTP - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. HTTP(HyperText Transfer Protocol, 문화어: 초본문전송규약, 하이퍼본문전송규약)는 W3 상에서 정보를 주고받을 수 있는 프로토콜이다. 주로 HTML 문서를 주고받는 데에

ko.wikipedia.org

tools.ietf.org/html/rfc2616

 

RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1

[Docs] [txt|pdf] [draft-ietf-http...] [Tracker] [Diff1] [Diff2] [Errata] Obsoleted by: 7230, 7231, 7232, 7233, 7234, 7235 DRAFT STANDARD Updated by: 2817, 5785, 6266, 6585 Errata Exist Network Working Group R. Fielding Request for Comments: 2616 UC Irvine

tools.ietf.org

 

developer.mozilla.org/ko/docs/Web/HTTP/Overview

 

HTTP 개요 - HTTP | MDN

HTTP는 HTML 문서와 같은 리소스들을 가져올 수 있도록 해주는 프로토콜입니다. HTTP는 웹에서 이루어지는 모든 데이터 교환의 기초이며, 클라이언트-서버 프로토콜이기도 합니다. 클라이언트-서버

developer.mozilla.org

* HTTP 에러 코드

developer.mozilla.org/ko/docs/Web/HTTP/Status

 

HTTP 상태 코드 - HTTP | MDN

BCD tables only load in the browser HTTP 응답 상태 코드는 특정 HTTP 요청이 성공적으로 완료되었는지 알려줍니다. 응답은 5개의 그룹으로 나누어집니다: 정보를 제공하는 응답, 성공적인 응답, 리다이렉

developer.mozilla.org

* HTTP Chunked 메시지 참고 자료

flylib.com/books/en/1.2.1.149/1/

 

Transfer Encoding and Chunked Encoding | HTTP: The Definitive Guide

flylib.com © 2008-2017. If you may any questions please contact us: flylib@qtcs.net

flylib.com

* String hex to Int

viiiin.tistory.com/66

 

[C++] String to Hex 변환

프로그래밍 중에 텍스트 파일에서 16진수 형태의 문자열을 읽어와서 정수형으로 변환해 줘야 할 경우가 종종 발생합니다. 이러한 경우에 다음과 같은 stringstream 클래스를 사용하면 매우 간단하

viiiin.tistory.com

 

* HTTP Multipart 참고글

qssdev.tistory.com/47

 

HTTP Multipart와 MIME

HTTP multipart request.md HTTP Multipart Multipart는 HTTP를 통해 File을 SERVER로 전송하기 위해 사용되는 Content-type입니다. 간단하게 HTTP(request와 response 둘 다)는 4개로 나눌 수 있..

qssdev.tistory.com

 

* HTTP Content-Type 종류 참고

juyoung-1008.tistory.com/4

 

MIME-Type,Content-Type이란?

MIME이란? MIME이란? Multipurpose Internet Mail Extensions의 약자로 간략히 말씀을 드리면 파일 변환을 뜻한다. MIME는 이메일과 함께 동봉할 파일을 텍스트 문자로 전환해서 이메일 시스템을 통해 전달하기

juyoung-1008.tistory.com

 

* MIME 규격

www.w3.org/Protocols/rfc1341/7_2_Multipart.html

 

RFC1341(MIME) : 7 The Multipart content type

7.2 The Multipart Content-Type In the case of multiple part messages, in which one or more different sets of data are combined in a single body, a "multipart" Content-Type field must appear in the entity's header. The body must then contain one or more "bo

www.w3.org

 

'Protocol' 카테고리의 다른 글

UDP를 알아보자  (0) 2021.07.08
SOAP을 알아보자  (0) 2021.06.10
SMTP를 알아보자  (0) 2020.12.16