HTTP 헤더 - 일반 헤더

Aiden·2022년 3월 13일
2

HTTP

목록 보기
12/13
post-thumbnail

지금까지 총 11개의 포스팅을 거치면서,
IP, TCP 와 UDP, DNS 와 URI 부터 HTTP 의 기본적인 개념과 역사, HTTP 메서드와 상태코드에 대해서 모두 살펴보았다.

또한 그 과정에서 컬렉션과 스토어, 리다이렉션과 PRG 등의 개념들에 대해서도 살펴볼 수 있었다.

이제 길고 길었던 HTTP 시리즈의 마지막 장으로, 헤더에 대해서 정리해보고자 한다.

HTTP 헤더는 굉장히 다양하기 때문에 일반적으로 자주 사용되는 일반 헤더, 그리고 캐시와 조건부 요청 관련 헤더들로 각각 나누어 두 포스팅에 걸쳐 살펴볼 것이다.

이번 포스팅에서는 먼저, 일반 헤더에 대해서 다루어보았다.



HTTP 헤더 개요


각각의 HTTP 헤더들에 대해 살펴보기 전에, 지난 HTTP 기본 포스팅에서 다뤘던 내용을 간단히 복습해보고 넘어가도록 하자.

💡 헤더

헤더는 요청/응답 메시지에서 부가적인 정보들을 전송하기 위해 사용된다.

  • HTTP 전송에 필요한 모든 부가 정보
    • 본문 데이터 관련 정보
    • 인증 정보
    • 브라우저 정보
    • 서버 애플리케이션 정보
    • 캐시 관련 정보 등
  • 임의의 요소 추가 가능

💡 헤더의 구조

Field-Name + : + OWS + Field-Value + OWS

  • OWS = '띄어쓰기 허용'

  • Field-Name 은 대소문자 구분 X


💡 헤더의 분류

📌 RFC2616 (과거)

  • General Header
  • Request Header
  • Response Header
  • Entity Header
  • General Header : 메시지 전체에 적용되는 정보

  • Request Header : 요청 정보

  • Response Header : 응답 정보

  • Entity Header : 엔티티 정보


과거 RFC2616 의 스펙에서는 총 4 개의 헤더로 분류하고 있다.
각각은 메시지에 전반적으로 영향을 미치는 General Header 와 요청에 필요한 정보를 담은 Request Header, 응답에 필요한 정보를 담은 Response Header, 엔티티와 관련된 정보를 담은 Entity Header로 구성되어 있다.

여기서 엔티티란, 메시지가 전달하고자하는 데이터를 의미하는데, 주로 Body 에 담기며 Payload라고도 부른다. 따라서 Entity Header는 엔티티에 대한 정보를 담고 있는 메타데이터라고 볼 수도 있다.


📌 RFC7230 ~ RFC7235 (현재)

  • 엔티티(Entity)
  • 표현(Representation)

하지만 2014년 공개된 RFC7230 ~ RFC7235 스펙에서는 엔티티라는 단어를 더 이상 사용하지 않고, 표현이라는 단어를 사용하기로 했다. 메시지 본문에 담기는 Payload는 특정 리소스를 JSON , XML , html 등과 같은 다양한 포맷으로 표현해낸 것이라고 볼 수 있기 때문이다.

따라서 Entity HeaderRepresentation Header 혹은 표현 헤더라 불리며, 메시지 본문의 Payload 는 Representation Data 혹은 표현 데이터라 불린다.

즉, 표현표현 헤더표현 데이터를 모두 포함하는 개념이며, 표현 헤더는 여전히 표현 데이터에 대한 정보를 담고 있는 메타데이터이다.




HTTP 헤더 - 일반 헤더


이제 본격적으로 HTTP 헤더에 대해서 하나씩 살펴보도록 하자.

💡 표현

📌 Representation

  • Content-Type
  • Content-Encoding
  • Content-Language
  • Content-Length

표현 헤더본문에 담긴 데이터를 클라이언트와 서버가 서로 잘 이해할 수 있도록 정보를 제공한다.
따라서 메타데이터라고 볼 수 있으며, 전송과 응답 시 모두 사용된다.

Content-Type

  • 표현 데이터의 형식

    • 미디어 타입
    • 문자 인코딩

ex) text/html; charset=utf-8 application/json image/png . . .

Content-Encoding

  • 표현 데이터를 압축하기 위해 사용

    • 데이터를 전달하는 곳에서 압축 후 헤더 추가
    • 데이터를 전달받는 곳에서 헤더의 정보로 압축 해제

ex) gzip deflate identity . . .

Content-Language

  • 표현 데이터의 자연 언어

ex) ko en en-US . . .

Content-Length

  • 표현 데이터의 길이

    • byte 단위 사용
    • Transfer-Encoding 사용 시, Content-Length 사용 불가 (이후 설명)


💡 협상

📌 Content Negotiation

  • Accept
  • Accept-Charset
  • Accept-Encoding
  • Accept-Language

협상 헤더클라이언트가 선호하는 표현 정보를 요청 시 함께 전달하기 위해 사용한다.

예를 들어, 클라이언트가 한국어로 된 데이터를 선호한다면, 이러한 정보를 요청 시에 함께 전달하여 서버로부터 한국어 데이터를 응답받을 수 있다. 또한, 우선 순위를 설정할 수도 있기 때문에 한국어 데이터가 서버에 존재하지 않을 경우 차선 언어를 선택할 수도 있다.

Accept

  • 클라이언트가 선호하는 미디어 타입

Accept-Charset

  • 클라이언트가 선호하는 문자 인코딩

Accept-Encoding

  • 클라이언트가 선호하는 압축 인코딩

Accept-Language

  • 클라이언트가 선호하는 자연 언어

⚠️ 우선순위 지정 1

  • Quality Valuesq 를 사용

    • 0 ~ 1 사이의 값 (클수록 높은 우선순위)
    • 생략 시 1

ex) ko-KR;q=1 ko;q=0.9 en-US;q=0.8 en:q=0.7 . . .

⚠️ 우선순위 지정 2

  • 구체적인 것이 우선

    • Accept : text/* , text/plain , text/plain;format=flowed , */*
    • 이 때, 우선순위는 text/plain;format=flowed > text/plain > text/* > */*


아래에서는 4 가지의 예시를 통해 협상 헤더우선순위 설정에 대한 이해를 도왔다.
Accept-Language 를 예시로 들어 설명하였으며, 다른 협상 헤더들도 마찬가지로 동작한다.

예시 1)

가. 협상 헤더 미적용

  • 클라이언트가 이벤트 페이지에 대한 조회 요청을 서버로 전송하였다.

  • 서버는 자신의 기본 언어인 '영어' 로 페이지를 전송하였다.

나. 협상 헤더 적용

  • 클라이언트가 이벤트 페이지에 대한 조회 요청과 함께 Accept-Language 협상 헤더로 '한국어' 를 지정하였다.

  • 협상 헤더를 해석한 서버는 '한국어'도 지원하기 때문에, '한국어' 페이지를 우선적으로 전송하였다.



예시 2)

가. 우선순위 미적용

  • 클라이언트가 이벤트 페이지에 대한 조회 요청과 함께 Accept-Language 협상 헤더로 '한국어' 를 지정하였다.

  • 하지만 서버는 '한국어'를 지원하지 않기 때문에 '한국어' 페이지를 전송해줄 수 없다.

  • 따라서 서버는 자신의 기본 언어인 '독일어' 로 페이지를 전송하였다.

나. 우선순위 적용

  • 클라이언트가 이벤트 페이지에 대한 조회 요청과 함께 Accept-Language 협상 헤더로 우선순위를 지정하였다.

  • 지정된 우선순위는 `한국어' , '영어' 순이다.

  • 서버는 '한국어'를 지원하지 않기 때문에 '한국어' 페이지를 전송해줄 수 없다.

  • 하지만 차순위인 '영어'를 지원하기 때문에 '영어' 페이지를 전송하였다.


💡 전송 방식

📌 Transfer Method

  • Transfer-Encoding
  • Range
  • Content Range

HTTP 의 전송 방식은 크게 4 가지로 나뉘며, 각각의 방식에 따라 전송 방식 헤더가 다르게 활용된다.

아래에서는 각 전송 방식에 대해 간단히 살펴보면서, 전송 방식 헤더에 대해 소개한다.

✅ 단순 전송

  • Content-Length 를 통해 전송할 데이터의 길이를 명시

    • 한 번에 요청
    • 한 번에 응답
    • 데이터의 길이를 알 수 있을 때 사용

✅ 압축 전송

  • Content-Length 로 길이를 명시하고, Content-Encoding 으로 압축 방식을 명시

    • 한 번에 요청
    • 한 번에 응답
    • 데이터를 압축하여 전송할 때 사용

✅ 분할 전송

  • Trasnfer-Encoding 헤더에 chunked 명시하여 데이터 분할 여부를 명시

    • Chunk 단위로 데이터를 분할하여 전송
    • Content-Length 사용 불가 ❌
    • \r\n 으로 분할 전송의 끝을 명시

  • ⚠️ Content-Length 를 사용할 수 없는 이유

    • 위 그림과 같이, 분할 전송되는 데이터의 바이트 정보가 이미 포함되어 있기 때문에 Content-Length 를 사용할 수 없다.

✅ 범위 전송

  • 요청 시 Range 헤더에 데이터의 범위를 명시하고, 응답 시 Content-Range 헤더에 전송한 데이터의 범위와 총 길이를 명시

    • 데이터의 특정 범위만을 요청 가능
    • 데이터 전송 도중 오류 발생 시, 처음부터 모든 데이터를 다시 요청할 필요가 없음
    • 네트워크 다운로드 용량 절약



💡 일반 정보

📌 General Info

  • From
  • Referer
  • User-Agent
  • Server
  • Date

일반 정보 헤더는 단순한 정보성 헤더들이다.

From

  • 유저 에이전트의 이메일 정보

    • 검색 엔진에서 주로 사용
    • 요청 시 사용

Referer

  • 현재 요청된 페이지의 이전 웹 페이지 주소

    • 유입 경로 분석 가능
    • 요청 시 사용
    • Referrer 의 오타이지만 이미 통용되고 있어 수정 불가

ex) www.naver.com -> www.google.com 이동 요청 시, Referer: www.naver.com 포함하여 전송

User-Agent

  • 유저 에이전트의 애플리케이션 정보

    • 클라이언트의 애플리케이션 정보
    • 통계 정보로 활용
    • 장애가 발생하는 특정 브라우저 파악 가능
    • 요청 시 사용

Server

  • 요청을 처리하는 ORIGIN Server 의 소프트웨어 정보

    • ORIGIN Server : 메시지 전달 시 거치는 프록시 서버가 아닌, 실제 요청을 처리하는 원 서버
    • 응답 시 사용

ex) Server: Apache/2.2.22 (Debian) Server: nginx . . .

Date

  • 메시지가 발생한 날짜 및 시간 정보

    • 응답 시 사용

ex) Date: Tue, 15 Nov 1994 08:12:31 GMT . . .


💡 특수 정보

📌 Special Info

  • Host
  • Location
  • Allow
  • Retry-After

특수 정보 헤더는 특별한 정보를 제공하는 헤더들이다.

Host

  • 요청한 호스트 정보

    • 필수 헤더
    • 하나의 서버가 여러 도메인을 처리해야 할 때 이를 구분하기 위해 사용
    • 요청 시 사용

  • ⚠️ 하나의 서버가 여러 도메인을 처리해야 할 때

    • 위와 같이, 가상 호스트를 통해 하나의 IP 를 가진 서버가 여러 도메인을 한 번에 처리 할 수 있다.

    • 하지만 이러한 경우, 클라이언트 요청 시 서버 내의 각 도메인을 구분할 수 없다.

    • TCP/IP 는 단순히 IP 를 기반으로 통신하기 때문이다.

    • 따라서 요청 시에 Host 헤더를 사용해 목적지 도메인을 명시하면, 서버 내 각 도메인을 정확히 구분하여 메시지를 전송할 수 있다.

    • 가상 호스팅에 대한 자세한 정보는 Wikipedia - Virtual Hosting 참고

Location

  • 페이지 리다이렉션 정보

    • 3xx 상태코드와 Location 헤더를 응답으로 받았을 경우, Location 위치로 리다이렉트
  • 요청에 의해 생성된 리소스 URI 정보

    • 201 상태코드와 Location 헤더를 응답으로 받았을 경우, 생성된 리소스 URI

    • 각 상태코드와 리다이렉션에 대한 자세한 정보는 HTTP 상태코드 참고

Allow

  • 허용 가능한 HTTP 메서드 정보

    • 리소스가 지원하는 메서드 집합을 명시
    • 서버가 405 Method Not Allowed 상태코드로 응답할 경우, 필수적으로 포함
    • 비어있는 경우, 어떤 메서드도 허용하지 않음

ex) Allow: GET, HEAD, PUT . . .

Retry-After

  • 유저 에이전트가 다음 요청까지 기다려야 하는 시간

    • 서버가 503 Service Unavailable 상태코드로 응답할 경우, 서비스가 언제까지 불능인지 명시할 수 있음
    • 서비스 정상 이용 가능한 날짜 및 시각 표기 가능
    • 서비스 정상 이용 가능까지 남은 시간을 초 단위로 표기 가능

ex) Retry-After: Fri, 31 Dec 1999 23:59:59 GMT Retry-After: 120 . . .

💡 인증

📌 Authentication

  • Authorization
  • WWW-Authenticate

인증 헤더는 인증 정보를 제공하거나, 구체적인 인증 방법 관련 정보를 전달하는 헤더이다.

Authorization

  • 클라이언트의 인증 정보를 서버에 전달

    • 다양한 인증 매커니즘에 따라 값이 다름

ex) Authorization: Basic xxxxxxxxxxxxxxxx . . .

WWW-Authenticate

  • 리소스 접근시 필요한 인증 방법 정의

    • 서버가 401 Unauthorized 상태코드로 응답할 경우 함께 사용

ex) WWW-Authenticate: Newauth realm="apps", type=1, title="Login to \"apps\"", Basic realm="simple" . . .

💡 쿠키

📌 Cookie

  • Set-Cookie
  • Cookie

쿠키 헤더는 클라이언트와 서버 간 일시적인 연결 유지를 위해 관련 정보를 제공하는 헤더이다.

본 글에서는 쿠키와 세션에 대해 자세히 설명하지 않으므로, 쿠키(Cookie)와 세션(Session)에 대한 자세한 정보는 아래 링크를 참고바란다.

간단히 정리하면 HTTP 는 Stateless 한 속성을 가지고 있기 때문에 서버의 Scale-out 에서 유리할 수 있지만, 클라이언트와 서버 간 연결 유지가 어렵다는 한계점을 가진다. 따라서 이를 극복하기 위해 쿠키(Cookie)가 등장하게 된 것이다.

물론 쿠키 또한 명확한 한계점을 가지고 있다.
정보가 클라이언트 측에서 관리되기 때문에 악용될 우려가 있고, 보안에 취약하여 정보가 탈취당할 위험성이 존재한다는 점이다.

따라서 이러한 쿠키 정보는 다시 서버 측의 세션(Session)에서도 관리되며, 각각에 부여되는 세션 ID 로 통신하여 보안성을 높일 수 있다.

  • 서버에서 클라이언트로 쿠키 정보(세션 ID)를 전달

ex) set-cookie: sessionId=abcde1234; expires=Sat, 26-Dec-2020 00:00:00 GMT; path=/; domain=.google.com; Secure

  • 위 그림과 같이, 클라이언트가 웹사이트에 요청을 보내면 서버는 해당 클라이언트의 쿠키 정보를 담아 응답 메시지를 전송한다.

  • set-cookie 응답 메시지를 받은 클라이언트는 자신의 쿠키 저장소에 쿠키 정보를 저장한다.

  • 클라이언트에서 서버로 쿠키 정보(세션 ID)를 전달

ex) cookie: sessionId=abcde1234

  • 서버로부터 쿠키 정보를 부여받은 클라이언트는 이후 서버에게 요청을 보낼 때마다 해당 정보를 함께 담아 요청 메시지를 전송한다.

  • 이 때, 클라이언트는 자신의 쿠키 저장소를 참조하게 된다.

Parameters

  • set-cookiecookie 헤더에서 사용되는 다양한 파라미터들은 다음과 같다.

    • expires : 쿠키 정보의 만료일

      • 명시 : 해당 날짜까지 유지 (영속 쿠키)
      • 생략 : 브라우저 종료 시 까지 쿠키 정보 유지 (세션 쿠키)
    • max-age : 쿠키 정보의 만료일(초단위)

      • 0, 음수(-) : 쿠키 삭제
      • 명시 : 해당 날짜까지 유지 (영속 쿠키)
      • 생략 : 브라우저 종료 시 까지 쿠키 정보 유지 (세션 쿠키)
    • domain : 쿠키 정보가 적용될 도메인

      • 명시 : 명시한 도메인 + 서브 도메인 모두 적용
      • 생략 : 현재 문서 기준 도메인만 적용
    • path : 쿠키 정보가 적용될 경로 설정

      • 명시된 경로를 포함한 하위 페이지만 쿠키 적용
      • 일반적으로 path=/ 와 같이 루트로 지정
    • secure : HTTPS 사용 시에만 쿠키 정보 전달

      • secure 미적용 시에는 HTTP, HTTPS 구분하지 않음
    • HttpOnly : 자바스크립트에서 쿠키에 접근 불가

      • XSS 공격 방지
      • HTTP 전송에만 사용
    • samesite : 요청 도메인과 쿠키 정보 내의 도메인이 같은 경우에만 전송

      • XSRF 공격 방지


지금까지 HTTP 일반 헤더들을 차례대로 살펴보았다.
다음 포스팅에서는 HTTP 캐시와 조건부 요청 관련 헤더들에 대해 다뤄볼 예정이다.



출처


김영한 님의 강의 모든 개발자를 위한 HTTP 웹 기본 지식 을 정리한 포스팅입니다.

0개의 댓글