HTTP 프로토콜
- HTTP(Hypertext Transfer Protocol)는 인터넷상에서 데이터를 주고 받기 위한 서버/클라이언트 모델을 따르는 프로토콜
- HTML, TEXT, IMAGE, 음성, 영상, 파일 ,JSON, XML (API) 등 거의 모든 형태의 데이터 전송 가능
- 서버간에 데이터를 주고 받을 때도 대부분 HTTP 사용
HTTP 특징
- 클라이언트 서버 구조
- 무상태 프로토콜(Stateless), 비연결성 HTTP 메시지
- 단순함, 확장 가능
HTTP의 요청/응답 모델
Request Response 구조
- 클라이언트는 서버에 요청을 보내고, 응답을 대기
- 서버가 요청에 대한 결과를 만들어서 응답
HTTP 메서드
GET
- 리소스 조회
- 서버에 전달하고 싶은 데이터는 query(쿼리 파라미터, 쿼리 스트링)를 통해서 전달
- 메시지 바디를 사용해서 데이터를 전달할 수 있지만, 지원하지 않는 곳이 많아서 권장하지 않음
POST
- 요청 데이터 처리
- 메시지 바디를 통해 서버로 요청 데이터 전달
- 서버는 요청 데이터를 처리
- 메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행한다.
- 주로 전달된 데이터로 신규 리소스 등록, 프로세스 처리에 사용
- ex) JSON으로 조회 데이터를 넘겨야 하는데, GET 메서드를 사용하기 어려운 경우 등 애매한 경우 POST 사용
PUT
1. 리소스를 대체
- 리소스가 있으면 대체
- 리소스가 없으면 생성
- 쉽게 이야기해서 덮어버림
2. 클라이언트가 리소스를 식별
- 클라이언트가 리소스 위치를 알고 URI 지정 (PUT /members/{memberId})
- POST와의 차이점
※ 리소스를 완전히 대체
/members/100
{
"age": 20,
"username":"oyeon"
}
- username 필드가 없는 다음과 같은 PUT 요청을 보내면
{
"age": 50
}
기존에 있던 age는 50으로 변경되고, username은 완전히 대체되기 때문에 날아간다.
PATCH
- 리소스를 부분 변경
- 위의 예시를 적용해도 username은 삭제되지 않음
- PATCH가 사용되지 않는 서버의 경우 POST 사용하면 됨
HTTP 상태 코드란? 종류
클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능
2xx (Successful)
3xx (Redirection)
4xx (Client Error)
- 클라이언트 오류, 잘못된 문법등으로 서버가 요청을 수행할 수 없음
5xx (Server Error)
- 서버 오류, 서버가 정상 요청을 처리하지 못함
HTTP 헤더
- HTTP 전송에 필요한 모든 부가 정보
- ex) 메시지 바디의 내용, 메시지 바디의 크기, 압축, 인증, 요청 클라이언트, 서버 정보, 캐시 관련 정보
표현 헤더
표현: 요청이나 응답에서 전달할 실제 데이터
- 표현 데이터를 해석할 수 있는 정보 제공
- Content-Type, Content-Encoding, Content-Language, Content-Length
협상 헤더
협상: 콘텐츠 네고시에이션
- 협상 헤더는 요청시에만 사용
- 우선순위로 Quality Values(q) 값 사용
- 구체적인 것이 우선 된다 (1. text/plain;format=flowed, 2. text/plain, 3. text/, 4. /*)
- Accept: 클라이언트가 선호하는 미디어 타입 전달
- Accept-Charset: 클라이언트가 선호하는 문자 인코딩
- Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
- Accept-Language: 클라이언트가 선호하는 자연 언어
일반 정보
- From: 유저 에이전트의 이메일 정보
- Referer: 이전 웹 페이지 주소
- User-Agent: 유저 에이전트 애플리케이션 정보
- Server: 요청을 처리하는 오리진 서버의 소프트웨어 정보
- Date: 메시지가 생성된 날짜
특별한 정보
- Host: 요청한 호스트 정보(도메인)
- Location: 페이지 리다이렉션
- Allow: 허용 가능한 HTTP 메서드
- Retry-After: 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
인증 헤더
- Authorization: 클라이언트 인증 정보를 서버에
- WWW-Authenticate: 리소스 접근시 필요한 인증 방법 정의
쿠키 헤더
- Set-Cookie: 서버에서 클라이언트로 쿠키 전달(응답)
- Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청시 서버로 전달
검증 헤더
- 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
- Last-Modified: 데이터가 마지막에 수정된 시간
- ETag(Entity Tag): 캐시용 데이터에 임의의 고유한 버전 이름 달아둠. 데이터 변경시 이름을 바꾸어 변경
조건부 요청 헤더
- 검증 헤더로 조건에 따른 분기
- If-Modified-Since: 캐시가 가지고 있는, Last-Modified
- If-None-Match: 캐시가 가지고 있는, ETag
- 조건이 만족하면 200 OK
- 조건이 만족하지 않으면 304 Not Modified
캐시 제어 헤더
- Cache-Control: 캐시 제어
- Pragma: 캐시 제어(하위 호환)
- Expires: 캐시 유효 기간(하위 호환)
HTTP의 무상태성(Stateless)
- 서버가 클라이언트의 상태를 보존 X
- 점원A, B, C (서버) 예시
장점
- 서버 확장성 높음(스케일 아웃)
- 중간에 서버가 장애가 나도 서버가 상태를 보관하고 있지 않으므로 다른 서버에 요청하면 된다.
단점
한계
- 모든 것을 stateless 하게 설계할 수는 없음
- ex) 로그인의 경우 쿠키, 서버 세션등을 사용해서 상태 유지
HTTP/1.0 비 연결성(connectionless)
- HTTP는 기본이 연결을 유지하지 않는 모델
- 일반적으로 초 단위의 이하의 빠른 속도로 응답
- 1시간 동안 수천명이 서비스를 사용해도 실제 서버에서 동시에 처리하는 요청은 수십개 이 하로 매우 작음
- 예) 웹 브라우저에서 계속 연속해서 검색 버튼을 누르지는 않는다.
- 서버 자원을 매우 효율적으로 사용할 수 있음
한계
- TCP/IP 연결을 새로 맺어야 함 - 3 way handshake 시간 추가
- 웹 브라우저로 사이트를 요청하면 HTML 뿐만 아니라 자바스크립트, css, 추가 이미지 등
등 수 많은 자원이 함께 다운로드
극복
- 지금은 HTTP 지속 연결(Persistent Connections)로 문제 해결
- HTTP/2, HTTP/3에서 더 많은 최적화
지속 연결(Persistent Connections) (feat. keep-alive)
- HTTP 1.0 초기의 HTTP 연결은 요청시 TCP 의 3-way handshake 방식으로 연결이 이루어졌었다.
- 즉, client, server 간의 연결 성립 이후 SYN, SYN-ACK, ACK handshaking이 발생하고 이를 바탕으로 통신을 구성한 뒤 연결을 끊는 순서가 필요했다.
- 웹의 초창기에는 컨텐츠의 수가 많지 않았기 때문에 이런 TCP 연결은 부담되지 않았지만, 웹을 통한 멀티미디어 컨텐츠의 발달로 인해, TCP Connection 의 재사용이 요구되게 되었다.
- 웹에서의 커넥션 재사용을 Keep-alive 또는 Connection reuse 라 하며, HTTP/1.0 에서는 클라이언트가 서버에게 요청하는 Request Header에 다음과 같은 값을 통해 연결을 유지하였다.
Connection: keep-alive
HTTP/1.1 에서는 이 헤더를 사용하지 않더라도 모든 요청/응답이 Connection을 재사용하도록 설계되어 있으며, 필요없는 경우에만 TCP 연결을 종료하는 방식으로 변경되었다.
Connection: close
해제 시에 위와 같은 명시적 Connection 헤더를 이용하며, 그렇지 않은 경우 무조건 연결은 재사용되게 되어 있다.
HTTP 파이프라이닝
- HTTP/1.1 로 스펙이 업그레이드 되면서 클라이언트와 서버간 요청과 응답의 효율성을 개선하기 위해 만들어진 개념
- HTTP Request 들은 연속적으로 발생하며, 순차적으로 동작한다.
- HTTP/1.0 에서 HTTP Request 는 소켓에 write 한뒤, 서버의 Response 를 받아 다음 Request 를 보내는 방식으로 웹이 동작한다.
- 여러 요청에 대해 여러 응답을 받고, 각 처리가 대기되는 것은 Network Latency 에 있어서 큰 비용을 요구한다.
- 게다가 HTTP/1.0 에서 HTTP 요청들은 연결의 맺고 끊음을 반복하기 때문에 서버 리소스 적으로도 비용을 요구한다.
- HTTP/1.1 에서는 다수의 HTTP Request 들이 각각의 서버 소켓에 write 된 후, Browser 는 각 request 들에 대한 response 들을 순차적으로 기다리는 문제를 해결하기 위해 여러 요청들에 대한 응답 처리를 뒤로 미루는 방법을 사용한다.
- 즉, HTTP/1.1 에서 클라이언트는 각 요청에 대한 응답을 기다리지 않고, 여러개의 HTTP Request 를 하나의 TCP/IP Packet 으로 연속적으로 Packing 해서 요청을 보낸다.
- 파이프라이닝이 적용되면, 하나의 Connection 으로 다수의 Request 와 Response 를 처리할 수 있게끔 Network Latency 를 줄일 수 있다.
- 하지만 위의 기법 설명에서 언급하듯이, 결국 완전한 Multiplexing이 아닌 응답처리를 미루는 방식이므로 각 응답의 처리는 순차적으로 처리되며, 결국 후순위의 응답은 지연될 수 밖에 없다.
- 이는 HTTP의 Head Of Line Blocking 이라 부르며 Pipelining 의 큰 문제점이다.
- 따라서 HTTP/1.1 의 웹서버는 서버측에 Multiplexing 을 통한 요청의 처리를 요구하며, 각 Connection 당 요청과 응답의 순서가 보장되는 통신을 한다.
- HTTP 파이프라이닝은 HTTP/2 가 등장하면서 Multiplexing 알고리즘으로 대체되었고, 모던 브라우저들에서도 기본적으로는 활성화하지 않고 있다.
HTTP/1.1, HTTP/2, HTTP/3 특징
HTTP/1.1
- TCP 기반으로 개발되어 있음
- 1997년: 가장 많이 사용, 중요한 버전
- RFC2068 (1997) -> RFC2616(1999) -> RFC7230~7235(2014)
- Head Of Line Blocking 문제 발생
HTTP/2
- TCP 기반으로 개발되어 있음
- Multiplexing 알고리즘으로 HTTP 파이프라이닝 대체하여 Head Of Line Blocking 문제 해결
HTTP/3
reference
https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard
https://shlee0882.tistory.com/107
https://etloveguitar.tistory.com/137
https://jins-dev.tistory.com/entry/HTTP11-%EC%9D%98-HTTP-Pipelining-%EA%B3%BC-Persistent-Connection-%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC