본문 바로가기
네트워크/HTTP

[HTTP] 헤더 정리

by jeonghaemin 2021. 4. 29.
728x90

본 게시글은 김영한 님의 모든 개발자를 위한 HTTP 웹 기본 지식강의를 수강하며 정리한 것입니다.

HTTP 헤더

  • HTTP 전송에 필요한 모든 부가정보를 전송할 수 있도록 해준다.
  • 예 : 메시지 바디의 내용, 메시지 바디의 크기, 압축, 인증, 요청 클라이언트, 서버 정보, 캐시 정보 등등
  • 많은 개수의 표준 헤더가 있다.
  • 필요시 임의의 헤더를 추가할 수 있다.
  • 구조 : field-name ":" OWS field-value OWS
    • field-name은 대소문자를 구분한다.
    • OWS : Optional Whitespace, 띄어쓰기 허용

HTTP 표준

  • 1999년 RFC2616(현재는 폐기됨)
  • 2014년 RFC7230~7235 등장

RFC2616(과거)

HTTP 헤더 분류

  • General 헤더 : 메시지 전체에 적용되는 정보. (예: Connections: close)
  • Request 헤더 : 요청 정보(예: User-Agent: Mozilla/5.0 (Macintosh; ..)
  • Response 헤더 : 응답 정보(예: Server: Apach)
  • Entity 헤더: 엔티티 바디 정보(예: Content-Type: text/html)

  • 엔티티 본문 : 요청이나 응답에서 실제로 전달할 데이터
  • 메시지 본문(message body) : 엔티티 본문(entity body)을 전달하는 데 사용
  • 엔티티 헤더 : 엔티티 본문의 데이터를 해석할 수 있는 정보를 제공(예: 데이터 유형, 데이터 길이, 압축 정보 등)

RFC7230(최신)

RFC723x 변경점

  • 용어 변경 : 엔티티(Entity) → 표현(Representation)
  • 표현 = 표현 메타데이터 + 표현 데이터

  • 메시지 본문(message body) : 표현 데이터를 전달하는 데 사용, 페이로드(payload)라고도 한다.
  • 표현(표현 헤더 + 표현 데이터) : 요청이나 응답에서 전달할 실제 데이터
  • 표현 헤더 : 표현 데이터를 해석할 수 있는 정보 제공(데이터 유형, 데이터 길이, 압축 정보 등등)

참고 : 표현 헤더는 표현 메타데이터와, 페이로드 메시지를 구분해야 하지만 복잡해지기 때문에 생략한다.

HTTP 헤더의 분류

표현

Content-Type

  • 표현 데이터의 형식
  • 미디어 타입, 문자 인코딩
  • 예) text/html; charset=utf-8, application/json, image/png

참고: application/json은 기본 문자 인코딩이 utf-8

Content-Encoding

  • 표현 데이터의 압축 인코딩
  • 데이터를 전달하는 쪽에서 압축 후 인코딩 헤더를 추가하고 읽는 쪽에서 인코딩 헤더의 정보를 보고 적절히 압축을 해제하여 사용
  • 예) gzip, deflate, identity(압축 x)

Content-Language

  • 표현 데이터의 자연 언어
  • 예) ko, en, en-US

Content-Length

  • 바이트 단위의 표현 데이터 길이
  • Transfer-Encoding을 사용하면 Content-Length 사용하면 안 됨

협상(Content Negotiation)

  • 클라이언트가 선호하는 표현을 요청
  • 협상 헤더는 요청 시에만 사용

협상 헤더의 종류

  • Accept : 클라이언트가 선호하는 미디어 타입
  • Accept-Charset : 클라이언트가 선호하는 문자 인코딩
  • Accept-Encoding : 클라이언트가 선호하는 압축 인코딩
  • Accept-Language : 클라이언트가 선호하는 자연 언어

협상 헤더의 우선순위

q(Quality Values) 값을 사용하여 필드 값의 우선순위를 적용할 수 있음

  • 0~1 범위의 값을 사용하며 클수록 높은 우선순위를 가짐(생략 시 1)
  • 예 : Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8
    1. ko-KR;q=1(생략)
    2. ko;q=0.9
    3. en-US;q=0.8

구체적인 것이 높은 우선순위를 가짐

  • Aceept: text/, text/plain, text/plain;format=flowed, */
    1. text/plain;format=flowed
    2. text
    3. text/*
    4. */ *

구체적인 것을 기준으로 미디어 타입을 맞춤

  • Accept: text/;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */;q=0.5

Aceept 헤더의 값이 위와 같을 때 미디어 타입에 따른 Quality 값은 다음과 같다.

전송 방식

서버에서 클라이언트로 전송하는 방식

주로 단순 전송, 압축 전송, 분할 전송, 범위 전송이 사용됨

단순 전송

  • Content-Length
  • 단순히 컨텐츠의 길이를 지정해주고 한 번에 요청하고 한번에 받는 방법
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
**Content-Length: 3423**

<html>
    ...
</html>

압축 전송

  • 메시지 본문을 압축하여 전송하는 방법
  • 용량이 절반 이상 줄어드는 경우가 많기 때문에 사용을 권고
  • Content-Encoding 헤더를 사용하여 압축 형식을 지정
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
**Content-Encoding: gzip**
Content-Length: 521

lkj123kljoiasudlkjaweioluywlnfdo912u34ljko98udjkl

분할 전송

  • 데이터를 분할하여 전송하는 방법
  • Transfer-Encoding: chunked
  • chunk : 덩어리
  • 분할 전송 시에는 Contetnt-Length 헤더를 사용하면 안 됨
    • 처음에 길이를 예상할 수 없음
    • 분할해서 보낼 때 청크마다의 바이트 길이를 알려줌
청크 길이(16진수)\r\n
청크 데이터\r\n

위와 같은 형식으로 청크를 전송하며, 전송이 끝날 시 청크 길이를 0으로 보내면 된다.

0\r\n
\r\n

예시

HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked

5\r\n
Hello\r\n
5\r\n
World\r\n
0\r\n
\r\n

범위 전송

  • 범위를 지정해서 일부분만 가져오는 방법

요청

Range 헤더 사용

Range: <unit>=<range-start>-
Range: <unit>=<range-start>-<range-end>
Range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>
Range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
  • : 범위를 결정하는 단위. 보통 bytes사용
  • : 범위 요청의 시작 지점을 알리는 단위를 뜻하는 정수
  • : 요청한 범위의 끝을 알리는 단위를 의미하는 정수. 옵션이며 생략 시엔 문서의 끝을 요청의 끝으로 사용

예시

GET /event
Range: bytes 1001~2000

응답

Content-Range 헤더 사용

Content-Range: <unit> <range-start>-<range-end>/<size>
Content-Range: <unit> <range-start>-<range-end>/*
Content-Range: <unit> */<size>
  • : 범위를 결정하는 단위. 보통 bytes사용
  • : 범위 요청의 시작을 알려주는 정수 단위
  • : 범위 요청의 끝을 알려주는 정수 단위
  • 문서의 총 크기. 모른다면 *

예시

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Range: bytes 1001~2000/2000

일반 정보

From

  • 유저 에이전트의 이메일 정보
  • 일반적으로 잘 사용되지 않고, 주로 검색 엔진 같은 곳에서 사용
  • 크롤러와 같은 로보틱 사용자 에이전트를 실행하고 있다면, 반드시 전송해야 함
  • 예) 검색 엔진 사이트에서 내 웹사이트를 크롤링을 할 때, 검색 엔진 담당자에게 연락해야 될 때 사용
  • 요청 헤더

Referer

  • 현재 요청된 페이지 이전 웹페이지 주소
  • A → B 사이트로 이동하는 경우 B 사이트를 요청할 때 Referer: A를 포함해서 요청
  • 예) google.com에서 검색을 통해 tistory.com에 접속할 때 Referer: google.com 을 포함해서 요청
  • 요청 헤더

User-Agent

  • User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36
  • 클라이언트의 애플리케이션 정보(웹 브라우저 정보 등등)
  • 활용
    • 통계 정보
    • 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능
  • 요청 헤더

Server

  • 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
  • 예)
    • Server: Apache/2.2.22(Debien)
    • Server: nginx
  • 응답 헤더

Date

  • 메시지가 발생한 날짜와 시간
  • Date: Tue, 15 Nov 1994 08:12:31 GMT
  • 응답 헤더(과거 스펙에선 요청에서도 사용했지만 최신 스펙에서는 응답에서만 사용)

특별한 정보

Host

  • 요청한 호스트의 정보(도메인)
  • 필수 헤더
  • 요청 헤더
  • 하나의 서버가 여러 도메인을 처리해야 할 때 구분에 사용
  • 하나의 IP주소에 여러 도메인이 적용되어 있을 때 구분에 사용

Location

  • 페이지 리다이렉션
  • 리다이렉션 : 웹브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동으로 이동
  • 201(Created) 응답에서 Location 값은 요청에 의해 새로 생성된 리소스의 URI

Allow

  • 허용 가능한 HTTP 메서드
  • 405(Method Not Allowed)에서 응답 헤더에 포함해야 함
  • 예) Allow: GET, HEAD, PUT

Retry-After

  • 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
  • 503(Service Unavailable) 응답의 경우에 서비스가 언제까지 불능인지 알려줄 수 있음
  • 예)
    • Retry-After: Fri, 31 Dec 1999 23:59:59 GMT (날짜 표기)
    • Retry-After: 120 (초단위 표기)

인증

Authorization

  • 클라이언트 인증 정보를 서버에 전달
  • 예) Authorization: Basic xxxxxxxxxxxxxxxx

WWW-Authenticate

  • 리소스 접근 시 필요한 인증 방법 정의
  • 401 Unauthorized 응답과 함께 사용
  • WWW-Authenticate: Newauth realm="apps", type=1, title="Login to "apps"", Basic realm="simple"

쿠키

Set-Cookie

  • 서버에서 클라이언트로 쿠키 전달
  • 응답 헤더

Cookie

  • 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청 시 서버로 전달
  • 요청 헤더
  • 사용처 : 사용자 로그인 세션 관리, 광고 정보 트래킹
  • 쿠키 정보는 항상 서버에 전송되기 때문에 네트워크 트래픽을 추가 유발
  • 보안에 민감한 데이터는 저장하면 안 됨(주민 번호, 신용카드 번호 등등)
  • 최소한의 정보만 사용해야 됨(세션 id, 인증 토큰)
  • 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지(localStorage, sessionStorage)를 참고

쿠키 - 생명주기

expires

  • 예) Set-Cookie: expires=Sat, 26-Dec-2020 04:39:21 GMT
  • 만료일이 되면 쿠키 삭제
  • 옵션 값이며, 지정하지 않으면 세션 쿠키로 취급되어 클라이언트 종료 시 쿠키 파기됨
    • 세션 쿠키 : 만료 날짜를 생략하면 브라우저 종료시 까지만 유지
    • 영속 쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지

max-age

  • 예) Set-Cookie: max-age=3600 (3600초)
  • 쿠키가 만료될 때까지의 시간(초 단위)
  • 0이나 음수를 지정하면 쿠키 삭제
  • Exprires와 함께 지정 시 max-age의 우선순위가 더 높음

쿠키 - 도메인

  • 예) domain=example.org
  • 명시 - domain=example.org 지정해서 쿠키 생성
    • 명시한 문서 기준 도메인 + 서브 도메인 포함
    • exmaple.org에 더해 dev.example.org도 쿠키 접근 가능
  • 생략 - exmple.org에서 쿠키를 생성하고 domain 지정 생략
    • exmaple.org에서만 쿠키 접근 가능
    • dev.exmaple.org에서는 쿠키 미접근 → 서브 도메인에서 접근 불가

쿠키 - 경로

  • 예) path=/home
  • 지정한 경로를 포함한 하위 경로 페이지만 쿠키 접근 가능
  • 일반적으로 루트를 지정(path=/)

쿠키 - 보안

  • Secure : 쿠키는 http, https를 구분하지 않고 전송하는데, Secure를 적용하면 https인 경우에만 쿠키를 전송
  • HttpOnly : XSS 공격 방지, 자바스크립트에서 접근 불가(document.cookie), HTTP 전송에만 사용
  • SameSite : XSRF 공격 방지, 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송

캐시

캐시를 사용하면 서버에 최초 요청 시에만 데이터를 다운로드하여 브라우저의 캐시에 저장하고, 해당 데이터의 변경이 일어날 때까지 로컬에 있는 데이터를 사용하여 네트워크 사용량, 브라우저 로딩 속도를 줄일 수 있다.

  • 캐시를 사용하면 캐시 가능 시간 동안 네트워크 사용량을 줄일 수 있음
  • 브라우저 로딩 속도가 빨라져 빠른 사용자 경험을 제공할 수 있음
  • 캐시 유효 시간이 초과하면, 서버를 통해 데이터를 다시 조회하고, 캐시를 갱신
  • 이때 데이터가 변경되지 않았다면 HTTP Body 없이 304 Not Modified 응답하고 캐시 유효시간 갱신 후 데이터 재사용

캐시 제어 헤더

Cache-Control

  • 캐시 지시어
  • Cache-Control: max-age : 캐시 유효 시간 설정, 초단위
  • Cache-Control: no-cache : 데이터는 캐시 해도 되지만, 항상 원(Origin) 서버에 검증하고 사용
  • Cache-Control: no-store : 데이터에 민감한 정보가 있으므로 저장하면 안 됨, 메모리에서 사용하고 최대한 빨리 삭제
  • Cache-Control: must-revalidate
    • 캐시 만료 후 최초 조회 시 원 서버에 검증해야 함
    • 원 서버 접근 실패 시 반드시 오류가 발생해야 함 - 504(Gateway Timeout)
    • no-cacahe의 경우 원서버에 접근할 수 없어 검증할 수 없는 경우에도 서버 설정에 따라서 캐시 데이터를 반환할 수도 있음
    • 캐시 유효시간이라면 캐시를 사용함

Pragma

  • 캐시 제어(하위 호환)
  • Pragma: no-cache : no-cache처럼 동작
  • HTTP 1.0의 하위 호환으로, 지금은 거의 사용하지 않음

Expires

  • 캐시 만료일을 날짜로 지정(하위 호환)
  • 예) expires: Mon, 01 Jan 1990 00:00:00 GMT
  • HTTP 1.0부터 사용
  • 지금은 더 유연한 Cache-Control: max-age 사용을 권장
  • Cache-Control: max-age와 함께 사용하면 expires는 무시됨

검증 헤더와 조건부 요청

  • 캐시 유효시간이 초과해도, 서버의 데이터가 갱신되지 않으면, 304 NOT MODIFIED를 보낸다(바디 X)
  • 클라이언트는 캐시에 저장되어 있는 데이터를 재활용하여 네트워크 다운로드가 발생하긴 하지만 용량이 적은 헤더 정보만 다운로드

검증 헤더

  • 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터

Last-Modified

  • 서버에 있는 데이터의 마지막 수정 날짜를 담고 있다(GMT 시간 사용)
  • 예) Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT

ETag

  • 캐시 데이터에 임의의 고유한 버전 이름을 달아두고, 데이터가 변경되면 이 이름을 바꾸어서 변경(hash를 다시 생성)
  • 예) ETag: "v1.0", ETag: "a2jiodwjekjl3"

조건부 요청 헤더

  • 검증 헤더로 조건에 따른 분기
  • 조건이 만족하면 200 OK 응답과 함께 BODY를 포함한 모든 데이터 전송
  • 조건이 만족하지 않으면 304 Not Modified 응답, 헤더 데이터만 전송

If-Modified-Since

  • 주어진 시간이 클라이언트의 Last-Modified의 시간보다 최근인 경우 성공
  • 예) If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
  • If-Modified-Since ↔ If-Unmodified-Since

If-None-Match

  • 클라이언트의 ETag 값과 일치하지 않으면 성공
  • 예) If-None-Match: "v1.0", If-None-Match: "a2jiodwjekjl3"
  • If-None-Match ↔ If-Match

Last-Modified와 If-Modified-Since의 단점

  • 1초 미만의 단위로 캐시 시간 조정 불가능
  • 날짜 기반의 로직을 사용하기 때문에
  • 데이터를 수정해서 날짜가 다르지만, 데이터를 수정한 결과가 전과 같은 경우
  • 서버에서 별도의 캐리 로직을 관리하고 싶은 경우
    • 예) 스페이스나 주석처럼 크게 영향이 없는 변경에서 캐시를 유지하고 싶은 경우

프록시 캐시

프록시 서버는 클라이언트가 자신을 통해서 원서버에 간접적으로 접속할 수 있게 해 주는 것을 가리킨다.

서버와 클라이언트 사이에서 중계기로써 대리로 통신을 수행하는 것을 프록시라고하고, 그 기능을 하는 것을 프록시 서버라고 한다.

프록시 서버에 요청된 내용들을 캐시를 이용하여 저장해두면, 캐시안에 있는 데이터들을 요구하는 요청에 대해서는 원서버에 접속하여 데이터를 가져올 필요가 없게 됨으로써, 전송 시간을 절약함과 동시에 불필요한 네트워크 접속을 하지않아도 되는 장점을 가진다.

  • private 캐시 : 웹 브라우저 같이 로켈에 저장되는 캐시
  • public 캐시 : 중간에서 공용으로 사용하는 캐시 서버, 프록시 캐시 서버

Cache-Control 기타

  • Cache-Control: public : 응답이 public 캐시에 저장되어도 됨
  • Cache-Control: private : 응답이 해당 사용자만을 위한 것임, private 캐시에 저장해야 함(기본 값)
  • Cache-Control: s-maxage : 프록시 캐시에만 적용되는 max-age
  • Age: 60(HTTP 헤더) : 오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간(초 단위)
  • Cache-Control: s-maxage, Age 이 두 가지는 이런 게 있다는 것 정도만 알아두면 됨.

캐시 무효화

  • 확실하게 캐시 무효화를 하는 방법
  • Cache-Control: no-cache, no-store, must-revalidate
  • Pragma: no-cache → HTTP 1.0 하위 호환을 위해

참고

'네트워크 > HTTP' 카테고리의 다른 글

[HTTP] 상태 코드 정리  (0) 2021.03.29
[HTTP] 메서드(method) 정리  (0) 2021.03.27

댓글