이 글은 김영한님의 인프런 강의인 모든 개발자를 위한 HTTP 웹 기본 지식 강의를 요약한 것입니다.
HTTP(HyperText Transfer Protocol)
을 활용하면 HTML 텍스트뿐만 아니라 모든 것을 전송할 수 있다.
HTML
, TEXT
, 이미지
, 음성
, 영상
, 파일
, JSON
, XML
, 서버 간에 데이터를 주고 받을 때도
등등!
HTTP는 1991년 HTTP/0.9가 등장한 이래 현재 가장 많이 사용하는 1997년의 HTTP/1.1, 2015년 HTTP/2, 현재 진행형인 HTTP/3로 발전해 왔다.
HTTP/1.1: 가장 많이 사용, 대부분의 기능이 여기 들어 있음. TCP.
RFC2068(1997) -> RFC2616(1999) -> RFC7230~7235(2014)HTTP/2: 성능 개선. TCP.
HTTP/3: 현재 진행형, 성능 개선. UDP.
개발자 도구의 네트워크 탭에서 protocol 컬럼을 활성화 하면 어느 네트워크 프로토콜을 사용하는지 알 수 있다. 예를 들어, h2는 HTTP/2, h3은 HTTP/3이다.
stateful은서버가 클라이언트의 이전 상태를 보존한다는 의미이다. 반대로 무상태(stateless)는 서버가 클라이언트의 이전 상태를 보존하지 않는다는 의미이다. 승객과 매표 직원의 대화를 예시로 보면서 이해해 보자.
stateful
승객: 서울에서 전주 가는 KTX는 얼마인가요?
직원: 25,000원입니다.승객: 2장 주세요.
직원: 50,000원입니다. 결제는 무엇으로 하시겠습니까? (KTX 노선과 주문 수량에 대한 상태를 유지)승객: 체크카드입니다.
직원: 결제과 완료되었습니다. (KTX 노선과 주문 수량, 결제 수단에 대한 상태를 유지)
stateless
승객: 서울에서 전주 가는 KTX는 얼마인가요?
직원: 25,000원입니다.승객: 2장 주세요.
직원: ??? 무엇을 2장 구매하시는 건가요???승객: 아까 말했잖아요😳. 서울에서 전주 가는 KTX요!!!
직원: 몇 장인지, 결제 수단은 무엇인지 한 번에 얘기해주세요!
stateful은 우리가 일상에서 대화를 할 때와 비슷하다. 대화를 주고 받을 때 마다(요청과 응답) 상대는 문맥의 상태를 유지한다. 하지만 stateless에서는 대화가 오고 갈 때 마다 상대는 그 문맥의 상태를 모른 체 대화를 한다고 보면 된다 혹은 상대가 계속 바뀐다고 볼 수도 있다. 한꺼번에 이야기 해야한다. "서울에서 전주가는 KTX 2장 체크카드로 결제할게요!"
stateful의 경우에는 상태를 유지해야 하므로 항상 같은 서버가 유지되어야 한다. 하지만 stateless는 상태를 보관하지 않으므로 클라이언트의 요청에 어느 서버가 응답해도 상괸이 없다. 따라서 클라이언트의 요청이 대폭 증가해도 서버를 증설해 해결할 수 있다.
하지만 모든 것을 stateless로 설계할 수 없다. 단순히 로그인만 보더라도 사용자가 로그인한 상태를 서버에 유지시켜 주어야 한다. 이 경우에는 브라우저 쿠키나 서버 세션 등을 사용해 상태를 유지한다.
비연결성은 클라이언트가 서버에 요청을 하고 응답을 받으면 바로 TCP/IP 연결을 끊어 연결을 유지 하지 않는 것이다. 이를 통해 서버의 자원을 효율적으로 관리하고, 수 많은 클라이언트의 요청에도 대응할 수 있게 한다. HTTP는 연결을 유지하지 않는 모델을 기본으로 한다. 수 천명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청
은 수 십개 이하로 작다(예를 들어 구글을 수 천명이 이용해도 검색을 수 천명이 동시에 이용하지는 않는다. 하지만 현대카드 슈퍼콘서트 예매처럼 정말 수 십만명이 한꺼번에 몰리는 경우도 있다😂).
현재는 HTTP 지속 연결(Persisten Connections)로 문제를 해결했다. 지속 연결은 요청에 따라 연결이 된 이후 일정 시간 연결을 유지하거나 여러 개의 요청(HTML, 자바스크립트, 이미지 등)에 대한 응답이 다 올 때 까지 기다린 후 연결을 종료하는 것이다(더 자세히 알아봐야겠다🧐). HTTP/2, HTTP/3에서는 최적화를 이루었다.
HTTP 메시지는 HTTP 요청 메시지와 HTTP 응답 메시지로 구분한다. 기본적으로 HTTP 메세지 구조는 아래와 같다.
start-line 시작 라인
header 헤더
empty line 공백 라인(CRLF, 필수)
message body
HTTP 요청 메시지 예시
GET /search?q=hello&hl=ko HTTP/1.1
Host: www.google.com
(CRLF)
message body
HTTP 응답 메시지 예시
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 4432
(CRLF)
message body
(1) 요청 메시지
GET /search?q=hello&hl=ko HTTP/1.1
요청 메시지에서는 request-line으로 불린다.
request-line = HTTP 메서드
(SP: 공백)요청 대상
(SP: 공백)HTTP 버전
CRLF
HTTP 메서드: GET, POST, PUT, DELETE 등
요청 대상: "/"로 시작하는 절대 경로로 작성(절대경로[?쿼리])
(2) 응답 메시지
HTTP/1.1 200 OK
응답 메시지에서는 status-line으로 불린다.
status-line =
HTTP 버전
(SP)상태 코드
(SP)상태 문구(reason-phrase)
상태 코드: 200(성공), 300(리다이렉션), 400(클라이언트 오류), 500(서버 오류)
상태 문구: 상태 코드에 대한 짧은 문구
Host: www.google.com
Content-Type: text/html;charset=UTF-8
Content-Length: 4432
header-field = 필드 이름":" (OWS: 띄어쓰기 허용) 필드 값 (OWS)
필드 이름: 필드 이름은 대소문자 구분 없음. 필드 이름 다음에 띄어쓰기 없이 ":"가 와야 함.
HTTP 헤더는 HTTP 전송에 필요한 모든 부가 정보(표준 헤더가 굉장히 많다)가 들어 있다. 필요시 임의의 헤더도 추가할 수 있다.
message body는 실제 전송할 데이터이다. HTML, 이미지, 영상, JSON 등 byte로 표현할 수 있는 모든 데이터를 전송할 수 있다.