HTTP(HyperText Transfer Protocol)
✔️ 요약
HTTP(HyperText Transfer Protocol)은 텍스트 기반의 통신 규약으로 인터넷에서 데이터를 주고 받을 수 있는 프로토콜입니다.
이렇게 규약을 정해두었기 때문에 모든 프로그램이 이 규약에 맞춰 개발해서 서로 정보를 교환할 수 있게 되었습니다.
✔️ HTTP 동작
클라이언트. 즉, 사용자가 브라우저를 통해서 어떠한 서비스를 URL을 통하거나 다른 것을 통해서 요청(Request)을 하면 서버에서는 해당 요청사항에 맞는 결과를 찾아서 사용자에게 응답(Response)하는 형태로 동작합니다.
HTML 문서만이 HTTP 통신을 위한 유일한 정보 문서는 아닙니다.
Plain text로부터 JSON 데이터 및 XML과 같은 형태의 정보도 주고 받을 수 있으며, 보통은 클라이언트가 어떤 정보를 HTML 형태로 받고 싶은지, JSON 형태로 받고 싶은지 명시해주는 경우가 많습니다.
✔️ HTTP 특징
- HTTP 메시지는 요청/응답 방식으로 동작하며 HTTP서버와 HTTP 클라이언트에 의해 해석이 됩니다.
- TCP/IP를 이용하는 응용 프로토콜입니다.
- HTTP는 연결 상태를 유지하지 않는 비연결성 프로토콜입니다. 이러한 단점을 해결하기 위해 Cookie와 Session이 등장했습니다.
- 커스텀 헤더를 추가 가능하여 n개로 확장이 가능합니다.
✔️ HTTP의 기본 아키텍처
- HTTP는 클라이언트/서버 기반 아키텍처를 기반으로 하는 요청/응답 프로토콜입니다.
- 웹 브라우저, 검색 엔진 등은 클라이언트로 동작하고 Servlet과 같은 웹 서버는 서버로 동작합니다.
✔️ HTTP의 예시
클라이언트 프로그램에서 사용자가 회원가입을 시도하게 되면, 서버로 회원정보를 보내게 되고 서버는 회원 정보를 저장해주기도 합니다.
이 과정에서 클라이언트와 서버 간의 교류가 HTTP라는 규약을 이용하여 발생하게 됩니다.
📌 Request (요청)
클라이언트가 서버에게 연락하는 것을 요청이라고 하며 요청을 보낼 때는 요청에 대한 정보를 담아 서버로 보냅니다.
예를 들어, 서버가 주문서를 받아 클라이언트가 어떤 것을 원하는지 파악할 수 있게 합니다.
이처럼 요청은 식당에서 주문서를 작성하는 것과 같다고 생각하면 됩니다.
- Request HTTP 메시지 예시
GET https://www.naver.com/ HTTP/1.1 // 시작줄
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... // 헤더
Upgrade-Insecure-Requests: 1
1. 시작줄 (첫 줄)
첫 줄은 시작줄로 메서드 구조 버전으로 구성되었습니다.
- GET : HTTP MEthod
- https://www.naver.com/ : 사이트 주소
- HTTP/1.1 : HTTP 버전
2. 헤더 (두 번째 줄부터)
두 번째 줄부터는 헤더이며 요청에 대한 정보를 담고 있습니다.
User-Agent, Upgrade-Insecure-Requests 등등이 헤더에 해당되며 헤더의 종류는 매우 많습니다.
3. 본문 (헤더에서 한 줄 띄고)
본문은 요청할 때 함께 보낼 데이터를 담는 부분입니다. 현재 예시에는 단순히 주소로만 요청을 보내고 있고 따로 데이터를 담아 보내지 않기 때문에 비어 있습니다.
📌 Response (응답)
서버가 요청에 대한 답변을 클라이언트에게 보내는 것을 응답이라고 합니다.
- Response HTTP 메시지 예시
HTTP/1.1 200 OK // 시작줄
Connection: keep-alive // 헤더
Content-Encoding: gzip
Content-Length: 35653
Content-Type: text/html;
<!DOCTYPE html><html lang="ko" data-reactroot=""><head><title...
1. 시작줄 (첫 줄)
첫 줄은 버전 상태코드 상태메시지로 구성되어 있습니다. 200은 성공적인 요청이었다는 뜻입니다.
2. 헤더 (두 번째 줄부터)
두 번째 줄부터는 헤더로 응답에 대한 정보를 담고 있습니다.
3. 본문 (헤더 뒤부터)
응답에는 대부분의 경우 본문이 있습니다. 보통 데이터를 요청하고 응답 메시지에는 요청한 데이터를 담아서 보내주기 때문입니다.
응답 메시지에 HTML이 담겨 있는데 이 HTML을 받아 브라우저가 화면에 렌더링합니다.
✔️ HTTP method
주요 메소드 5가지(GET, POST, PUT, PATCH, DELETE)와 기타 메소드 4가지(HEAD, OPTIONS, CONNECT, TRACE)가 있습니다.
GET | GET [request-uri]?query_string HTTP/1.1\r\n Host:[Hostname] 혹은 [IP] \r\n |
GET 요청 방식은 URI(URL)가 가진 정보를 검색하기 위해 서버측에 요청하는 형태입니다. |
POST | POST [request-uri]?query_string HTTP/1.1\r\n HOST:[Hostname] 혹은 [IP] \r\n Content-Lenght:[Lenght in Bytes] \r\n \r\n [query-string] 혹은 [데이터] |
POST 요청 방식은 요청 URI(URL)에 폼 입력을 처리하기 위해 구성한 서버 측 스크립트(ASP, PHP, JSP 등) 혹은 CGI 프로그램으로 구성되고 Form Action과 함께 전송되는데, 이때 헤더 정보에 포함되지 않고 데이터 부분에 요청 정보가 들어가게 됩니다. |
HEAD | HEAD [request-uri] HTTP/1.1\r\n Host:[Hostname] 혹은 [IP] \r\n |
HEAD 요청 방식은 GET과 유사한 방식이나 웹 서버에서 헤더 정보 이외에는 어떤 데이터도 보내지 않습니다. 웹 서버의 다운 엽 점검(Health Check)이나 웹 서버 정보(버전 등) 등을 얻기 위해 사용될 수 있습니다. |
OPTION | OPTIONS [request-ri] HTTP/1.1\r\n Host:[Hostname] 혹은 [IP] \r\n |
해당 메소드를 통해 시스템에서 지원되는 메소드 종류를 확인할 수 있습니다. |
PUT | PUT [request-uri] HTTP/1.1\r\n Host:[Hostname] 혹은 [IP] \r\n Content-Lenght:[Length in Bytes] \r\n Content-Type:[Content Type] \r\n \r\n [데이터] |
POST와 유사한 전송 구조를 가지기 때문에 헤더 이외에 메시지(데이터)가 함께 전송됩니다. 원격지 서버에 지정한 콘텐츠를 저장하기 위해 사용되며 홈페이지 변조에 많이 악용되고 있습니다. |
DELETE | DELETE [request-uri] HTTP/1.1\r\n Host:[Hostname] 혹은 [IP] \r\n \r\n |
원격지 웹 서버에 파일을 삭제하기 위해 사용되며 PUT과는 반대 개념의 메소드입니다. |
TRACE | TRACE [request-uri] HTTP/1.1\r\n Host:[Hostname] 혹은 [IP] \r\n \r\n |
원격지 서버에 Loopback 메시지를 호출하기 위해 사용됩니다. |
CONNECT | CONNECT [request-uri] HTTP/1.1\r\n Host:[Hostname] 혹은 [IP] \r\n \r\n |
웹 서버에 프록시 기능을 요청할 때 사용됩니다. |
📌 GET 과 POST 의 비교
- GET myServer/getItem?name=hamburger HTTP/1.1
- URL에 쿼리 스트링을 추가해서 보냅니다 (소용량)
- 리소스를 얻어오기 위해 사용합니다 (헤더만 있고 바디가 없음)
- URL에 데이터가 노출되므로 보안에 취약하고 데이터 공유에 유리합니다.
- POST myServer/getItem HTTP/1.1
- Body에 쿼리 스트링을 추가해서 보냅니다 (대용량)
- 서버에 정보를 제공하거나 저장할 때 사용합니다.
- 데이터를 Body에 담아 전송하므로 보안에 유리하고 데이터 공유에 불리합니다.
📌 HTTP method의 속성
1. 안전(Safe Methods)
계속해서 메소드를 호출해도 리소스를 변경하지 않는다는 뜻입니다.
즉, 주요 메소드 중에는 GET 메소드가 안전하다고 볼 수 있습니다.
2. 멱등(Idempotent Methods)
메소드를 계속 호출해도 결과가 똑같다는 뜻입니다.
GET, PUT, DELETE는 멱등하다고 볼 수 있지만 POST나 PATCH는 멱등하다고 볼 수 없습니다.
3. 캐시가능(Cacheable Methods)
캐싱을 해서 데이터를 효율적으로 가져올 수 있다는 뜻입니다.
GET, HEAD, POST, PATCH가 캐시가 가능하지만 실제로는 GET과 HEAD만 주로 캐싱이 쓰인다고 합니다.
✔️ HTTP Status Code
클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능입니다.
- 1XX (조건부 응답) : 요청을 받았으며 작업을 계속한다.
- 2XX (성공) : 클라이언트가 요청한 동작을 수신하여 이해했고 승낙했으며 성공적으로 처리했음을 가리킨다.
- 3XX (리다이렉션 완료) : 클라이언트는 요청을 마치기 위해 추가 동작을 취해야 한다.
- 4XX (요청 오류) : 클라이언트에 오류가 있음을 나타낸다
- 5XX (서버 오류) : 서버가 유효한 요청을 명백하게 수행하지 못했음을 나타낸다
📌 Status code 더 자세히 보기
200번대는 성공을 의미하는 뜻인데 더 자세하게는 다음과 같습니다.
- 200 OK : 요청 성공
- 201 Created : 요청 성공해서 새로운 리소스가 생성됨
- 202 Accepted : 요청이 접수되었으나 처리가 완료되지 않았음
- 204 No Content : 서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없음
300번대는 리다이렉션인데 이는 location 헤더가 있으면 location 위치로 자동 이동하는 것을 리다이렉트라고 합니다.
- 301 Moved Permanently : 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
- 302 Found : 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
- 303 See Other : 리다이렉트시 요청 메서드가 GET으로 변경
- 304 Not Modified : 캐시를 목적으로 사용
- 307 Temporary Redirect : 리다이렉트시 요청 메서드와 본문 유지(요청 메서드를 변경하면 안된다.)
- 308 Permanent Redirect : 리다이렉트시 요청 메서드와 본문 유지(처음 POST를 보내면 리다이렉트도 POST 유지)
400번대는 클라이언트 측에서 오류가 발생했다고 알려주는 것입니다.
- 400 Bad Request : 클라이언트가 잘못된 요청을 해서 서버가 요청을 처리할 수 없음
- 401 Unauthorized : 클라이언트가 해당 리소스에 대한 인증이 필요함
- 403 Forbidden : 서버가 요청을 이해했지만 승인을 거부함
- 404 Not Found : 요청 리소스를 찾을 수 없음
500번대는 서버 측에서 오류가 발생했다고 알려주는 것입니다.
- 500 Internal Server Error : 서버 문제로 오류 발생, 애매하면 500 오류
- 503 Service Unavailable : 서비스 이용 불가
✔️ HTTP의 발전
📌 HTTP 1.0
기본적으로 Connection 당 하나의 요청을 처리할 수 있습니다.
그렇기 때문에 동시 전송은 불가능하고 하나의 요청에 대한 응답이 온 후 다음 요청을 처리하게 됩니다.
웹사이트에 수 많은 멀티미디어 리소스들이 있는 상황에서 이러한 특징은 Network Latency를 발생시킵니다.
📌 HTTP 1.1
HTTP 1.0의 문제를 해결하기 위해 HTTP Pipelining이 도입되었습니다.
이는 TCP 안에 두 개 이상의 HTTP 요청을 담아 Network Latency를 줄이는 방식입니다.
하지만 이는 정확히 구현하기 힘들뿐 아니라 Header가 무겁고 HOL Blocking이 발생합니다.
- 무거운 Header
클라이언트와 서버 간에 수 많은 HTTP 요청이 발생할 것이고 Header의 정보는 대부분 동일합니다.
하지만 HTTP 1.1에서는 이러한 Header를 중복해서 계속 보낼 뿐 아니라 Cookie 정보 역시 매 요청마다 Header에 포함되어 전송됩니다.
즉 불필요한 데이터를 주고 받는데 네트워크 자원이 소비되는 문제가 발생합니다.
- HOL Blocking
HOL(Head of Line) Blocking은 앞선 요청에 의해 뒤에 요청이 지연되는 것을 의미합니다.
Pipeline에서 한 번에 여러 개의 요청을 할 경우 가장 앞에 요청이 지연되면 그 뒤 요청들도 지연이 발생합니다.
📌 HTTP 1.1을 개선하기 위한 노력
- Image Spriting
여러 이미지 파일들에 대해 각각 요청을 하기 보다 한 번에 요청으로 끝내기를 택했습니다.
여러 이미지를 모아 하나의 큰 이미지를 만든 후, CSS로 해당 이미지의 좌표값을 지정해서 사용합니다.
- Domain Sharding
하나의 Domain에 대해 여러 개의 Connection을 생성하여 병렬로 요청을 보냅니다.
하지만 브라우저 별로 Domain당 Connection 개수의 제한이 존재하므로 근본적인 해결책이 될 수 없습니다.
- CSS, Javascript 최소화
전송되는 데이터의 용량을 줄이기 위해 CSS, Javascript 파일을 최소화하여 통신합니다.
📌 HTTP 2.0
HTTP 2.0은 기존 HTTP 1.1을 개선하는 방향에서 성능 쪽에 초점을 맞춘 프로토콜로서 구글의 SPDY를 기반하였습니다.
- Multiplexed Streams
HTTP 1.1의 HTTP pipelining의 개선안으로 하나의 Connection으로 동시에 여러 개의 메시지를 주고 받을 수 있습니다.
또한 응답은 요청 순서에 상관없이 Stream으로 받기 때문에 HOL Blocking도 발생하지 않습니다.
- Stream Prioritization
응답에 대한 우선순위를 정해 우선순위가 높을수록 응답을 빨리 합니다.
예를 들어 하나의 HTML 문서에 CSS 파일과 여러 IMG 파일이 있다고 가정해보겠습니다.
만일 여러 IMG 파일을 응답하느라 CSS 파일의 응답이 느려지면 클라이언트는 렌더링을 하지 못하고 기다리게 됩니다.
따라서 CSS 파일의 우선순위를 올려 렌더링을 진행하며 IMG 파일은 도착하는대로 띄워준다면 더 효율적입니다.
- Server Push
서버가 클라이언트의 요청없이 응답을 보내는 방법입니다.
위와 마찬가지로 하나의 HTML 문서에 CSS파일과 여러 IMG 파일이 있다고 가정해보겠습니다.
기존에는 HTML 문서를 요청한 후 다시 각각의 CSS 파일과 여러 IMG 파일을 위한 요청을 보내야 했습니다.
하지만 Server Push로 인해서 클라이언트의 요청을 최소화하고 서버가 리소스를 알아서 보내줍니다.
- Header Compression
HTTP 1.1의 경우 이전 요청과 중복되는 Header도 똑같이 전송하느라 네트워크 자원을 불필요하게 낭비하였습니다.
HTTP 2.0의 경우 Header Table과 Huffman Encoding을 사용하는 HPACK 압축방식으로 이를 개선하였습니다.
클라이언트와 서버는 각각 Header Table을 관리하고 이전 요청과 동일한 필드는 table의 index만 보내고, 변경되는 값은 Huffman Encoding 후 보냄으로써 Header의 크기를 경량화하였습니다.
📄 참고
https://velog.io/@surim014/HTTP%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80
https://developer.mozilla.org/ko/docs/Web/HTTP/Status
https://ssungkang.tistory.com/entry/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-HTTP-11-VS-HTTP-20