목차
1. 일반 헤더
1) 헤더 개요
- HTTP 전송에 필요한 모든 부가정보
- 표준 헤더가 너무 많음
- 필요시 임의의 헤더 추가 가능
- 1999년 표준이 폐기되고 2014년 RFC723x 등장
2) 표현
표현의 의미
HTML에 들어있는 리소스는 추상적이다. 이를 클라이언트와 서버가 주고 받을 때, 서로 이해할 수 있는 무언가로 변환해서 데이터를 전달해야한다. DB에 있는 바이너리 데이터를 그대로 전달할 수는 없으니, HTML이든 JSON이든으로 변환해서 표현하기 때문에 "표현"이라는 단어를 사용한다.
표현의 종류
1) Content-Type
- Content Body에 들어가는 내용이 무엇인지를 알려준다.
- 컨텐츠가 text/html이라면 html의 텍스트 application/json이라면 json을 의미한다.
2) Content-Encoding
- 표현 데이터를 압축한 방법에 대한 정보
- 압축한 방법을 모르면 데이터를 받는 쪽에서 압축을 풀 수 없으므로, 방법에 대한 정보가 필요하다.
3) Content-Language
- 표현 데이터의 언어에 대한 정보
- 예를 들어 한국에서 영어로 되어있는 사이트에 접속했을 때, Language 정보가 다르므로 자동해석같은 기능을 팝업창에 띄우는 등의 동작을 할 수 있다.
4) Content-Length
- 표현 데이터의 길이이다.
- 바이트 단위이다.
- Transfer-Encoding(전송 코딩)의 경우 Content-Length를 사용하면 안됨
3) 콘텐츠 협상
종류
- Accept: 클라이언트가 선호하는 미디어 타입 전달
- Accept-Charset: 클라이언트가 선호하는 문자 인코딩
- Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
- Accept-Language: 클라이언트가 선호하는 자연언어
Accept-Language 예시
예를들어Accpet-Language에 ko(한국어)를 요청하면 어떻게 될까? 다중 언어를 지원하는 서버이지만 아쉽게도 한국어는 지원하지않는다. 이런 경우를 해결하기 위해 우선순위라는 개념이 있다.
협상과 우선순위
요청 메시지에 우리는 위와 같이 여러개의 값을 담아 전송할 수 있다. 협상의 우선순위는 클수록 높다.
- ko-KR;q=1(1일 때 q는 생략된다)
- ko;q=0.9
- en-US;q=0.8
- en:q=0.7
우선순위는 위와 같이 정리할 수 있다. 아까의 예시에서 비록 한국어는 지원하지 않지만, 그 다음의 우선순위에 en이 있으므로 영어로 값을 전달해주게 된다.
협상과 우선순위2
언어요청 외에도, 데이터의 종류에 대해서도 요청의 우선순위를 전달할 수 있다. 이러한 경우 구체적인 것이 우선한다는 원칙을 기준으로 정리해볼 수 있다.
- text/plain;format=flowed
- text/plain
- text/*
- */*
순으로 우선순위를 결정할 수 있다.
4) 전송 방식
컨텐츠의 길이를 알 때 단순하게 요청하고 한번에 쭉 받는다.
Content-Encoding 메타데이터를 추가로 넣어 압축해 전송한다.
용량이 큰 경우 분할해서 전송한다. 이땐 Content-length를 넣지 않는다.
중간에 받다가 끊겼을 경우, 처음부터 다시받기보단 받은 부분이후부터 받는 것이 효율적이다. 이러한 경우 범위를 지정해 전송한다.
5) 일반 정보
From
유저 에이전트의 이메일 정보
Referer
이전 웹 페이지 주소
- 유입 경로 분석을 위해 사용
User-Agent
유저 에이전트의 애플리케이션 정보
- user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) /Chrome ....
- 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능
Server
요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
Date
메시지가 발생한 날짜와 시간
6) 특별한 정보
Host
요청한 호스트 정보(도메인)
예를들어, 한 IP에 여러 도메인이 있다고 하자. 그럼 서버입장에서는 어떤 도메인으로 들어오는지를 알아야 한다. 따라서 이를 식별하기 위한 Host라는 정보가 있다.
Location
페이지 리다이렉션
응답코드 3xx에서 설명함
201 (Created): Location 값은 요청에 의해 생성된 리소스 URI
3xx (Redirection): Location 값은 요청을 자동으로 리다이렉션하기 위한 대상 리소스를 가리킴
Allow
허용 가능한 HTTP 메서드
Retry-After
유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
7) 쿠키
쿠키 미사용
로그인 이후 다시 페이지를 접속하는 경우, 서버에서는 로그인 한 사용자 정보가 없기 때문에 사용자를 인식할 수 없다. 왜냐하면 HTTP는 무상태 프로토콜이기 때문이다. 클라이언트와 서버가 요청과 응답을 주고 받으면 연결이 끊어지고, 서버는 이전 요청을 기억하지 못한다.
대안 1 - 모든 요청에 사용자 정보를 포함
보안 문제가 있고, 모든 요청에 사용자 정보가 포함되도록 개발 해야함
대안 2 - 쿠키
쿠키는 유저들의 효율적이고 안전한 웹 사용을 위해 웹사이트에서 널리 사용되고 있다. 쿠키는 웹사이트 접속 후 통신이 끊기기 전 접속자의 개인장치에 다운로드되고 브라우저에 저장되는 작은 파일이다. 따라서 로그인 이후 다시 페이지에 접속하는 경우, 쿠키 저장소에서 값을 조회해 로그인 상태 등을 유지한 채로 웹 사이트에 접속할 수 있다.
쿠키는 한개에4KB까지 저장 가능하며, 최대 300개까지 저장할 수 있다. 쿠키에는 이름, 값, 만료날짜, 도메인, 경로정보가 들어있다. 하지만 이러한 쿠키는 보안에 있어서는 치명적인 단점이 될 수 있다. 예를 들어 로그인을 위한 정보를 쿠키에 담는다면, 클라이언트에 저장된 아이디와 비밀번호가 노출될 수 있다. 이에 따라 세션이라는 개념이 등장했는데, 이는 중요한 정보는 서버에서 관리하고, 클라이언트에게는 세션 쿠키(세션ID)를 주어 식별이 가능하도록 한 것이다.
2. 캐시와 조건부 요청 헤더
1) 캐시 기본 동작
개념
데이터나 값을 미리 복사해놓는 임시 저장소이다. 캐시는 저장 공간이 작고 비용이 비싼 대신 빠른 성능을 제공한다. 브라우저에서 같은 리소스를 요청할 때마다 리소스를 가져오는 것은 낭비이다. 따라서 이를 방지하기 위해 임시로 저장한다는 것이 필요하게 되었는데, 이것이 캐시이다.
캐시가 없을 때
- 데이터가 변경되지 않아도 계속 네트워크를 통해 데이터를 다운로드 받아야 한다.
- 인터넷 네트워크는 매우 느리고 비싸다.
- 브라우저 로딩 속도가 느려진다.
캐시 사용
- 비싼 네트워크 사용량을 줄이고 브라우저 로딩속도를 향상시킬 수 있다.
2) 검증 헤더와 조건부 요청1
캐시 유효시간이 지나면, 서버로부터 리소스를 다시 가져와야 한다. 하지만, 만약 리소스가 똑같은 것이라면 이를 다시 가져오는 것은 낭비이다. 이러한 문제를 해결하기 위한 매커니즘이 있는데 바로 검증 헤더와 조건부 요청이다. 서버의 리소스가 변경되지 않았다는 것만 알 수 있다면, 로컬에 있던 캐시를 사용할 수 있다. 이는 검증 헤더라는 것을 통해 체크할 수 있는데, 아래의 Last-Modified가 바로 그것이다. 서버는 리소스를 전달할 때 Last-Modified에 마지막 수정 일자 데이터를 같이 보낸다.
이제 캐시 시간이 초과되고 클라이언트에서 똑같은 리소스를 요청한다고 생각해보자. 서버에서 받았던 수정 일자가 그대로 서버에 전달된다. 만약 서버의 마지막 수정 일자가 변경되지 않아, 둘이 같다는 것을 검증한다.
둘이 같다면, 서버는 HTTP 응답(304)에 Body를 넣지 않고 보낸다. 이후 응답을 받은 클라이언트는 헤더 데이터를 갱신하고, 로컬 캐시에 있던 리소스를 사용하게 된다.
하지만 데이터를 수정해서 날짜가 다르지만, A->B , B->A로 데이터 결과가 똑같은 경우는 어떨까? 이런 경우 날짜가 달라 리소스를 다시 받게 될 것이다. 이런 것을 해결하기 위해 Etag라는 것이 있다.
3) 검증 헤더와 조건부 요청2
Etag
특정 버전의 리소스를 식별하는 식별자로 웹 서버의 내용을 확인하고 변하지 않았으면, 웹 서버로 full 요청을 보내지 않기 때문에, 캐시가 더 효율적이게 되고, 대역폭도 아낄 수 있다.
4) 캐시와 조건부 요청 헤더
Cache-Control(캐시 지시어)
(1) Cache-Control: max-age
캐시 유효 시간, 초 단위
(2) Cache-Control: no-cache
데이터는 캐시해도 되지만, 항상 origin 서버에 검증하고 사용
(3) Cache-Control: no-store
데이터에 민감한 정보가 있으므로 저장하면 안됨
Pragma(캐시 제어)
Expires(캐시 만료일 지정)
하위 호환이라 잘 사용하지 않음.
5) 프록시 캐시
한국에서 미국 등 물리적으로 멀리 있는 나라의 서버와 통신하려면 시간이 오래걸린다. 따라서 이러한 문제를 해결하기 위해 중간 어딘가에 프록시 캐시 서버라는 것을 둔다. 쉽게 생각해서 아래처럼 동작한다고 보면된다.
그렇다면 프록시 서버가 정확히 무엇일까? 클라이언트 사이의 중계기로서 대리로 통신을 수행하는 것을 '프록시'라고 하며, 그 중계 기능을 하는 것을 프록시 서버라고 한다. 프록시 서버 중 일부는 프록시 서버에 요청된 내용들을 캐시를 이용하여 저장해둔다. 이렇게 캐시를 해 두고 난 이후, 캐시 안의 정보를 요구하는 요청에 대해서는 orign 서버에 접속해 데이터를 가져올 필요가 없게 된다. 이를 통해, 전송 시간을 줄이고, 불필요하게 origin 서버와의 연결을 하지 않게 된다. 또한 외부와의 트래픽을 줄여 네트워크 병목 현상도 방지할 수 있다.
Cache-Control(캐시 지시어)
(1) Cache-Control: public
응답이 public 캐시에 저장되어도 됨
(2) Cache-Control: private
응답이 해당 사용자만을 위한 것임. private 캐시에 저장되어야 됨
(3) Cache-Control: s-maxage
프록시 캐시에만 적용되는 max-age
(4) Age: 60(HTTP 헤더)
origin 서버에서 응답 후 프록시 캐시 내에 머문 시간
6) 캐시 무효화
캐시를 하면 아예 안되는 경우가 있는데, 이를 위한 방법엔 여러가지가 있다. 하지만 완벽히 무효화를 하려면, 모든 것을 다 사용해야 한다고 한다.
Cache-Control(캐시 지시어)
(1) Cache-Control: no-cache
데이터는 캐시해도 되지만, 항상 origin 서버에 검증하고 사용(이름이 헷갈림)
(2) Cache-Control: no-store
데이터에 민감한 정보가 있으므로 저장하면 안됨
(3) Cache-Control: must-revalidate
캐시 만료후 최초 조회 시 origin 서버에 검증해야한다. 서버 접근 실패시 504오류. 캐시 유효시간인 경우엔 캐시를 사용한다.
(4) Pragma: no-cache
http 1.0을 쓰는 사이트를 위해 넣어준다.
no-cache vs must-revalidate
no-cache는 캐시가 만료된 경우, 예전의 응답조차 주지 않는다. 하지만 must-revalidate는 캐시가 만료된 경우에 예전의 응답을 준다.
본 포스팅은 김영한님 인프런 HTTP 강의를 듣고 복습용으로 기록하였습니다.
'IT > HTTP' 카테고리의 다른 글
[HTTP] HTTP 상태코드 (0) | 2022.06.04 |
---|---|
[HTTP] HTTP 메서드 (0) | 2022.06.04 |
[HTTP] HTTP 기본 (0) | 2022.06.03 |
[HTTP] 인터넷 네트워크 (0) | 2022.06.01 |