본 포스팅은 HTTP에 대해 좀 더 자세히 공부하고자 MDN 문서를 기반으로 공부한 내용을 정리한 글입니다.
HTTP란?
HTTP는 HTML 문서와 같은 리소스를 가져올 수 있게 해주는 프로토콜이다. 웹에서 발생하는 데이터 교환 행위의 근간이라고 할 수 있다. HTTP는 클라이언트-서버 프로토콜이며, 이는 즉 데이터를 받는 측 - 주로 웹 브라우저 - 가 요청을 시작하는 측이라는 것을 뜻한다. 클라이언트로부터 전송된 메시지는 요청(request)라고 부르고, 서버가 그에 대한 답변으로 보낸 메시지는 응답(response)라고 부른다. 클라이언트는 주로 웹 브라우저이지만, 구글 검색 크롤러 같은 로봇일 수도 있다.
HTTP는 1990년대 초반에 디자인되었고, 그 이후로 꾸준히 발전해왔다. HTTP는 TCP 또는 TLS-encrypted TCP connection 상에서 돌아가는 애플리케이션 레이어 프로토콜이다. 이론적으론, 트랜스포트 프로토콜 중 신뢰성 있는(reliable) 프로토콜이면 어떤 것이어도 상관이 없다.
클라이언트와 서버 사이...
출발지인 클라이언트와 목적지 서버 사이엔 수 많은 중간 노드들이 있다. 이들을 통칭하는 것이 바로 프록시(proxy)이다. 프록시 서버는 인터넷의 여러 네트워크들을 해쳐나갈 때 만나게 되는 중간에 있는 프로그램이나 컴퓨터를 뜻한다. 프록시 서버는 웹 상에 있는 컨텐츠들에 더 쉽게 접근할 수 있도록 해주는 역할을 한다.
브라우저와 서버 사이엔 이와 같이 요청을 처리하는 많은 컴퓨터들이 있다. 그러나 이들은 종종 눈에 잘 들어나지 않는다. 웹은 레이어드 형식으로 디자인되어 있고, 중간에 있는 이 프록시 서버들은 네트워크(OSI 3계층)와 트렌스포트(4계층) 레이어에 감추어져 있는 반면 HTTP는 가장 맨 위, 애플리케이션 레이어라 불리는 7계층에 있기 때문이다.
네트워크 문제를 진단할 때 OSI 7계층에서 HTTP 아래에 있는 있는 계층들을 아는 것은 정말 중요하지만, HTTP를 설명하는 데엔 큰 연관이 없다고 한다 (출처).
HTTP의 특징
1. 간편하다
HTTP는 비교적 쉽게 읽을 수 있다. HTTP/2에서 메시기자 암호화된다 하더라도 여전히 보기 편하다.
2. 확장성이 있다 (extensible)
HTTP/1.0에 HTTP headers가 추가되었다. HTTP 프로토콜은 이를 통해 쉽게 확장될 수 있다.
3. 무상태성(stateless)이지만 session을 가질 수도 있다
HTTP는 상태가 없다. 즉, 같은 연결 상 순서대로 진행된 두 개의 요청은 서로 완전 개별적이다. 다만, HTTP 핵심 그 자체는 무상태성을 가지나, 쿠키를 사용해서 상태가 있는 세션을 사용할 수 있다.
4. HTTP와 Connections
Connection은 트랜스포트 레이어에서 관리되는 것이기 때문에, 근본적으론 HTTP가 포함하는 범위는 아니다. 사실 HTTP 가 트렌스포트 프로토콜에 요구하는 사항에 Connection 기반이 되어야 한다는 조건은 없다. 다만 신뢰성(reliability)가 있어서 메시지를 잃어버리지만 않으면 된다.
인터넷에서 가장 자주 사용되는 트렌스포트 프로토콜 두 가지는 TCP와 UDP이다. 이중 TCP는 신뢰성이 있으나 UDP는 없다. 그래서 HTTP는 TCP를 기반으로 하며, 우연스럽게도(?) TCP는 connection 기반이기도 하다.
클라이언트와 서버는 HTTP 요청/응답을 본격적으로 교환하기 전에, 우선 먼저 TCP 연결을 성사시켜야 한다. 이를 TCP 3way handshakes라고 부르는데, 이와 관련해선 이전 포스팅에 상세한 설명을 적어놓았다:
2021.08.24 - [Learn to Code] - 웹 성능 개선을 위한 브라우저 작동 원리 이해
옛날의 HTTP/1.0에선 각 HTTP 요청/응답 때마다 별도의 TCP 연결을 오픈하는 것이 기본이었다고 한다. 하지만 이는 짧은 시간에 요청 여러개가 보내지고 하는 경우 하나의 TCP 연결을 사용하는 것보다 비효율적이다. 그래서 이러한 단점을 극복하고자 HTTP/1.1에 'pipelining'과 'persistent connections'가 도입되었고, 이로 인해 Connection 해더를 사용해서 TCP 연결을 부분적으로나마 컨트롤할 수 있게 되었다. HTTP/2는 여기서 좀 더 나아가서, 한 개의 연결 위에 복합적인 메시지들이 전달될 수 있도록해서 더욱 효율적으로 커낵션을 유지하도록 했다.
현재까지도 HTTP에 더 맞는 트렌스포트 프로토콜을 디자인하려는 노력이 진행 중이라고 한다.
2021.10.24 - [Learn to Code] - HTTP/1.1 vs. HTTP/2
HTTP로 할 수 있는 것들
위 HTTP의 특징에서 언급한 것과 같이 HTTP는 확장성이 있는 프로토콜이다. 이 확장성은 해더를 통해 무언가 설정이 변경이 가능함으로서 발생되는 것이다. 해더의 설정을 이용하면 웹을 더 용이하게 컨트롤할 수 있게 되며, 더 많은 기능들을 사용할 수 있게 된다.
HTTP를 통해 컨트롤 가능한 주요 기능들
캐싱(caching): 문서가 어떻게 캐싱될지 설정할 수 있다. 서버는 프록시들과 클라이언트에게 어떤 데이터를 얼마 동안이나 캐싱해야할 지 알려줄 수 있으며, 클라이언트는 중간에 있는 캐시 프록시에게 저장된 문서를 무시하게 설정하는 등의 일을 할 수 있다.
CORS: 스누핑 및 개인정보 도용을 방지하기 위해서, same origin policy가 생겨났다. 이는 웹앱을 로드할 때 하나의 출처(origin. 도메인, 스킴(scheme), 포트)에서 온 페이지들만 접근할 수 있게 하는 것이다. 이러한 same origin policy는 HTTP 해더를 통해 좀더 느슨하게 변경하여 원하는데로 리소스를 받아오도록 설정할 수 있다.
Authentication: 특정 유저들만 접근이 가능하도록 보호받는 페이지들이 있을 수 있다. 이는 http 쿠키를 사용해서 특정 세션을 설정할 수 있다.
Proxy와 tunnelling: 서버 또는 클라이언트는 종종 인트라넷 내부에 있고, 실제 IP 주소를 다른 컴퓨터들로부터 감추기도 한다. 이럴 경우, HTTP 요청은 이 네트워크 장벽을 넘어서기 위해 프록시들을 통과한다.
세션: HTTP 쿠키를 사용하면, 요청을 서버의 상태와 연결시킬 수 있다. 이를 통해 HTTP가 기본적으론 무상태성임에도 불구하고 세션을 생성할 수 있게 된다.
'Learn to Code' 카테고리의 다른 글
[JS] 정규표현식 (2) (0) | 2021.10.02 |
---|---|
[JS] 제너레이터란(Generator)?! (0) | 2021.10.02 |
[JS] 스코프(Scope)란? (0) | 2021.09.30 |
[JS] 웹팩(Webpack)과 바벨(Babel): 바닐라 자바스크립트에 처음부터 적용시켜보기 (2) | 2021.09.09 |
[프로젝트] React component: 마운트(mount)될 때와 언마운트(unmount)될 때 각기 다른 애니메이션 적용하기 (feat. onanimationend 프로퍼티) (0) | 2021.09.01 |
댓글