brunch

매거진 낭만기획

You can make anything
by writing

C.S.Lewis

by noel Nov 17. 2017

05. HTTP가 어떤 일을 하는지 한번 열어봅시다.

1부 웹의 시작과 현재


이 모델은 한 가지 의문을 불러일으킨다. 나의 시상하부는 어떻게 나의 체중을 알고 있을까? 만일 당신이 그런 시스템을 만들고자 한다면 어떤 방식을 적용하겠는가? 혈당을 측정해서? 축척된 지방으로? 심부 체온으로? 발바닥에 가해지는 압력으로?

데이비드 J. 린든 - 고삐 풀린 뇌


이전 글에서 웹 설계의 핵심 컨셉 3가지를 말씀드렸습니다. URL, HTTP와 HTML이죠. 모두에게 꽤나 친숙한 용어일 것이라 짐작하는데, 사실 이전 글에서 소개한 하이퍼텍스트와도 관련이 깊습니다. 


HTTP (하이퍼 텍스트 트랜스퍼 프로토콜, Hyper Text Transfer Protocol)

직역하면 하이퍼텍스트 문서를 전달하기 위한 규약입니다. 패킷통신과 TCP/IP에 대하여 설명한 글을 다시 상기해 봅시다. 이 통신망에서 HTTP로 특정 웹사이트에 접속해 달라고 하는 요청을 우리는 이미 잘 알고 있습니다. 바로 이렇게 사용합니다.  https://www.daum.net/ 


HTML도 하이퍼텍스트와 관련이 깊습니다.

HTML (하이퍼 텍스트 마크업 랭귀지, Hyper Text Markup Language)

하이퍼 텍스트 문서를 만들기 위한 언어입니다.


웹은 태생부터 하이퍼텍스트로 문서를 관리하고 공유하기 위하여 만들어졌습니다. 다시 말해 웹은 하이퍼텍스트 문서 (HTML)을 공통된 형식의 주소 (URL)로 이용하기 위한 약속(HTTP)을 의미합니다. 


오늘은 그 약속 중 하나인 HTTP에 대하여 좀 더 자세히 이야기해 볼 생각입니다. 어려운 개념이 있을 수 있습니다. 제가 설명을 잘할 수 있을지도 걱정이 많이 됩니다. 기획자들이 정말 꼭 알아야 하냐에도 확신이 들지 않아 글의 고갱이를 얼추 잡아 놓은 상황에서도 완성을 할지를 고민했습니다.


하지만 HTTP는 현업에서 알게 모르게 연관이 있는 부분이 많고, 광범위하게 사용되는 것이기 때문에 작동원리에 대한 개념을 대략이라도 가지고 있는 게 좋을 것이라 생각했습니다. 특히 HTTP의 구성요소 중 쿠키, 상태 메시지, UAG 등 개념은 실무에도 종종 쓰이는 것으로 그 원리와 유래를 설명하는 게 좋겠다는 결심이 들었습니다.


제가 개발자가 아니다 보니 설명을 잘할 수 있을지, 잘 못 알고 있는 지식을 전달하지 않을지 걱정이 많습니다. 혹시라도 이 글을 읽는 능력자분이 계시면 잘못되거나 보완이 필요한 부분에 대하여 말씀해 주신다면 저와 독자들에게 큰 도움이 될 것입니다.


HTTP 들여다 보기


HTTP는 하이퍼텍스트 문서를 전달하기 위한 약속입니다. 아마도 인터넷에서 가장 유명한 프로토콜 이겠지만, 유일한 프로토콜은 아닙니다. 이 글을 읽으시는 분 중에는 FTP나 SMTP를 알고 계시는 분도 있을 것입니다. ftp는 파일을 전송하기 위한 약속, smtp는 메일을 보내기 위한 약속입니다. 우리가 어떤 메일 프로그램을 쓰건 별문제 없이 서로 글을 주고받을 수 있는 것은 각각의 프로그램들이 SMTP라는 공통의 약속을 지킬 수 있게 설계되었기 때문입니다. 마찬가지로 모든 웹브라우저는 http약속을 알고 있고 이를 지킵니다. 그래서 크롬, 사파리, 인터넷 익스플로를 쓰더라도 문제없이 데이터를 주고받을 수 있는 것입니다.


웹브라우저에서 주소를 입력할 때 http://이나 https://을 붙이는 것은 http프로토콜로 통신을 하겠다는 선언입니다. 그러면 HTTP는 데이터를 주고받기 위한 일을 합니다. 눈에 보이지 않는 이 과정은 터미널을 통해서 볼 수 있고, 별도 프로그램 없이 브라우저의 확장 기능을 통해서도 간단히 볼 수 있습니다. 브라우저의 개발자 도구 옵션으로도 충분히 볼 수 있습니다.


그림 1. 브런치 접속 시 HTTP 헤더 내용


HTTP가 요청하고 받는 내용을 크롬 개발자 도구로 본 것입니다.

오늘은 이 그림을 자세히 들여다볼 생각입니다.


HTTP 요청과 응답


우선 웹사이트를 요청하고 응답을 받는 부분을 살펴보겠습니다.

웹은 기본적으로 요청과 응답의 구조입니다. 연결을 계속 물고 있는 것이 아니라 요청을 한번 하고 응답을 하면 연결을 끊습니다.


경험이 많은 독자분은 "어? 그렇지 않아요! 계속 서버와 커넥션을 유지하게 하는 경우도 있어요."라고 말씀하실지도 모릅니다. 맞습니다. 자바스크립트를 포함한 웹 관련 기술이 발달하며 '요청-응답-끊기'에서 하지 못했던 일들이 요즘은 여러 방법으로 가능해졌습니다. 이건 나중 연재에서 소개를 할 생각이고요, 어쨌든 가장 기본적인 동작은 요청하면 응답한다 라고 생각해 주시면 됩니다. 이건 웹이 본래 정적인 문서 교환을 위하여 만들어진 것이고 그 잔재를 유지하고 있는 것입니다. 이번 연재에서는 웹은 기본적으로 요청을 하면 응답을 하고 연결이 완료되는 구조가 기본이다.. 그 정도로만 이해하고 넘어가도록 합시다.


그림 1을 좀 더 자세히 봅시다. 복잡하다고 겁먹을 필요 없습니다. 설명을 들으면 전혀 어렵지 않습니다. 우선, 캡쳐로는 글이 잘 않보이니 예제1, 예제2를 통하여 요청과 응답에 대한 내용을 텍스트로 옮겨 보겠습니다.


[예제 1: Request Headers (브라우저가 서버에 요청하는 내용) ]

GET / HTTP/1.1Host: brunch.co.kr
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/x...
Referer: https://brunch.co.kr/
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4,zh-CN;q=0.2,zh;q=0.2
Cookie: ...e7-e4d1-48b...iOQvfiwiKCKfkpxoxPQ1LtqdA8cxynz..121


그러면 이런 응답 코드가 돌아옵니다..

[예제 2: Response Headers ( 서버가 브라우저에 응답하는 내용) ]

HTTP/1.1 200 OK
Date: Thu, 16 Nov 2017 06:27:35 GMT
Server: Apache
Content-Language: ko-KR
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html;charset=utf-8
(이후 요청한 웹페이지의 소스가 따라옵니다.)


먼저 살펴볼 것은 요청과 응답에 관한 각각의 첫 줄 입니다. 예제 1의 첫줄을 먼저 봅시다.

GET / HTTP/1.1Host: brunch.co.kr

라고 요청을 하고 있습니다. 해석을 해보면 대략 아래와 같은 내용일 것입니다.

brunch.co.kr에 정보를 가져와줘 (GET). HTTP의 버전 1.1을 사용할게.

GET은 서버에 해당 정보를 요청한다는 의미입니다. 만일 게시물 등을 작성한 후 이것을 서버에 저장해 달라고 요청할 경우에는 GET대신 POST를 쓰게 됩니다. 요청을 했으니 응답을 보내줘야 하겠죠?


다음은 예제 2의 첫줄 입니다. 응답 쪽 해더의 내용이죠.

HTTP/1.1 200 OK

라고 응답을 받았습니다. 역시 해석을 해보면 아래와 같은 뜻입니다.

HTTP 1.1을 통하여 응답을 잘 받았어. 여기 네가 요청한 소스야.. 

200 OK라고 표시되어 있는데요 HTTP규약에서 정의한 요청 코드입니다. 어쩌면 이 글을 읽으시는 분 중에는 404페이지나 500 오류를 듣거나 보신 분들이 있을 것입니다. 역시 요청 코드입니다. 200, 404, 500 말고도 여러 가지가 있는데 100번대는 진행 중, 200번은 성공, 300번은 리다이렉션, 400과 500은 오류를 의미합니다. 그중 400은 잘못된 요청에 관한, 500은 응답해야 할 서버에 대한 오류를 의미합니다.


웹서핑을 하면서 가끔 pgae not found, 404라고 쓰여있는 흰 바탕의 오류 페이지를 보신 적이 있을 것입니다. 좀 규모가 있는 사이트에서는 이런 오류 페이지 대신에 자체 제작한 페이지를 보여줍니다. 해당 페이지가 없을 경우를 어떻게 알아서 보여주는 것일까 궁금해하셨다면, 답은 이 응답 코드에 있습니다. 404라고 리턴될 때 기본 오류 메시지를 노출하는 대신 미리 만들어둔 페이지가 없습니다 안내 페이지를 보여주게 설정해 둔 것입니다.


유저가 어떤 기기로 접속했는지도 HTTP가 알려줍니다.


다시 요청 코드로 돌아가 봅시다. 예제 1의 다섯 번째 줄입니다.

HTTP에는 유용한 정보가 여러 개 들어가 있는데 그중 하나가 유저 에이전트입니다.

요청하는 쪽의 기기 환경을 보여줍니다.


User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3..  

나는 맥 유저이고, 크롬 브라우저로 접속한 거야

라고 하고 있습니다.


유저 에이전트, 브라우저 UA, UAG 등으로 불리는 정보입니다. 어쩌면 개발자들이 하는 얘기를 들어보셨을 수도 있습니다. "UA를 읽어서 모바일이나 PC로 분기 처리를 할게요.."같이요. 회사에서 사용하는 통계 툴에서 접속 기기와 브라우저 정보를 보신 적이 있을 수도 있습니다. 어떻게 알 까 신기해하셨을 경험이 있었을지 모르겠습니다.  이렇게 HTTP에 담겨있는 정보를 수집하는 경우가 보통입니다.


집에 가는 길을 알려주는 작은 빵조각, HTTP 쿠키


아마도 동화 헨젤과 그레텔을 들어보신 적이 있을 겁니다.


집안 형편이 어려운 부모가 자신들을 몰래 버리려 하자 오누이는 가는 길에 몰래 돌을 뿌려 무사히 집으로 돌아올 수 있었습니다. 그런데 다음번에 또 자신들을 버리려 할 때는 미쳐 돌을 준비하지 못해서 돌멩이 대신 빵조각을 사용하게 되죠. HTTP 쿠키는 그 빵조각(쿠키)에서 유래되었습니다.


예제 1의 마지막 줄을 봅시다.

Cookie: ...e7-e4d1-48b...iOQvfiwiKCKfkpxoxPQ1LtqdA8cxynz..121


쿠키는 브라우저에서 서버로 요청이 있을 때 도메인 단위로 발급하는 작은 텍스트 파일입니다. 일단 발급이 되면 삭제되거나 만료되기 전 까지는 서버에 요청이 있을 때마다 나 전에 이 쿠키 받았어 라고 서버에 알려줍니다. 집으로 찾아가는 길을 기억하게 해주는 작은 돌멩이나 빵조각처럼 HTTP 쿠키는 이 사람에 대하여 간단하게 기억할 수 있게 해줍니다.


그림 2. 웹브라우저와 서버간 쿠키 발급 및 전송 모델 예제


이 동화의 그다음 부분도 기억하실 겁니다. 빵조각을 뿌리게 되는데, 그 빵조각을 새들이 다 주워 먹어서 집으로 돌아가는 길을 잃고 결국 산속에서 미아가 되어 버립니다. 

동화 속 빵조각과 같이 이 쿠키는 불완전한 요소가 많습니다.


새들이 빵을 먹어치우듯 영구히 남아있지도 않고 쉽게 지워질 수 도 있습니다.

브라우저 단위로 발급됩니다. 즉 같은 사람이라 하더라도 브라우저를 바꾸면 같은 사람인지 알 수 없습니다.

발급할 수 있는 개수도 한정되어 있고, 작은 빵 조각처럼 크기도 제한적입니다. 많은 정보를 담을 수 없죠.

예전에 비하여 다소 개선되었지만 보안에 취약합니다. 누군가 고의로 빵조각을 집어먹거나 다른 데로 옮겨놓을 수 있는 것처럼요.


이렇게 불안한 쿠키가 웹 초창기부터 지금까지도 널리 사용되는 이유는 간편하기 때문입니다. 쇼핑을 하다가 잠시 뉴스를 보고 왔는데 애써 고른 상품이 날아가 버리면 짜증 나는 상황이 발생할 것입니다. 그렇다고 구매도 아니고 단순하게 장바구니에 상품을 담기 전에 회원가입을 하고 로그인을 하라고 할 수도 없는 일이죠. 


쿠키는 이러한 경우처럼 보통 민감하거나 정교한 정보를 담을 필요는 없지만 어떤 상태를 기억해야 할 때 매우 간단히 사용할 수 있습니다. 장바구니에 물건을 담은 것을 기억하고, 이전에 본 페이지를 기억해 주기도 합니다. 로그인을 한 후 다시 페이지를 방문할 때마다 로그인을 안 하게 할 수도 있습니다. 여행을 가려고 호텔을 한번 검색했더니 이후 모든 광고가 여행 관련 상품으로만 노출되는 경험을 해보신 분들도 있을 겁니다. 검색엔진이나 여행사이트의 쿠키가 그 흔적을 기억하고 있다가, 다른 배너 광고에서도 좋아할 만한 내용을 찾아서 보내주는 것입니다.


쿠키는 웹사이트를 방문하거나, 배너에 노출되거나, 배너를 클릭하는 등 개발자가 사전에 설정해 놓은 대로 유저의 디바이스의 특정 위치에 자동 저장됩니다. 그 이후 다시 해당 도메인으로 방문을 하게 되면 HTTP는 이 쿠키를 전송하여 발급받은 쿠키를 다시 알려주게 됩니다. 서버는 이를 추적하여 해당 쿠키에 맞는 적절한 행동을 할 수 있습니다.




쿠키는 브라우저 단위로 발급된다. 로그인하지 않고 상품을 장바구니에 담아뒀다가 다음날 다시 보는 것은 가능하지만 피씨에서 장바구니에 담아 둔 물건을 모바일에서 보는 것은 불가능한 이유이다. (쿠키는 브라우저별로 발급될 뿐 아니라 유저의 로컬에 저장된다. 어찌어찌 동일 시스템에서는 크로스 브라우징 쿠키를 사용할 수 있는 편법이 존재할 수 도 있을지 모르나, 디바이스까지 바뀌어버리면 쿠키로는 애초에 불가능한 일이다.) 또한 쿠키는 웹브라우저에서 사용하는 방식으로 모바일앱에서는 쿠키 사용이 불가능하다. 대신 모바일 앱은 기기 고유값인 ADID를 사용한다. ADID를 포함하여 유저가 누군지 알아내는 방법의 진화에 대하여는 다음 기회에 보다 상세히 설명할 생각이다.


HTTPS에 대한 설명까지 하려다 내용이 너무 길어져 이번 연재에는 넣지 않았다. 이후 연재에서 설명할 기회가 있을 것 같아 우선 넘어간다. 



이번 연재에 사용한 그림의 출처를 밝힌다.

표지그림 ( 출처 )

그림 1 : 브런치의 HTTP해더를 크롬 브라우저를 통하여 확인하고 직접 캡처

그림 2 ( 출처 )

1) 브라우저에서 웹페이지를 요청하면 2) 서버는 요청한 페이지와 함께 쿠키를 발급해서 보내고 3) 같은 서버의 다른 페이지를 방문할 때 브라우저는 발급받은 쿠키를 다시 보내어 이전에 방문한 적 있는 누구누구라는 증명을 하는 과정을 요약한 그림이다.









브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari