본문 바로가기

Network

HTTP

HTTP란

우리는 HTTP에 대해서 많이 들어봤다. 하지만 HTTP가 무엇인가 라는 질문에 대답하기엔 아직 대답하기에 어려운 부분이 많이 있다. 이번에 HTTP에 대해서 정리해보겠다. 우선 HTTP란 인터넷 상에서 정보를 주고받는 프로토콜을 말한다.

특징

HTTP는 다음과 같은 특징이 있다.

무상태

무상태란 통신을 하는데 서로의 상태를 기억하지 않는것을 말한다. 따라서 어떠한 클라이언트와 통신을 하던 간에 해당 요청에 따른 응답만 하면 된다. 즉, 모든 통신이 독립적이다. 이러한 특징을 통해 서버는 클라이언트의 정보를 기억할 필요가 없으며, 요청에 따른 응답만 하면 되기에 여러개의 서버를 둘 수 있다는 서버에 확장성이라는 장점을 가질 수 있다. 하지만 클라이언트가 자신이 누군지 서버에 알려줘야 하는 상황이라면 매번 자신의 정보를 서버에 전달해야 한다는 단점이 있다.

 

비연결성

HTTP는 연결을 유지하지 않는다는 비연결성 이라는 특징 또한 갖고 있는데, 클라이언트가 서버에 요청을 하고, 서버는 그에 대한 응답을 하면 둘의 연결은 끊어진다는 의미이다. 즉, 서버는 클라이언트와 연결을 유지하기 위해 자원을 쓰지 않는다. 이는 요청이 많지 않을때는 효율적이고 빠르게 응답이 가능하나 큰 규모의 서비스인 경우 매번 요청이 올때마다 연결을 끊고 다시 맺는 작업을 하는것은 비효율적이며 한계를 보인다. 이를 해결하기 위해 연결을 유지하는 방법이 나왔는데 이는 다음 HTTP버전을 설명할 때 알아보도록 하자.

 

클라이언트 서버 구조

HTTP는 클라이언트가 요청이 있을때만 서버가 응답을 하는 단방향 통신이다. 서버는 클라이언트에 요청하지 않으며 응답만 할 뿐이다. 이때 HTTP의 요청과 응답 메시지는 다음과 같이 이루어져 있다.

요청 메시지 

  • start-line
    • HTTP 메서드
    • 요청 대상
    • HTTP 버전
  • header
    • 요청 클라이언트 정보
    • 메시지 바디의 크기, 압축, 인증, 캐시, 등등
  • empty line
  • message body
    • 실제 전송할 데이터
    • byte로 표현할 수 있는 모든 데이터

응답 메시지

  • start-line
    • HTTP 버전
    • HTTP 상태 코드
    • 이유 문구
  • header
    • 메시지 바디의 크기, 압축, 인증, 캐시, 등등
  • empty line
  • message body
    • 실제 전송할 데이터
    • byte로 표현할 수 있는 모든 데이터

이때 HTTP 메소드의 종류는 다음과 같다.

  • GET: 리소스 조회
  • POST: 요청 데이터 처리, 주로 등록에 사용
  • PUT: 리소스 대체, 해당 리소스가 없으면 생성
  • DELETE: 리소스 삭제
  • PATCH: 리소스 부분 변경
  • HEAD: GET과 동일하지만 메시지 부분을 제외하고, 상태 중과 헤더만 반환
  • OPTION: 대상 리소스에 대한 통신 가능 옵션을 설명(주로 CORS에서 사용)
  • CONNECT: 대상 자원으로 식별되는 서버에 대한 터널을 설정
  • TRACE: 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행

HTTP의 진화

HTTP는 월드 와이드 웹에 내재된 프로토콜이다. 팀 버너스 리에 의해서 발명되었으며, 본래의 단순함의 대부분을 지키면서 확장성 위에서 만들어지도록, 많은 수정을 거쳐왔다. 

 

월드 와이드 웹, HTTP 0.9

당시 전 세계는 입자 가속기 연구에 참여하고 있었다. 하지만 이들은 서로 다른 컴퓨터와 운영체제로 일을 하다 보니 소통이 되지 않는 불편함을 겪고 있었다. 이에 팀 버너스 리는 컴퓨터와 운영체제에 상관없이 소통할 수 있는 방법을 찾기 위해 노력했으며, 자신이 제안한 월드 와이드 웹의 개념을 이용해 최초의 웹 페이지를 작성했다. 그리고 컴퓨터에 저장되어있는 정보를 인터넷을 통해 연결했다. 이때 문서를 교환하기 위해 HTTP라는 프로토콜을 사용했는데 문서만 교환하는 용도로 쓰이다 보니 매우 간단했다. 다음과 같은 요청과 응답으로 이루어져 있으며 이때의 버전을 HTTP/0.9 또는 원라인-프로토콜이라고 한다.

GET /mypage.html

 

<HTML>
A very simple HTML page
</HTML>

메소드도 GET방식 밖에 없었고 헤더도 없었다.

 

HTTP 1.0

HTTP/0.9는 매우 제한적이었으며 브라우저와 서버 모두 좀 더 융통성을 가지도록 빠르게 확장되었다. 다음은 HTTP 1.0에서 추가된 기능이다.

  • 버전 정보가 각 요청 사이내로 전송되기 시작했다. (HTTP/1.0  GET 라인에 붙은 형태로)
  • 상태 코드 라인 또한 응답의 시작 부분에 붙어 전송되어, 브라우저가 요청에 대한 성공과 실패를 알 수 있고 그 결과에 대한 동작(특정 방법으로 그것의 로컬 캐시를 갱신하거나 사용하는 것과 같은)을 할 수 있게 되었다.
  • HTTP 헤더 개념은 요청과 응답 모두를 위해 도입되어, 메타데이터 전송을 허용하고 프로토콜을 극도로 유연하고 확장 가능하도록 만들었다.
  • content-type의 도입으로 html문서 외에도 전송이 가능해졌다.
  • 하지만 1번 통신을 하면 연결이 끊기기에 매번 연결을 맺어야 하는 비효율적인 통신을 하였다.

다음은 HTTP/1.0의 통신이다.

GET /mypage.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
A page with an image
  <IMG SRC="/myimage.gif">
</HTML>

두 번째 커넥션에 의한 이미지를 내려받기 위한 요청과 그에 대한 응답이다.

GET /myimage.gif HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

200 OK
Date: Tue, 15 Nov 1994 08:12:32 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/gif
(image content)

HTTP 1.1

HTTP 1.0의 모호함과 몇몇의 사항들을 개선하여 1.0이 나온지 얼마 되지 않아 1.1버전이 출시되었다. 다음은 HTTP 1.1에서 새롭게 추가된 사항들이다.

  • connection 헤더에 keep-alive가 default로 설정되어 서버와 클라이언트간 연결을 유지하는것이 가능하게 되었다.
  • 파이프라이닝을 추가하여, 첫번째 요청에 대한 응답이 완전히 전송되기 이전에 두번째 요청 전송을 가능케 하여, 통신의 효율성을 높였다.
  • chunked 응답 또한 지원된다.(요청 메시지가 클때 조금씩 분할하여 요청을 보내는것)
  • 추가적인 캐시 제어 메커니즘이 도입되었다.
  • 언어, 인코딩 혹은 타입을 포함한 컨텐츠 협상이 도입되어, 클라이언트와 서버로 하여금 교환하려는 가장 적합한 컨텐츠에 대한 동의를 가능케 했다.

다음은 HTTP 1.1의 요청과 응답이다.

GET /en-US/docs/Glossary/Simple_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header

200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding

(content)


GET /static/img/header-background.png HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header

200 OK
Age: 9578461
Cache-Control: public, max-age=315360000
Connection: keep-alive
Content-Length: 3077
Content-Type: image/png
Date: Thu, 31 Mar 2016 13:34:46 GMT
Last-Modified: Wed, 21 Oct 2015 18:27:50 GMT
Server: Apache

(image content of 3077 bytes)

 

HTTP 2.0

HTTP 1.1 버전에서 파이프라이닝 기능은 한번에 하나의 응답만 처리할 수 있어 앞전에 있던 요청에 대한 응답이 너무 길면 뒤에 요청이 Blocking 되어버리는 HeadOfLineBlocking(HOL)이 발생하는 문제가 발생하고, header의 구조가 중복되어 비효율적인 매번 비효율적인 응답을 하는 한계점이 있어 이를 해결하기 위해 http 2.0버전이 나왔다.

HTTP 2.0은 다음과 같은 특징을 갖는다.

  • 이는 텍스트 프로토콜이라기 보다는 이진 프로토콜로 더 이상 읽을 수도 없고 수작업을 만들어낼 수 없다. 즉, http메시지가 프레임 단위로 분할되며 각 프레임이 스트림을 통해 전달이 된다.
  • 따라서 동시에 여러 요청을 처리하는 것이 가능해 졌으며, 스트림 별로 우선순위를 부과해 우선순위에 맞추어 응답하는것 또한 가능해졌다. 
  • 데이터의 중복과 그런 데이터로부터 유발된 불필요한 오버헤드를 제거하면서, 연속된 요청 사이의 매우 유사한 내용으로 존재하는 헤더들을 허프만 인코딩을 통해 압축한다.
  • 또한 서버 푸시라는 매커니즘에 의해 클라이언트가 요청하지 않은것에 대해서도 서버가 클라이언트에 필요한것을 응답해준다.(server push)
  • 이렇게 완벽해 보이는 HTTP 2.0도 결국에는 tcp위에서 작동한다는 특징이 있기에 한계를 갖게 된다. 병렬 처리를 한다고 하더라도 스트림중 하나의 패킷이 유실 된다면 tcp 고유의 HOL이 발생하여 다른 스트림 또한 블록킹 된다는 점이다.

HTTP 3.0

HTTP 2.0의 한계를 극복하기 위해 새롭게 나온 버전으로 QUIC이라는 프로토콜을 이용하며, 기존의 버전과는 다르게 이는 UDP위에서 작동한다. 따라서 HTTP 2.0에서 직면한 TCP 고유의 문제를 해결할 수 있게 되었다. UDP가 데이터 전송의 신뢰성을 보장하지 않지만 UDP위에 새로운 전송계층을 추가함으로써 TCP에 존재하는 패킷 재전송, 혼잡 제어, 속도 제어 등 여러 기능들을 제공한다. 또한 TCP보다 더 빠르다는 특징이 있다.

'Network' 카테고리의 다른 글

Session, Cookie, Cache  (0) 2023.01.31
REST API  (2) 2023.01.19
http 상태코드  (0) 2023.01.07
TCP & UDP  (0) 2022.11.10