[HTTP_NETWORK] HTTP 프로토콜
업데이트:
이번 시간에는 HTTP 프로토콜에 대해 알아보자.
1. HTTP는 클라이언트와 서버 간에 통신을 한다
TCP/IP에 있는 다른 프로토콜과 같이 HTTP도 클라이언트와 서버 간에 통신을 한다. 리소스를 필요하다고 요구하는 쪽이 클라이언트이고, 이러한 리소스를 제공하는 쪽이 서버가 된다. HTTP를 이용하여 2대의 컴퓨터 간에 통신을 하는 경우 반드시 한 대는 클라이언트, 한 대는 서버가 된다. 경우에 따라 2대의 컴퓨터 간에 역할이 바뀌는 경우도 있지만 한 번만 통신을 하는 경우를 보면 클라이언트와 서버의 역할은 반드시 정해져 있다.
2. Request와 Response
HTTP는 클라이언트로부터 Request(요청)가 송신되며, 그 결과가 서버로부터 Response(응답)로 돌아온다. 즉 통신은 클라이언트에서 시작된다. 서버에서 Request를 받지 않고서 Response를 송신하는 경우는 없다. 반드시 Request가 있어야 서버는 Response를 할 수 있다.
3. HTTP는 상태를 유지하지 않는 프로토콜
HTTP는 상태를 유지하지 않는 stateless 프로토콜이다. Request와 Response를 교환하는 동안 상태를 관리하지 않는다. 따라서 HTTP 프로토콜에서는 이전에 보냈던 Request나 Response에 대해서는 기억하지 않는다. 과거의 정보가 없어 새로운 Request가 보내질 때마다 새로운 Response가 생성된다.
하지만 웹이 발전하면서 stateless 특성으로 처리하지 어려운 일들이 많아지게 되었다. 예를 들어 로그인 후 페이지를 이동하는 경우 로그인 상태를 유지할 필요가 있는데, 이러한 상태를 유지하고 싶은 경우 사용하기 위해 Cookie(쿠키)라는 기술이 도입되었다.
4. Request URI로 리소스를 식별
HTTP는 URI를 사용해 리소스를 지정한다. URI를 통해 인터넷 상의 어떠한 리소스도 호출할 수 있게 된다.
5. HTTP 메소드
HTTP/1.1 에서 사용할 수 있는 메소드에 대해 알아보자.
1) GET : 리소스 획득
GET 메소드는 Reuqest URI로 식별된 리소스를 가져올 수 있도록 요구한다. 가져올 리소스 내용은 서버가 해석한 결과이다. 리소스가 텍스트이면 그대로 반환하고 GGI와 같은 프로그램이면 실행해서 출력된 내용을 돌려준다.\
2) POST : 엔티티 전송
POST 메소드는 엔티티를 전송하기 위해 사용된다. GET으로도 엔티티를 전송할 수 있지만 일반적으로는 POST를 사용한다. GET은 Request body가 없는 반면 POST는 Request body에 엔티티를 전송한다.
3) PUT : 파일전송
PUT 메소드는 파일 전송을 위해 사용한다. FTP에 의한 파일 업로드와 같이 Request에 포함된 엔티티를 Request URI로 지정한 곳에 보존하도록 요구한다. HTTP/1.1 PUT 자체에는 인증 기능이 없어 누구든 파일 업로드를 할 수 있다는 점 때문에 일반적으로 사용되지는 않는다. 웹 애플리케이션에 의한 인증 기능과 짝을 이루는 경우나 REST와 같이 웹끼리 연계하는 설계 양식을 사용할 때 이용하기도 한다.
4) HEAD : 메시지 헤더 취득
HEAE 메소드는 GET과 같은 기능이지만 메시지 바디는 반환하지 않는다. URI 유효성이나 리소스 갱신 시간을 확인하려는 목적으로 사용된다.
5) DELETE : 파일 삭제
DELETE 메소드는 파일을 삭제하기 위해 사용된다. PUT 메소드와는 반대로 동작하며 Request URI로 지정된 리소스의 삭제를 요구한다. PUT과 마찬가지로 인증 기능이 없어 일반적으로는 사용되지 않는다.
6) OPTIONS : 제공하는 메소드 문의
OPTIONS 메소드는 Request URI로 지정한 리소스가 제공하는 메소드를 조사할 때 사용한다.
7) TRACE : 경로 조사
TRACE 메소드는 웹서버에 접속해서 자신에게 통신을 되돌려받는 루프백을 발생한다. ‘Max-Forwards’ 라는 헤더 필드에 수치를 포함시켜 서버를 통과할 때마다 그 수치를 줄여나간다. 수치가 0이 된 곳을 끝으로 Response를 돌려준다. 클라이언트는 TRACE 메소드를 사용해 Request를 보낸 곳에 어떤 Request가 가공되어 있는지를 조사할 수 있다. 하지만 크로스 사이트 트레이싱(XST)와 같은 공격을 일으키는 보안 상의 문제도 있어 일반적으로 사용되지 않는다.
8) CONNECT : 프록시에 터널링 요구
CONNECT 메소드는 프록시에 터널 접속 확립을 요구함으로써 TCP 통신을 터널링 시키기 위해 사용된다. 주로 SSL, TSL 등의 프로토콜로 암호화 된 것을 터널링하기 위해 사용된다.
6. 메소드를 사용해 지시
Request URI로 지정한 리소스에 Request를 보내는 경우 메소드를 사용해 어떤 행동을 하기를 원하는지 지시한다. 메소드는 대소문자를 구분하므로 반드시 대문자로 작성하도록 하자.
7. 지속 연결로 접속량 절약
HTTP 초기 버전에서는 통신을 할 때마다 TCP에 의해 연결과 종료를 할 필요가 있었다. 당시에는 작은 사이즈의 텍스트를 보내는 정도였기 때문에 이는 문제가 되지 않았으나, 웹이 발전해가면서 통신량이 늘어나는 문제가 발생되었다. 예를 들어 하나의 페이지에 이미지가 20개가 있는 경우, 이미지 20개를 위해 여러 Request를 송신한다. Request를 보낼 떄마다 TCP 연결과 종료를 하게 되어 통신량이 늘어나게 되었다.
지속연결 이란 TCP 연결 문제를 해결하기 위해 고안된 방법이다. 어느 한 쪽이 명시적으로 연결을 종료하지 않는 이상 TCP 연결을 유지하는 방식이다. 이로 인해 TCP 커넥션의 연결과 종료를 반복하지 않아 서버에 대한 부하가 줄어들게 된다. 이로인해 HTTP Request와 Response가 빠르게 이뤄지므로 웹 페이지도 빨리 표시할 수 있게 된다. 이러한 지속연결은 HTTP/1.1 에서는 표준 동작이지만 HTTP/1.0 에서는 정식 사양이 아니다.
지속연결은 여러 Request를 보낼수록 파이프라인화를 가능하게 한다. 이전에는 Request 송신 후에 Response를 수신할 떄까지 기다린 뒤 다음 Request를 발행했다면, 파이프라인화를 통해 Response를 기다리지 않고 바로 다음 Request를 보낼 수 있게 되었다. 병행해서 Request를 보낼 수 있게 되면서 더욱 더 빠르게 웹 페이지를 표시할 수 있게 되었다.
개별 연결보다 지속연결이 Request 완료가 빠르고, 지속연결보다 파이프라인화가 더 빠르다.
8. 쿠키를 이용한 상태 관리
HTTP는 stateless 프로토콜이기 때문에 과거에 교환했던 정보를 알 수 없다. stateless에도 장점이 있는데, 상태를 유지하지 않는다는 점에서 서버의 CPU나 메모리 같은 리소스 사용을 줄일 수 있다는 점이다. 하지만 상태관리가 안된다는 큰 단점이 존재한다.
stateless의 특징은 남겨두고 이와 같은 문제를 해결하기 위해 쿠키가 도입되었다. 쿠키는 Request와 Response에 쿠키 정보를 추가해서 클라이언트의 상태를 파악하기 위한 시스템이다. 쿠키는 서버에서 Response로 보내진 Set-Cookie 라는 헤더 필드의 쿠키를 클라이언트에 보존하게 된다. 다음번에 클라이언트가 같은 서버로 Request를 보낼 때 클라이언트가 가지고 있던 쿠키 값을 넣어서 송신한다. 서버는 클라이언트가 보낸 쿠키를 통해 어느 클라이언트가 접속했는지 체크하고 서버 상의 기록을 확인해서 이전 상태를 알 수 있다.