말하지 않으면 몰라요. 컴퓨터도 몰라요.
우리가 카페에 가서 앉아만 있는다고 해서 원하던 커피가 눈앞에 나타나진 않습니다. 카운터로 가서 어떤 음료나 사이드 메뉴를 주문할지 그리고 어떤 옵션을 추가할지를 점원에게 설명하고 나야 우리는 원하는 메뉴를 받아 자리에서 먹을 수 있죠.
인터넷 또한 마찬가지입니다. 서버에게 원하는 데이터를 요청하고, 요청하는 데이터에 대한 응답을 받고 나서야 우리는 HTML, CSS, 이미지 등 원하는 리소스를 받아볼 수 있습니다. 그리고 이러한 클라이언트와 서버 간 소통을 가능케 하는 것이 바로 지금부터 알아볼 HTTP입니다.
지난 1편에서 클라이언트와 서버가 서로 상호교환하는 과정을 통해 우리가 웹 페이지를 볼 수 있다고 설명했죠? 사람들이 말, 글 등으로 서로 소통하듯이 프로그램 또한 상호 약속을 통해 만들어진 어떤 규격을 가지고 메시지를 주고 받는데요, 이 때 사용하는 규약이 바로 프로토콜이랍니다.
HTTP(Hyper Text Transfer Protocol)는 웹 브라우저와 웹 서버 간에 데이터를 주고받기 위해 사용하는 인터넷 프로토콜입니다. 프로토콜이란 상호 간에 정의한 규칙을 의미하며 특정 기기 간에 데이터를 주고받기 위해 정의되었습니다. 이러한 프로토콜 중에서 인터넷에서 사용하며 HTML을 비롯한 다양한 리소스들을 전송할 수 있는 프로토콜이 바로 HTTP입니다.
프로토콜의 모델은 여러 가지가 존재하는데 그중 HTTP는 클라이언트/서버 모델을 따릅니다. 클라이언트/서버 모델이란 서로 관계를 맺고 있는 컴퓨터 프로그램이 클라이언트와 서버 두 역할로 구분되어 있다는 뜻입니다.
이러한 모델은 클라이언트가 서버에게 요청을 보내고, 서버는 그에 대한 결과를 응답하는 구조를 갖고 있습니다. 가령 카페로 예를 들면 카페 내에는 고객/종업원이 존재하고 이들은 고객이 메뉴를 주문하면 종업원이 주문서를 확인하고 주문한 메뉴를 만들어 주는 형태로 관계를 맺고 있다는 거죠.☕️
요청하고 전송하는 과정에서 클라이언트와 서버는 각각 HTTP 메시지라는 것을 전송하는데, 이때 클라이언트가 서버에서 요청하는 메시지가 요청 메시지 (Request Message), 클라이언트의 요청을 해석한 서버가 응답하는 메시지가 응답 메시지 (Response Message)입니다. 이 두 개의 메시지를 주고받으며 서버와 클라이언트는 각자 필요한 정보를 받고 또 보낼 수 있게 되는 거죠.
그리고 대화에도 서론-본론-결론처럼 일련의 구조가 있듯 HTTP 메시지 또한 일정한 포맷이 존재합니다. 이러한 포맷은 누가 누구에게 보내는지에 따라 조금 형식이 다른데요, 지금부터 2가지 다른 메시지 유형과 그 포맷에 대해 알아보겠습니다.
요청 메시지는 손님이 점원에게 요청한 정보가 담긴 주문서와 유사합니다. 클라이언트가 서버에게 요청하는 정보가 담겨 있으며 아래와 같은 구조를 갖고 있습니다.
첫 줄에는 클라이언트가 무엇을, 어떻게 처리하고자 한다는 정보가 담겨 있는데, 이때 메서드는 '어떻게' , 즉 처리 방식에 해당합니다. 다시 말해 클라이언트가 서버에게 데이터를 요청하고, 요청하는 데이터에 수행하고자 하는 동작을 나타냅니다. 메서드의 종류는 크게 아래와 같습니다.
GET : 존재하는 자원에 대한 요청
POST : 새로운 자원을 생성
PUT : 존재하는 자원에 대한 변경
DELETE : 존재하는 자원에 대한 삭제
메서드가 '어떻게' 에 해당한다면 경로는 메서드를 참고하여 수행할 대상, 즉 '무엇을'에 해당합니다. 주로 가져오려는 리소스의 경로를 표시하며 형태는
https://www.google.com/ 처럼 완전한 형식,
/index.html 처럼 상대적인 형식 등 메서드의 유형에 따라 다양한 포맷이 있습니다.
HTTP 프로토콜의 버전을 표시합니다. 현재는 1.1 버전과 보안성을 강화한 2 버전이 주를 이루고 있습니다.
서버에 대한 추가 정보를 전달합니다. 주로 호스트의 정보나 접속하고 있는 사용자의 정보, 그리고 열려고 하는 페이지의 정보 등을 확인할 수 있습니다. 예시에 나온 헤더 속성을 확인해보면 다음과 같습니다.
uset-agent : 웹 브라우저의 다른 표현. 요청하는 웹 브라우저의 정보 및 운영체제를 표시합니다.
accept-encoding : 클라이언트가 이해할 수 있는 압축 방식을 표시합니다. accept-encoding을 표기하여 서버에게 전송하면 서버는 필요한 경우 리소스를 압축하여 반환합니다.
공백 라인은 헤더와 본문을 구분하는 역할입니다. 빈 줄이 없으면 메시지를 읽어들일 때 어디까지가 헤더이며 어디부터가 본문인지를 파악할 수 없기 때문에 중요한 요소입니다.
메시지의 가장 마지막에 들어가는 컨텐츠입니다. 다만 다른 컨텐츠와는 달리 본문은 필수 요소는 아닙니다. 메서드가 GET, HEAD, DELETE, OPTIONS 처럼 리소스를 가져오는 요청은 보통 본문이 필요가 없기 때문입니다. 따라서 POST 처럼 서버에 새로운 자원을 추가해야 하는 경우에 그 정보를 본문에 작성하여 전달합니다.
요청 메시지가 주문서의 역할이었다면 응답 메시지는 영수증의 역할이라고 볼 수 있습니다. 내가 주문한 내용이 잘 들어갔는지, 혹시 결제한 카드의 한도가 초과되지는 않았는지 확인할 수 있는 결과물이죠.
정리하자면 응답 메시지는 클라이언트의 요청에 대한 서버의 답변이 담겨 있으며 아래와 같은 구조를 갖고 있습니다.
요청 메시지와 동일하며 HTTP 프로토콜의 버전을 나타냅니다.
상태 코드는 클라이언트 요청의 성공 여부를 숫자로 나타낸 것이며 상태 메시지는 상태 코드를 이해하기 쉽게 영어로 풀어쓴 메시지입니다.
상태 코드와 상태 메시지는 100번대부터 500번대까지 존재하는데 그 중 우리가 가장 자주 접하는 코드는 성공했을 때 나오는 200번대, 웹 브라우저 측에서 오류가 발생했을 때 나오는 400번대입니다. 자세한 코드의 내용은 아래를 참고해 주세요.
1xx (조건부 응답) : 요청을 받았으며 작업을 계속합니다.
2xx (성공) : 정상적으로 요청을 수행했을 때 나타나는 코드입니다.
3xx (리다이렉션 완료) : 클라이언트가 요청을 마치기 위해 추가 동작을 취해야 할 때 나타납니다.
4xx (요청 요류) : 클라이언트의 요청에 오류가 있을 때 나타나는 코드입니다.
5xx (서버 오류) : 서버가 들어온 요청을 수행하지 못했을 때 나타납니다.
요청 헤더와 유사한 형식으로 추가 정보를 전달합니다. 위의 예시에 나온 헤더들을 한 번 설명하자면 다음과 같습니다.
content-type : 전달한 리소스의 타입. text/html 라면 텍스트 중에서도 HTML타입이라는 뜻이며, image/jpeg라면 jpeg확장자를 가진 이미지임을 의미합니다.
content-encoding : 응답 메시지 헤더의 accept-encoding 처럼 컨텐츠가 압축된 방식을 표시합니다.
date : 해당 메시지가 만들어진 날짜와 시간을 포함합니다.
가져온 리소스가 표시됩니다. 만약 리소스 유형이 HTML이라면, <html><body></body></html> 형태의 HTML코드가 나타나고, 유형이 이미지 또는 동영상이면 그에 맞는 코드가 표시됩니다.
여기까지 웹 클라이언트와 웹 서버의 커뮤니케이션에서 중요한 역할을 하는 프로토콜, HTTP에 대해 간략히 알아보았습니다.
HTTP의 도움으로 우리는 정확하게 원하는 정보를 브라우저에 불러올 수 있게 되었네요!
HTTP라는 말만 들으면 왠지 어려워보였는데, 알고 보니 왠지 회사에서 메일을 보낼 때 일정한 규격에 맞게 작성하는 우리네 사회생활과 비슷해보이지 않나요?
그래서 그런지 웹에 대해 알아가는 과정이 마냥 힘들지는 않는가 봅니다.
그럼 다음 포스팅에서 뵙겠습니다.
HTTP 상태 코드 - 위키백과, 우리 모두의 백과사전