HTTP
는 HyperText Transfer Protocol의 약자다.
HTTP
는 인터넷 상에서 클라이언트와 서버가 자원을 주고 받을 때 쓰는 통신 규약이다.
HTML 문서, 이미지, 동영상과 같은 자원들을 가져올 수 있도록 해주는 프로토콜이다.
HTTP는 웹에서 이루어지는 모든 데이터 교환의 기초이고, 클라이언트와 서버 프로토콜이기도 하다.
클라이언트와 서버들은 메시지 교환에 의해 통신하게 된다.
클라이언트(웹 브라우저)에 의해 전송되는 메시지가 요청(Request)
이고, 그에 대한 서버에서의 응답으로 전송되는 메시지가 응답(Response)이다.
HTTP
는 메시지 교환, 즉 텍스트를 교환하는 방식이기 때문에, 네트워크 상에서 메시지를 가로채면 내용이 노출되는 보안 이슈가 존재한다.
이를 해결해주는 프로토콜이 HTTPS 이다.
HTTP
는 애플리케이션 계층의 프로토콜로 확장 가능한 프로토콜이다.
신뢰 가능한 전송 프로토콜이라면 이론상으로는 무엇이든 사용할 수 있으나 대부분의 경우 TCP
혹은 암호화된 TCP 연결인 TLS
를 통해 전송된다.
HTTP는 사람이 쉽게 읽을 수 있게 간단하게 고안되었다.
심지어 HTTP/2
가 다소 더 복잡해졌지만 여전히 HTTP 메세지를 프레임별로 캡슐화하여 간결함을 유지하였다.
HTTP 메시지들은 사람이 읽고 이해할 수 있어 테스트하기 쉽다.
HTTP/1.0에서 소개된, HTTP 헤더
는 HTTP를 확장하고 실험하기 쉽게 만들어주었다.
클라이언트와 서버가 새로운 헤더에 대해 간단한 합의만 한다면, 언제든지 새로운 기능을 추가할 수 있다.
HTTP는 상태를 저장하지 않는다.(Stateless
)
동일한 연결 상에서 연속하여 전달된 두 개의 요청 사이에는 연결고리가 없다.
e-커머스 쇼핑처럼 사용자의 정보가 필요하고, 사용자가 페이지와 상호작용 하길 원할 때 문제가 된다.
HTTP의 핵심은 상태가 없는 것이지만, HTTP 쿠키로 상태가 있는 세션을 만들수 있다.
헤더 확장성을 사용하여 동일한 상태를 공유하기 위해 각각의 요청들에 세션을 만들도록 HTTP 쿠키가 추가된다.
HTTP/1.1와 초기 HTTP 메시지는 사람이 읽을 수 있다.
HTTP/2
에서, 이 메시지들은 새로운 이진 구조인 프레임 안으로 임베드되어, 헤더의 압축과 다중화와 같은 최적화를 가능하게 한다.
본래의 HTTP 메시지의 일부분만이 이 버전의 HTTP 내에서 전송된다고 할지라도, 각 메시지의 의미들은 변화하지 않으며 클라이언트는 본래의 HTTP/1.1 요청을 가상으로 재구성한다.
그러므로 HTTP/1.1 포맷 내에서 HTTP/2를 이해하는 것은 여전히 유용하다.
HTTP 메시지의 두 가지 타입인 요청(Requests)
과 응답(Responses)
은 각자의 특성있는 형식을 가지고 있다.
요청은 다음의 요소들로 구성된다.
보통 클라이언트가 수행하고자 하는 동작을 정의한 GET, POST 같은 동사나 OPTIONS나 HEAD와 같은 명사이다.
일반적으로, 클라이언트는 GET을 사용하여 리소스를 가져오거나 POST를 사용하여 HTML 폼의 데이터를 전송하려고 하지만, 다른 경우에는 다른 동작이 요구될 수도 있다.
예를 들면 프로토콜 (http://), 도메인 (여기서는 developer.mozilla.org), 또는 TCP 포트 (여기서는 80)인 요소들을 제거한 리소스의 URL이다.
HTTP 프로토콜의 버전
서버에 대한 추가 정보를 전달하는 선택적 헤더들
POST와 같은 몇 가지 메서드를 위한, 전송된 리소스를 포함하는 응답의 본문과 유사한 본문이다.
응답은 다음의 요소들로 구성된다.
HTTP 프로토콜의 버전
요청의 성공 여부와, 그 이유를 나타내는 상태 코드
아무런 영향력이 없는, 상태 코드의 짧은 설명을 나타내는 상태 메시지
요청 헤더와 비슷한, HTTP 헤더들
선택 사항으로, 가져온 리소스가 포함되는 본문
HTTP
는 클라이언트-서버 프로토콜로 애플리케이션 계층의 최상위에 위치한다.
Reuqest
는 하나의 개체, 사용자 에이전트나 그것을 대신하는 프록시에 의해 전송된다.
대부분 웹 브라우저
각각의 개별적인 Request
들은 서버로 보내지며, 서버는 요청을 처리하고 Response
라고 불리는 응답을 제공한다.
이 Request
와 Response
사이에는 여러 개체들이 있는데, 예를 들면 다양한 작업을 수행하는 게이트웨이
또는 캐시 역할을 하는 프록시
등이 있다.
실제로는 브라우저와 Request
을 처리하는 서버 사이에는 좀 더 많은 컴퓨터들이 존재한다.
라우터, 모뎀 등
웹의 계층적인 설계 덕분에, 이들은 네트워크와 전송 계층 내로 숨겨진다.
사용자 에이전트는 주로 브라우저
에 의해 수행되는 사용자를 대신하여 동작하는 모든 도구이다.
애플리케이션을 디버그하는 웹 개발자들과 엔지니어들이 사용하는 프로그램들은 예외
브라우저
는 항상 요청을 보내는 개체다.
웹 페이지를 표시하기 위해, 브라우저
는 페이지의 HTML 문서를 가져오기 위한 요청을 전송한 뒤, 파일을 구문 분석하여 실행해야 할 스크립트 그리고 페이지 내 포함된 하위 리소스들(보통 이미지와 비디오)을 잘 표시하기 위한 레이아웃 정보(CSS)에 대응하는 추가적인 요청들을 가져온다.
그런 뒤에 브라우저
는 완전한 문서인 웹 페이지를 표시하기 위해 그런 리소스들을 혼합한다.
브라우저에 의해 실행된 스크립트는 이후 단계에서 좀 더 많은 리소스들을 가져올 수 있으며 브라우저는 그에 따라 웹 페이지를 갱신하게 된다.
웹 페이지
는 하이퍼텍스트 문서로, 표시된 텍스트의 일부는 사용자가 사용자 에이전트를 제어하고 웹을 돌아다닐 수 있도록 새로운 웹 페이지를 가져오기 위해 실행 될 수 있는 링크임을 뜻한다.
브라우저
는 HTTP 요청 내에서 이런 지시 사항들을 변환하고 HTTP 응답을 해석하여 사용자에게 명확한 응답을 표시해준다.
통신 채널의 반대편에는 클라이언트에 의한 요청에 대한 문서를 제공하는 서버가 존재한다.
서버는 사실 상 논리적으로 단일 기계로서 로드 밸런싱 혹은 그때 마다 다른 컴퓨터(캐시, DB 서버, e-커머스 서버 등)들의 정보를 얻고 부분적이나 완전하게 문서를 생성하는 소프트웨어의 복잡한 부분을 공유하는 서버들의 집합이다.
서버는 반드시 단일 머신일 필요는 없지만, 여러 개의 서버를 동일한 머신 위에서 호스팅 할 수도 있다.
HTTP/1.1과 Host 헤더를 이용하여, 동일한 IP 주소를 공유할 수도 있다.
웹 브라우저와 서버 사이에서는 수많은 컴퓨터와 머신이 HTTP 메시지를 이어 받고 전달한다.
여러 계층으로 이루어진 웹 스택 구조에서 이러한 컴퓨터/머신들은 대부분은 전송, 네트워크 혹은 물리 계층에서 동작하며, 성능에 상당히 큰 영향을 주지만 HTTP 계층에서는 이들이 어떻게 동작하는지 눈에 보이지 않는다.
이러한 컴퓨터/머신 중에서도 애플리케이션 계층에서 동작하는 것들을 일반적으로 프록시라고 부른다.
프록시는 눈에 보이거나 프록시를 통해 요청이 변경되거나 변경되지 않는 경우 눈에 보이지 않을 수 있고, 다양한 기능들을 수행할 수 있다.
클라이언트가 서버와 통신하고자 할 때, 최종 서버가 됐든 중간 프록시가 됐든, 다음 단계의 과정을 수행한다.
TCP 연결은 요청을 보내거나(혹은 여러개의 요청) 응답을 받는데 사용된다.
클라이언트는 새 연결을 열거나, 기존 연결을 재사용하거나, 서버에 대한 여러 TCP 연결을 열 수 있다.
HTTP/2 이전의 HTTP 메시지는 인간이 읽을 수 있다.
HTTP/2에서는 이런 간단한 메시지가 프레임 속으로 캡슐화되어, 직접 읽는게 불가능하지만 원칙은 동일하다.
GET / HTTP/1.1
Host: developer.gil.log
Accept-Language: kr
HTTP/1.1 200 OK
Date: WED, 28 Oct 2020 08:12:02 GMT
Server: Apache
Last-Modified: Tue, 28 Oct 2020 08:11:22 GMT
ETag: "51142bc1-7449-479b075b2891b"
Accept-Ranges: bytes
Content-Length: 29769
Content-Type: text/html
<!DOCTYPE html... (here comes the 29769 bytes of the requested web page)
4. 연결을 닫거나 다른 요청들을 위해 재사용한다.
HTTP 파이프라이닝
이 활성화되면, 첫번째 응답을 완전히 수신할 때까지 기다리지 않고 여러 요청을 보낼 수 있다.
HTTP 파이프라이닝은 오래된 소프트웨어와 최신 버전이 공존하고 있는, 기존의 네트워크 상에서 구현하기 어렵다는게 입증되었으며, 프레임안에서 보다 활발한 다중 요청을 보내는 HTTP/2로 교체되고 있다.
연결은 전송 계층에서 제어되므로 근본적으로 HTTP 영역 밖이다.
HTTP는 구체적인 전송 프로토콜을 요구하지 않고, 신뢰할 수 있거나 메시지 손실이 없거나 오류를 표시 해줄 수 있는 연결을 요구한다.
인터넷 상 가장 일반적인 두 개의 전송 프로토콜 중 TCP는 신뢰할 수 있으며 UDP는 아니다.
그러므로 HTTP는 연결이 필수는 아니지만 연결 기반인 TCP 표준에 의존한다.
클라이언트와 서버가 HTTP를 요청/응답으로 교환하기 전에 여러 왕복이 필요한 프로세스인 TCP 연결을 설정해야한다.
HTTP/1.0의 기본 동작은 각 요청/응답에 대해 별도의 TCP 연결을 여는 것이다.
이 동작은 여러 요청을 연속해서 보내는 경우에는 단일 TCP 연결을 공유하는 것보다 효율적이지 못하다.
이러한 결함을 개선하기 위해, HTTP/1.1은 파이프라이닝 개념과 지속적인 연결의 개념을 도입했다.
기본적인 TCP 연결은 Connection 헤더를 사용해 부분적으로 제어할 수 있다.
HTTP/2
는 단일 연결 상에서 메시지를 다중 전송(multiplex)하여 연결을 좀 더 지속되고 효율적으로 유지하는데 발전했다.