[네트워크] HTTP 기초 - HTTP의 기본
HTTP기초
1. 모든 것이 HTTP
HTTP는 HyperText Transfer Protocol의 약자로 html같은 하이퍼텍스트를 전송하는 프로토콜 약속으로 시작했지만 지금은 모든 것을 HTTP를 통해 하고 있다. HTML, TEXT 뿐만 아니라 IMAGE, 음성, 영상, 파일은 물론 JSON, XML(API) 등 거의 모든 형태의 데이터 전송이 가능하다. 게다가 서버간에 데이터를 주고 받을 때도 대부분 HTTP를 사용한다.
HTTP는 1991년에 0.9 버전을 시작하여 현재 HTTP/3 버전까지 나와있지만 1997년에 나온 HTTP/1.1 버전을 가장 많이 사용하고, 우리에게 제일 중요한 버전이다. 이후 나온 HTTP/2와 HTTP/3는 성능 개선에만 초점이 맞춰져있다. HTTP/1.1은 세분화 하면 1997년에 나온 REC2068, 1999의 RFC2616, 2014년의 RFC7230~7235로 나눠져 있는데 50% 이상 1999년의 RFC2616을 기준으로 하고 있다.
기반 프로토콜은 HTTP/1.1, HTTP/2는 안정적인 TCP를 기반으로 하고 있고 최근 속도를 중시하여 HTTP/3가 UDP를 기반으로 두고 있다.
HTTP 특징은 다음과 같다
- 클라이언트 서버 구조
- 무상태 프로토콜(스테이스리스), 비연결성
- HTTP 메세지
- 단순함, 확장 가능
2. 클라이언트 서버 구조
HTTP는 기본적으로 Request Response 구조로 이뤄져 있다. 클라이언트는 서버에 요청을 보내고, 응답을 대기한다. 서버는 요청에 대한 결과를 만들어서 응답하는 구조이다. 이렇게 클라이언트와 서버를 분리하는 것이 중요하다. 복잡한 비즈니스 로직와 데이터는 서버에서 처리하게 만들고 클라이언트는 UI에 집중한다. 그래서 양쪽이 독립적으로 진화할 수 있게 된다.
3. 무상태 프로토콜
무상태 프로토콜은 서버가 클라이언트의 상태를 보존하지 않는 다는 뜻이다. 이전의 상황을 기억하고 상태를 유지하는 것이 Stateful, 상태 유지이다. 그러면 무상태, Stateless는 이와 반대로 이전 상황을 유지 하지 않는다는 것을 말한다. 이렇게보면 무상태는 부정적으로 보이지만 무상태는 이전 상황을 유지하지 않기 때문에 어떤 상황에서든 대응할 수 있는 데이터를 응답한다. 무상태는 응답 서버를 쉽게 바꿀 수 있고 서버를 대거 투입할 수 있어 무한한 확장성을 가질 수 있게 만든다. 그리고 무한한 서버 증설이 가능해 진다.
상태 유지는 항상 같은 서버가 유지되어야 한다. 반면 무상태는 아무 서버나 호출해도 된다. 그래서 스케일 아웃이라고 수평 확장을 하는 것에 매우 유리하다.
그러나 무상태도 실무에서 한계가 있다
- 모든 것을 무상태로 설계할 수 있는 경우도 있고 없는 경우도 있음
- 무상태 : 예) 로그인이 필요없는 단순한 서비스 소개 화면
- 상태유지 : 예) 로그인
- 로그인한 사용자의 경우 로그인 했다는 상태를 서버에 유지
- 일반적으로 브라우저 쿠키와 서버 세션등을 사용해서 상태 유지
- 상태 유지는 최소한만 사용
그리고 최대 단점으로 데이터를 너무 많이 사용한다^^
4. 비연결성(connectionless)
TCP/IP는 항상 연결이 되어 있는 상태를 유지한다. 그동안 서버 자원이 소모가 된다. 반면 연결을 유지하지 않는 모델은 서버 연결을 유지 하지 않으므로 최소한의 자원을 유지한다.
- HTTP는 기본이 연결을 유지하지 않는 모델
- 일반적으로 초 단위의 이하의 빠른 속도로 응답
- 1시간 동안 수천명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청은 수십개 이하로 매우 작음:
예) 웹 브라우저에서 계속 연속해서 검색 버튼을 누르지 않는다. - 서버 자원을 매우 효율적으로 사용할 수 있음
이런 장점이 있는 반명 서버 연결을 유지 하지 않음으로써 얻는 단점도 존재한다.
- TCP/IP 연결을 새로 맺어야 함 - 3way handshake 시간 추가
- 웹 브라우저로 사이트를 요청하면 HTML 뿐만 아니라 자바스크립트, CSS, 추가 이미지등등 수많은 자원이 함께 매번 다운로드
이런 단점을 극복하기 위해 지금은 HTTP 지속 연결(Persistent Connections)로 문제를 해결한다. 그리고 HTTP/2, HTTP/3에서 더 많은 최적화가 이뤄졌다.
5. HTTP 메시지
저번 포스트에서 잠깐 언급했듯이 HTTP는 요청 메시지와 응답메시지 형태가 다르다. 그러나 HTTP 메시지 구조는 공통적으로 4가지로 구성되어 있다.
- start-line 시작 라인
- header 헤더
- empty line 공백 라인(CRLF)
- message body
이를 적용해서 보면 요청 메시지는,
GET/search?1=hello&hl=ko HTTP/1.1 : 시작라인
Host:www.google.com : 헤더
공백 라인
그리고 응답 메시지는 다음과 같다.
HTTP/1.1 200 OK : 시작라인
Content-Type: text/html;charset=UTF-8
Content-Length: 3423 : 헤더
공백라인
“<html>
</html>:message body” </br> 공식 스펙은 다음 형태를 띄고 있다.
HTTP-message = start-line
*(header0field CRLF)
CRLF
[message-body] ### 5.1. 요청 메시지 시작 라인의 요청 메시지는 request-lin/ status-line 에서 request-line이다.<br> request-line = method SP(공백) request-target SP HTTP-version CRLF(엔터)
- http 메서드(GET:조회)
- 서버가 수행해야 할 동작 지정
- GET: 리소스 조회
- POST: 요청내역 처리
- 서버가 수행해야 할 동작 지정
- 요청대상(/search?q=hello&hl=ko)
- absolute-path?query
- 절대경로=”/”로 시작하는 경로
- HTTP Version
5.2. 응답메시지
시작 라인의 응답 메시지는 request-lin/ status-line 에서 status-line이다.
status-line = HTTP-version SP status-code SP reason-phrase CRLF
- HTTP 버전
- HTTP 상태코드: 요청 성공, 실패를 나타냄
- 200: 성공
- 400: 클라이언트 요청 오류
- 500: 서버 내부 오류
- 이유 문구: 사람이 이해할 수 있는 짧은 상태 코드 설명 글
그다음 HTTP 헤더를 보면 다음 형태로 되어있다
header-field = field-name “:” OWS field-value OWS(OWS:띄어쓰기 허용)
field-name은 대소문자 구문 없음
HTTP 헤더는 다음과 같은 용도를 지닌다.
- HTTP 전송에 필요한 모든 부가정보
- 예) 메시지 바디의 내용, 메시지 바디의 크기, 압축, 인증, 요청 클라이언트(브라우저) 정보, 서버 애플리케이션 정보, 캐시 관리 정보…
- 표준 헤더가 너무 많음
- 필요시 임의의 헤더 추가 가능
그다음 HTTP 메시지 바디가 있다. 메시지 바디는 실제 전송할 데이터를 표시하고 모든 데이터 전송이 가능하다.
- 실제 전송할 데이터
- HTML 문서, 이미지, 영상 JSON 등등 byte로 표현할 수 있는 모든 데이터 전송 가능