웹 서버는 HTTP 메시지를 받아서 파싱하여 적절한 자원을 찾은 뒤, 해당 자원을 HTTP 메시지로 보내주는 소프트웨어이다. 클라이언트와 웹 서버간에 이루어지는 통신은 모두 HTTP를 통해 발생하기 때문에, HTTP 메시지를 이해하는 것은 중요하다. HTTP 메시지의 흐름과 구조에 대해 살펴보자.
웹을 공부하다보면 인바운드와 아웃바운드라는 용어를 종종 접할 수 있다. 인바운드와 아웃바운드는 통신의 방향을 나타내는 말이다. 클라이언트에서 서버로의 방향을 인바운드, 서버에서 클라이언트로의 방향을 아웃바운드라 일컫는다.
메시지는 아래의 구조를 갖는다.
표준에 의하면 시작줄과 헤더의 끝은 빈 줄(CRLF)로 끝나야한다. CRLF는 캐리지 리턴(ASCII 13)과 개행 문자(ASCII 10)로 구성된 두 글자의 줄바꿈 문자열을 일컫는 말이다. 주의할 점은 표준과 다르게 동작하는 http 어플리케이션이 많이 존재하기 때문에, 빈줄로 시작줄과 헤더의 끝을 나타내더라도 동작할 수 있도록 웹서버를 구현하는 것이 바람직하다는 것이다.
또한, 시작줄의 구성 요소는 각각 공백으로 구분되고 헤더의 구성 요소는 CRLF로 구분된다.
HTTP 메시지는 크게 클라이언트에서 서버로 가는 요청 메시지와 서버에서 클라이언트로 가는 응답 메시지로 나뉘어진다.
요청 메시지의 형식은 아래와 같다.
<메서드> <요청 URL> <버전>
<헤더>
<엔터티 본문>
<요청 URL>은 클라이언트가 원하는 자원의 URL을 나타낸다. http 메시지를 수신하는 서버가 명확하기 때문에 일반적으로 호스트명을 생략한다.
<메서드>는 클라이언트가 원하는 서버의 동작을 나타낸다.
<버전>은 사용하는 http 프로토콜의 버전을 나타낸다. 주의할 점은, 해당 어플리케이션이 지원하는 제일 높은 버전을 명시하도록 돼있다는 것이다. 즉, 요청 메시지나 응답 메시지의 <버전>에 http/1.2가 명시돼있다고 해서 해당 메시지가 http 1.2 프로토콜을 따른다고 보면 안된다. 해당 메시지를 보낸 어플리케이션이 지원하는 제일 최신 버전이 1.2라는 의미인 것이고 해당 메시지는 http 1.1이나 http 1.0을 따르는 메시지일수도 있다.
<헤더>는 메시지의 속성을 나타낸다. <이름>: <값>의 형식을 갖는데 :과 <값> 사이에 공백이 존재해도 되고 존재하지 않아도 괜찮다.
<엔터티 본문>은 임의의 데이터 블록을 나타낸다.
응답 메시지의 형식은 아래와 같다.
<버전> <상태 코드> <사유 구절>
<헤더>
<엔터티 본문>
HTTP 1.1을 지원하는 어플리케이션은 최소한 GET과 HEAD 메서드를 구현해야한다.
안전한 메서드는 HTTP 요청이 서버에 어떠한 작용도 없음을 의미한다. 즉 HTTP 요청의 결과로 인해 서버에서 일어나는 일은 아무것도 없다는 것이다.
리소스를 요청하기 위해 쓰인다.
GET처럼 행동하지만, 서버는 응답으로 엔터티 본문을 포함하지 않고 헤더만 송신한다.
서버에 자원의 생성 혹은 교체를 요구하는 메서드. 요청 URL에 대응되는 새로운 자원을 생성하거나 교체한다.
서버에 입력 데이터를 전송하기 위해 사용하는 메서드. PUT은 서버의 자원에 데이터를 입력하는 것이고 POST는 서버에 데이터를 보내는 것이다.
클라이언트에서 서버에 요청을 보낼 때, 해당 요청은 방화벽, 프락시, 게이트웨이 등 많은 어플리케이션을 거칠 수 있다. 그리고 이러한 어플리케이션은 많은 경우 HTTP 메시지를 수정해서 전송한다. TRACE 메서드를 사용하여 서버에 도달했을 때의 HTTP 메시지가 어떻게 변하는지 알아낼 수 있다.
클라이언트가 서버에 OPTIONS 메서드를 사용하여 요청을 보내면, 서버는 해당 자원이 어떤 메서드를 지원하는지 "Allow" 헤더에 담아서 반환한다.
자원의 삭제를 요청하는 메서드. 삭제가 수행될 것임을 보장받지는 못한다.
이번 시간에서는 HTTP 메시지의 구조와 메서드에 대해 간략히 알아봤다. 다음 시간에는 상태 코드에 대해 자세히 알아보자.
HTTP 완벽 가이드 웹은 어떻게 동작하는가