제 2장 간단한 프로토콜 HTTP
HTTP를 사용하여 2대의 컴퓨터 간에 통신을 하는 경우,
한 번 통신을 할 때마다 반드시 어느 한 쪽은 클라이언트가 되고 다른 한 쪽은 서버가 된다.
HTTP는 클라이언트로부터 리퀘스트(Request)가 송신되며, 그 결과가 서버로부터 리스폰스(Response)로 되돌아온다.
클라이언트 ----------리퀘스트 송신----------> 서버
<----------리스폰스 송신----------
HTTP는 상태를 계속 유지하지 않는 스테이트리스(stateless) 프로토콜이다.
HTTP 프로토콜 레벨에서는 이전에 보냈던 리퀘스트나 이미 되돌려준 리스폰스에 대해서는 전혀 기억하지 않는다. 이는 많은 데이터를 매우 빠르고 확실하게 처리하는 범위성(scalability)을 확보하기 위해서 간단하게 설계되어 있는 것이다.
상태를 유지하지 않는다는 점에서 서버의 CPU나 메모리 같은 리소스의 소비를 억제할 수 있고, 단순한 프로토콜이기에 HTTP가 다양한 곳에서 이용되는 측면도 있다.
그러나 웹이 진화함에 따라, 스테이트리스 특성만으로는 처리하기 어려운 일이 증가하게 된다.
예를 들면, 쇼핑 사이트에 로그인했을 때이다. 인증이 필요한 웹 페이지에서 상태 관리를 하지 않는다면 인증을 마친 상태를 잊어버리기 때문에 새로운 페이지로 이동할 때마다 재차 로그인 정보를 보내든지 리퀘스트마다 매개 변수나 추가 정보를 붙여서 로그인 상태를 관리해야 하는 상황이 발생한다. 이를 해결하기 위해서 쿠키(Cookie)라는 기술이 도입된다.
쿠키(Cookie)를 사용한 상태 관리
쿠키는 리퀘스트와 리스폰스에 쿠키 정보를 추가해서 클라이언트의 상태를 파악하기 위한 시스템이다.
쿠키는 서버에서 리스폰스로 보내진 Set-Cookie라는 헤더 필드에 의해 쿠키를 클라이언트에 보존하게 된다.
↓
다음 번에 클라이언트가 같은 서버로 리퀘스트를 보낼 때, 자동으로 쿠키 값을 넣어서 송신한다.
↓
서버는 클라이언트가 보내온 쿠키를 확인해서 어느 클라이언트가 접속했는지 체크하고 서버 상의 기록을 확인해서 이전 상태를 알 수 있다.
HTTP는 URI(Uniform Resource Identifiers)를 사용하여 인터넷 상의 리소스를 지정한다.
이 URI가 있는 덕분에 인터넷 상의 어떤 장소에 있는 리소스도 호출 할 수 있다.
클라이언트는 리퀘스트를 송신할 때 리퀘스트 안에 URI를 '리퀘스트 URI'라고 불리는 형식으로 포함해야 하는데, 그 방법엔 여러 가지가 있다.
- 모든 URI를 리퀘스트 URI에 포함한다.
ex) GET http://hackr.jp/index.htm HTTP/1.1 - Host 헤더 필드에 네트워크 로케이션을 포함한다.
ex) GET /index.htm HTTP/1.1
Host : hackr.jp - 특정 리소스가 아닌 서버 자신에게 리퀘스트를 송신하는 경우는 리퀘스트 URI에 [*]을 지정할 수 있다.
ex) OPTIONS * HTTP/1.1 ( HTTP 서버가 지원하는 메소드를 묻는 예)
HTTP/1.1에서 사용할 수 있는 메소드 종류
메소드는 리소스에 어떠한 행동을 하기 원하는지를 지시하기 위해 존재한다.
- GET : 리소스 획득
리퀘스트 URI로 식별된 리소스를 가져올 수 있도록 요구한다. - POST : 엔티티 전송
엔티티를 전송하기 위해서 사용된다.
GET으로도 엔티티를 전송할 수 있지만 자주 사용하지 않고 일반적으로 POST를 사용한다. - PUT : 파일 전송
파일을 전송하기 위해서 사용된다.
HTTP/1.1 PUT 자체에는 인증 기능이 없어 누구든지 파일을 업로드 가능하다는 보안 상의 문제도 있어서 일반적인 웹 사이트에서는 사용되지 않고 있다. 웹 애플리케이션 등에 의한 인증 기능과 짝을 이루는 경우 REST(Representational State Transfer)와 같이 웹끼리 연계하는 설계 양식을 사용할 때 이용하는 경우가 있다. - DELETE : 파일 삭제
파일을 삭제하기 위해 사용된다.
PUT 메소드와는 반대로 동작하며 리퀘스트 URI로 지정된 리소스의 삭제를 요구한다.
PUT과 마찬가지로 인증 기능이 없기 때문에 일반적인 웹 사이트에서는 사용되고 있지 않다. - HEAD : 메세지 헤더 취득
GET와 같은 기능이지만 메세지 바디는 돌려주지 않는다.
URI 유효성과 리소스 갱신 시간을 확인하는 목적으로 사용된다. - OPTIONS : 제공하고 있는 메소드의 문의
리퀘스트 URI로 지정된 리소스가 제공하고 있는 메소드를 조사하기 위해 사용된다. - TRACE : 경로 조사
Web 서버에 접속해서 자신에게 통신을 되돌려 받는 루프백(loop-back)을 발생시킨다.
프록시 등을 중계하여 오리진(origin)서버에 접속할 때 그 동작을 확인하기 위해서 사용되는데,
크로스 사이트 트레이싱(XST)과 같은 공격을 일으키는 보안 상의 문제가 있어 잘 사용되진 않는다. - CONNECT : 프록시에 터널링 요구
프록시에 터널 접속 확립을 요함으로써, TCP 통신을 터널링 시키기 위해서 사용된다.
주로 SSL과 TLS 등의 프로토콜로 암호화된 것을 터널링 시키기 위해서 사용되고 있다.
지속 연결(Persistent Connections)
HTTP 초기 버전에서는 HTTP 통신을 한 번 할때마다 TCP에 의해 연결과 종료를 할 필요가 있었다.
초기 통신과 같이 작은 사이즈의 텍스트를 보내는 정도라면 문제가 없으나, 다량의 이미지가 포함되어 있는 경우 여러 리퀘스트를 송신하며 매번 TCP연결과 종료를 하게 되어 통신량이 늘어나게 된다.
이 문제를 해결하기 위해서 HTTP/1.1와 일부 HTTP/1.0에서는 지속 연결이라는 방법을 고안하였다.
지속 연결의 특징은 어느 한 쪽이 명시적으로 연결을 종료하지 않는 이상 TCP 연결을 계속 유지하는 것이다.
지속 연결의 이점은 TCP 커넥션의 연결과 종료를 반복되는 오버헤드를 줄여주기 때문에 서버에 대한 부하가 경감되고, 오버헤드를 줄인 만큼 HTTP 리퀘스트와 리스폰스가 빠르게 완료되어 웹 페이지를 빨리 표시할 수 있다는 점이다.
파이프라인(HTTP pipelining)화
지속 연결은 여러 리퀘스트를 보낼 수 있도록 파이프라인화를 가능하게 한다.
이전에는 리퀘스트 송신 후에 리스폰스를 수신할 때까지 기다린 뒤에 리퀘스트를 발행하던 것을, 파이프라인화에 의해서 리스폰스를 기다리지 않고 바로 다음 리퀘스트를 보낼 수 있다.
예를 들어 HTML 한 페이지에 10개의 이미지를 포함한 웹 페이지를 리퀘스트한 경우에는 개별 연결보다 지속 연결이 리퀘스트 완료가 빠르고, 지속 연결 보다 파이프라인화 쪽이 더 빠르다. 이 차이는 리퀘스트 수가 늘어날수록 현저하게 나타난다.
참고 : 그림으로 배우는 Http & Network Basic