2017년 8월 18일 금요일

[HTTP 프로토콜 강좌]#20 HTTP 일반 헤더 II - Transfer-Encoding, Upgrade, Warning, Trailer

이전 시간에 이어 오늘은 General 헤더의 마지막 시간이다.
오늘은 포스팅 글 제목에 있듯이 4개의 헤더를 다룬다.

  1. Transfer-Encoding
  2. Upgrade
  3. Warning
  4. Trailer



1. Transfer-Encoding

먼저 Transfer-Encoding 헤더를 이해하려면, HTTP 의 데이터 전송방식을 이해할 필요가 있다.

HTTP 1.0에서 클라이언트는 자신이 요청한 컨텐츠의 사이즈를 어떻게 알 수 있을까?
HTTP 1.0 은 연결유지 기능이 없기 때문에 TCP 커넥션이 끊어지는 것이 곧 데이터 전송의 완료라고 볼 수 있다.
(HTTP 1.0 에서는 하나의 TCP 커넥션에 하나의 요청만 처리되기 때문에 데이터 전송이 완료되면 커넥션이 끊어진다.)



따라서, HTTP 1.0 에서는 웹서버가 따로 전달하려는 데이터의 사이즈를 알려줄 필요가 없을뿐더러, 클라이언트 역시 데이터를 전달받기 전에 미리 사이즈를 알아야 할 이유가 없다.


하지만 HTTP 1.1에서는 좀 다르다. 바로 연결 유지(persist connection) 때문이다.
HTTP 1.1에서는 기본적으로 연결 유지 기능이 활성화 되어 있다. 하나의 TCP 커넥션에 여러개의 요청이 가능하기 때문에 클라이언트는 요청마다 전달될 컨텐츠의 데이터 사이즈를 미리 알고 있어야 한다. 웹서버가 전달해 주는 컨텐츠의 시작과 끝을 알아야만 해당 요청에 대한 처리가 올바르게 될 수 있기 때문이다.

그래서 HTTP 1.1에서는 Content-Length 라는 헤더로 전달하고자 하는 컨텐츠의 사이즈를 표시한다.

다음은 인기 그룹 트와이스의 이미지를 요청했을 때 서버의 응답헤더 부분이다.


응답헤더에서 볼수 있듯이 웹서버는 클라이언트의 요청 컨텐츠를 전달하기 앞서 Content-Length 헤더를 통해 이미지 사이즈를 먼저 알려준 후 데이터를 전달한다.

앞서 살펴 본 바와 같이 웹서버에서는 다음의 과정으로 데이터를 처리하게 되는데...

  1. 웹서버가 클라이언트의 요청을 받는다. 
  2. 웹서버는 클라이언트에게 전달해 줄 컨텐츠의 사이즈를 먼저 계산한다. 
  3. 계산된 컨텐츠의 전체 사이즈와 함께 데이터를 전달한다. 
바로 2번 과정에서 컨텐츠의 사이즈가 엄청 큰 경우 문제가 발생할 수 있다. 
컨텐츠가 큰 경우 전체 사이즈를 계산하는 과정이 오래 걸리게 되고.. 이는 곧 클라이언트가 느끼는 지연시간에 반영되게 된다. 

컨텐츠 사이즈가 큰 경우에는 이런 방식 보다는 좀 더 효율적인 다른 방식이 필요하다.
그것이 바로 "Chunked" 전송 방식이다. 

Chunked 전송 방식의 개념은 간단하다.
전체 덩어리를 한번에 주지 않고, 조금씩 조금씩 떼어 주는 방식이다. 
웹서버는 Chunked 방식으로 데이터를 전송하는 경우에는 전체 사이즈를 한번에 계산할 필요가 없다. 
일단 자신이 보내려는 덩어리 정도만 먼저 클라이언트에게 알리고 데이터를 보내고.. 그 다음에 또 전송할 덩어리만큼 알리고 보내고.. 글로 표현하자니.. 이거 원.... 
아래 그림을 참고해 보자. 



그림처럼 클라이언트가 트와이스 이미지를 요청하면, 웹서버는 전체 이미지의 부분만 떼어서 전달해 주는 방식이다.  떼어주는 부분의 사이즈만 알려주면 되기 때문에 전체 사이즈를 계산하지 않아도 되어서 기존 전송방식의 단점을 극복한 방식이다. 

컨텐츠의 마지막 부분을 전송하고 나서는 "0" 을 보내어 데이터가 모두 전송되었음을 알린다.



따라서 Chunked 전송방식에는 Content-Length 헤더가 존재하지 않는다. 
아래 Chunked 방식의 HTTP 헤더 내용을 살펴보자. 



  1. Transfer-Encoding: Chunked 를 통해 Chunked 전송방식으로 데이터를 전송할 것을 알린다. 
  2. 이후 데이터 전송시 전송하려는 데이터의 부분적인 사이즈를 16진수로 표시하여 알린 후 실제 데이터를 사이즈만큼 보낸다. 
  3. 위 2번 과정을 반복한다. 
  4. 데이터의 마지막 끝부분에 "0" 을 표시하여 데이터 전송이 완료되었음을 알린다. 
이 과정이 Chunked 전송방식의 전부이다. 

정리하면 Chunked 방식은 전달하려는 컨텐츠의 사이즈가 큰경우 서버의 처리 지연을 보완할수 있는 방법인것이다. 

Transfer-Encoding 헤더는 Chunked 전송방식으로 데이터를 전달하려 할때 주로 사용되는 헤더이며, 값으로는 위 헤더 내용처럼 "Chunked" 를 가지게 된다. 




2. Upgrade

Upgrade 헤더는 클라이언트와 서버간 통신 프로토콜을 바꾸려고 할때 사용하는 헤더이다. 새로운 HTTP 버젼이나 또는 TLS 와 같은 암호화 프로토콜로 변경하려고 하는 경우 Upgrade 헤더를 이용해서 프로토콜을 변경할 수 있다.

다음은 그 예이다.

GET http://www.compay.com/index.html HTTP/1.1
Host: www.company.com
Upgrade: TLS/1.0
Connection: Upgrade

위와 같은 요청을 받으면 서버는 "101 Switching Protocols" 상태 코드를 다음과 같이 전달한다.

HTTP/1.1 101 Switching Protocols
Upgrade: TLS/1.0, HTTP/1.1
Connection: Upgrade

클라이언트의 요청, 그리고 웹서버의 응답헤더 모두에 "Connection: Upgrade" 가 포함되어 있다. 이 부분은 Upgrade 헤더를 사용하면 항상 같이 포함되어 있는 헤더이다. 이유는 클라이언트가 직접 통신하는 대상은 실제 웹서버일수도 있지만, 중간 프록시 서버가 존재하는 경우라면 실제 웹서버가 아니기 때문이다.

클라이언트는 실제 통신하는 대상과 프로토콜 협상을 하기 때문에 Upgrade 헤더가 프록시를 경유하여 직접 통신하지 않는 실제 웹서버나 다른 프록시서버로 전달될 필요가 없다.

따라서 프록시를 경유하여 전달되는 헤더 정보에서 Upgrade 를 제거해야 하는데 이를 위해서는 Connection 헤더가 필요하기 때문이다.
(Connection 헤더에 대해서는 바로 이전 시간에 상세히 다룬바 있다. 여기 를 클릭하여 자세한 내용을 확인할 수 있다.)

"101 Switching Protocols" 상태코드도 Upgrade 헤더에 의한 확인 메시지로 사용된다. 위 응답헤더에서 우리는 TLS 1.0을 통한 HTTP 1.1 로 업그레이드 되었음을 알 수 있다.


3. Warning

Warning 헤더는 캐시서버의 문제점을 사용자에게 알리는 용도로 사용되는 헤더이다. 다음과 같은 형태로 경고코드 및 내용등이 포함되어 진다.

Warning: 110 proxy.com "Response is stale"
             Fri, 31 Dec 2000 10:10:07 GMT

위 내용 처럼, 첫번째 필드는 경고 코드(110), 그리고 다음 필드는 경고코드가 생성된 서버(proxy.com), 그리고 인용부호 안에 메시지(Response is stale)은 일반적인 경고 메시지이다.

추가적으로 마지막 필드의 시간정보는 경고 문구가 만들어진 시간인데, 사실 필수는 아니고 있어도 되고, 없어도 되는 옵션 필드이다.

HTTP 1.1에서 정의하고 있는 경고 코드(Warning Code) 는 다음과 같다.

코드 설명 의미
110 Response is stale 캐시서버가 제공한 컨텐츠가 만료시간을 초과한 오래된 것이다. (아마도 클라이언트가 max-stale 캐시 항목을 사용한것으로 보인다.)
111 Revalidation failed 캐시서버가 제공하려는 컨텐츠의 유효성 체크에 실패했다. (아마도 실제 웹서버와 통신할 수 없는 상태인것 같다.)
112 Disconnection operation 캐시서버가 의도적으로 통신이 끊겼다.
113 Heuristic expiration 캐시서버가 제공하려는 컨텐츠가 아직은 유효한데, 저장된지 24시간 이상 지난 컨텐츠입니다.
199 Miscellaneous warning 임의적인 경고 메시지입니다
214 Transformation applied 캐시서버가 컨텐츠를 임의적으로 수정했습니다.(캐시 저장공간이 넉넉치 않아 이미지 포맷을 변경한것 같습니다.)
299 Miscellaneous persistent warning 경고코드 199와 같은 임의적인 경고메시지인데 좀 상태가 지속되는 것으로 보입니다.




4. Trailer

클라이언트와 서버는 Chunked 전송방식을 사용하는 경우 Trailer 헤더를 포함할 수 있다. Trailer 헤더는 다른 HTTP 헤더처럼 나열되게 되는데, 위치가 메시지 바디의 제일 끝부분이다.

Trailer 헤더는 수신자로 하여금 어떠한 HTTP 헤더가 Chunked 방식의 트레일러로 사용될 것인지를 알게 해주는 헤더이다.

트레일러 헤더로는 HTTP 헤더 중 어떤것도 사용이 가능하지만 대표적으로 아래 3가지는 사용이 금지된다.


  • Transfer-Encoding
  • Content-Length
  • Trailer
다음 예제를 통해 Trailer 헤더가 어떻게 사용되는지 확인 해 보자. 

HTTP/1.1 200 OK
Date: Mon, 21 Aug 2017 09:20:01 GMT
Content-Type: text/plain
Transfer-Encoding: Chunked
Trailer: Expires

1a
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0
Expires: Sat, 25 Aug 2017 18:00:00 GMT

위 예제는 응답헤더에 Trailer 가 사용된 예이다. Trailer 헤더의 값으로 Expires 헤더를 명시하였다. 즉, Expires 를 Chunked 메시지의 트레일러로 사용하겠다는 의미이다. 
데이터 제일 마지막 부분에 Expires 헤더 정보가 위치함을 확인할 수 있다. 

이상 끝~

댓글 없음:

댓글 쓰기