Skip to content
On this page

HTTP 헤더

수정하기
문서 생성 2021-05-20 12:50:50 최근 수정 2021-05-20 12:51:06

용도

  • HTTP 전송에 필요한 모든 부가정보
  • 표현 (Representation) - REST-API에서 R이다.
    • Representation = 표현 메타데이터 + 표현
    • 요청이나 응답에서 전달할 실제 데이터
    • 왜 표현이라고 하나 ? → 리소스(데이터)를 받아서 여러 방식(HTML, XML, JSON...)으로 표현할 수 있기 때문에
  • 메시지 본문을 통해 표현 데이터를 전달
  • 메시지 본문 = 페이로드(payload)
  • 표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공

표현 헤더

  • Content-Type: 표현 데이터의 형식
    • 미디어 타입, 문자 인코딩
    • text/html; charset=utf-8, application/json, image/png
  • Content-Encoding: 표현 데이터의 압축 방식
    • 데이터를 읽는쪽(클라이언트)에서 인코딩 헤더의 정보로 압축 해제한다.
    • gzip, deflate, identity
  • Content-Language: 표현 데이터의 자연 언어
  • Content-Length: 표현 데이터의 길이
    • 바이트 단위, Transfer-Encoding은 사용하면 안된다.
  • 전송, 응답시 모두 사용할 수 있다.

협상 협상

  • 콘텐트 네고시에이션
  • 클라이언트가 선호하는 표현 요청
    • 요청시에만 사용
  • 우선순위
    • Quality Values(q) 값을 사용
      • 0~1 클수록 우선순위가 높다.
      • Accept-Language: ko-KR, ko;q=0.9,en-US;q=0.8,en;q=0.7
    • 구체적인 것이 우선순위가 높고, 구체적인 것을 기준으로 잡는다.
  • Accept: 클라이언트가 선호하는 미디어 타입 전달
  • Accept-Charset: 클라이언트가 선호하는 문자 인코딩
  • Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
  • Accept-Language: 클라이언트가 선호하는 자연 언어

전송 방식

단순 전송

  • 컨텐츠 길이를 알고있을 때, Content-Length를 지정해서 전송
    • 한번에 요청, 한번에 응답

압축 전송

  • 압축해서 전송, Content-Encoding이 들어가야 한다. 그래야 클라이언트가 받아서 압축 해제를 한다.

분할 전송

  • Transfer-Encoding
  • 나눠서 전송, Content-Length를 넣으면 안된다. 예상도 안되고 나눠진 Chuncked마다 길이가 있기 때문에

범위 전송

  • Range, Content-Range
    • 중간에 데이터를 전송하다 다시 요청할 경우, 처음부터 다시 요청하는 것보다 범위를 지정해서 요청하는 것

From

  • 유저 에이전트의 이메일 정보
  • 일반적으로 잘 사용되지 않음
  • 검색 엔진 같은 곳에서 사용

Referer

  • 이전 웹 페이지의 주소
  • 유입 경로를 분석할 때 사용
  • HTTP 요청에서 사용
  • 오타, referrer가 맞음

User-Agent

  • 유저 에이전트 애플리케이션 정보
  • 클라이언트 애플리케이션 정보(웹 브라우저 등)
  • 통계 정보
  • 어떤 종류의 브라우저에서 에러가 발생했는지 파악할 수 있다.
  • HTTP 요청에서 사용

Server

  • 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
  • ORIGIN 서버: HTTP 서버를 요청하면 여러 프록시 서버를 거치게 됨, 실제 응답을 해주는 서버
  • HTTP 응답에서 사용

Date

  • 메시지가 발생한 날짜/시간
  • HTTP 응답에서 사용

Host

  • HTTP 요청에서 사용
  • 필수
  • 하나의 IP 주소에 여러 도메인이 적용되어 있을 때 구분을 해준다.

Location

  • 페이지 리다이렉션
  • 응답코드 3xx 응답 결과에 Location 헤더가 있으면 그 위치로 리다이렉트
  • 201 Location 값은 요청에 의해 생성된 리소스의 URI
  • HTTP-Status-Codes 참고

Allow

  • 허용 가능한 HTTP 메서드
  • 405 (Method Not Allowed) 에서 응답에 포함해야 한다.
  • Allow: GET, HEAD, PUT
  • 잘 사용하지 않는다.

Retry-After

  • 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
  • 503, HTTP-Status-Codes 참고
  • 날짜/초단위 표기

인증

  • Authorization
    • 클라이언트 인증 정보를 서버에 전달
    • 인증 매커니즘이 다양하다. OAuth....마다 값이 다르다.
  • WWW-Authenticate
    • 리소스 접근시에 필요한 인증 방법을 정의한다.
    • 401 응답과 함게 사용한다.

쿠키

  • 웹페이지에 처음 접근한 뒤 로그인을 하고 접근을하면 로그인을 했는지 안했는지 서버는 알 방법이 없다.
    • HTTP는 Stateless 프로토콜이기 때문에
    • 연결을 주고 받으면 계속 연결이 유지되는 것이 아니기 때문에
    • 쿠키로 정보를 저장하는 것이 필요하다.
    • HTTP 참고
  • Set-Cookie
    • 서버에서 클라이언트로 쿠키 전달(응답)
  • Cookie
    • 클라이언트가 서버에서 받은 쿠키를 저장하고(웹 브라우저 내부의 쿠키 저장소에), HTTP 요청시 서버로 전달
  • 모든 요청 정보에 쿠키가 자동으로 포함된다.
  • set-cookie: sessionId=asdfsdf13213; expires=Sat, 22-May-2021 00:00:00 GMT; path=/; domain=.google.com; Secure

사용처

  • 사용자 로그인 세션
  • 광고 정보 트래킹

쿠키 정보는 항상 서버에 전송된다.

  • 네트워크 트래픽을 추가 유발하기 때문에 최소한의 정보만 사용(세션 id, 인증 토큰)
  • 서버에 전송할 필요가 없다면? localStorage, sessionStorage 사용

주의

  • 보안에 민감한 데이터는 저장해선 안된다.

생명 주기

  • expires, 만료일이 되면 쿠키가 삭제된다.
  • max-age, 초단위가 지나면 쿠키 삭제
  • 세션 쿠키: 만료 날짜를 생략, 브라우저 종료시까지만 유지
  • 영속 쿠키: 만료 날짜까지 유지

도메인

  • domain=.google.com
    • 명시: 명시한 문서 기준 도메인 + 서브 도메인 포함
  • 생략한다면?
    • 현재 문서 기준 도메인만 적용
    • 서브 도메인에는 미접근

경로 지정

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

보안

  • Secure
    • https인 경우에만 쿠키를 전송
  • HttpOnly
    • 자바스크립트에서 접근 불가하다. (document.cookie 사용 불가)
  • SameSite
    • 요청 도메인과 쿠키에 설정된 도메인이 같은 경우에만 쿠키를 전송한다.

캐시

  • cache-control: max-age
    • 캐시 유효 시간, 초 단위
  • Cache-Control: no-cache
    • 데이터는 캐시해도 되지만 항상 origin 서버에 검증하고 사용한다.
  • Cache-Control: no-store
    • 데이터에 민감한 정보가 있으므로 저장하면 안된다.
  1. 웹 브라우저에 캐시 저장소가 있다.
  2. 첫 요청시 응답을 캐시에 넣어둔다. 캐시가 유효한 시간과 함께
  3. 두번째 요청을 했을 때 유효한 시간이면 캐시에서 가져온다. (네트워크를 사용하지 않아도 됨, 속도가 빠르다.)
  4. 캐시 유효 시간이 초과된다면 서버를 통해 데이터를 다시 조회, 캐시 갱신 (네트워크를 사용한다.)
  • 서버에서 응답한 데이터가 같은 데이터라면 꼭 다시 받아야할까? → 검증 헤더와 조건부 요청을 사용하면 된다.

검증 헤더와 조건부 요청

  • 검증 헤더

    • 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
    • Last Modified, Etag
  • 조건부 요청 헤더

    • 검증 헤더로 조건에 따른 분기
    • If-Modified-Since: Last-Modified 사용
    • If-None-Match: ETag 사용
    • 조건 만족시 200 OK
    • 조건이 만족하지 않다면 304 Not Modified
  • Last Modified 사용

    • 캐시가 만료되어도 서버에서 데이터를 변경하지 않았다면, 데이터 전송 대신 기존 캐시를 사용하면 된다.
    • 서버에서 데이터가 변경되지 않았다는 것을 확인해야 한다.
    1. 처음 데이터를 요청했을 때 서버가 Last-Modified(데이터 최종 수정일) 검증 헤더를 포함해 응답한다.
    2. 브라우저의 캐시에 Last-Modified가 포함되어 있다.
    3. 서버 요청을 보낼 때 if-modified-since(조건부 요청)에 캐시에 있는 최종 수정일을 넘긴다.
    4. 서버에서 요청받은 데이터의 최종 수정일과 헤더에 포함된 최종 수정일을 확인하고 수정사항이 없는지 검증한다.
    5. 수정사항 없다면 304 Not Modified로 응답한다.
      • cache-controlLast-Modified를 포함, HTTP Body는 없다. (캐시에 있는 것을 사용하면 되기 때문에)
      • 전체 데이터가 아닌 헤더 부분만 전송 (네트워크 부하 ↓)
    6. 수정이 되었다면 200 OK로 응답
      • 모든 데이터 전송(BODY 포함)
    • 단점
      • 1초 미만 단위로 캐시 조정 불가능
      • 날짜 기반의 로직을 사용한다.
        • 데이터를 수정해서 날짜가 다르지만 같은 데이터로 수정해서 결과가 결국 같은 경우
        • 스페이스나 주석 처럼 크게 영향이 없는 변경인 경우
  • Etag, If-None-Match 사용

    • 캐시용 데이터에 임의의 고유한 버전 이름을 달아두기
    • `ETag: "v1.0", Hash 값
    • 데이터가 변경되면 이 이름을 바꾸어서 변경 (Hash 다시 생성)
    • 단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받기
    1. 서버에 데이터를 요청하면, ETag 값을 보내준다.
    2. 응답 결과(ETag 포함)를 캐시에 저장한다.
    3. 캐시가 만료되었다면, 캐시에 있는 ETag값을 If-None-Match에 보낸다.
    4. 서버의 데이터와 같다면 304 Not Modified로 응답한다.
      • HTTP Body는 없다.
      • 캐시는 갱신하고 캐시에서 조회
    • 클라이언트는 캐시 매커니즘을 모른다.

프록시 캐시

  • 프록시 캐시 서버
    • CDN 서비스
  • Origin 서버가 멀리 있다면 프록시 캐시 서버를 거쳐서 오도록 한다.
  • 클라이언트는 프록시 캐시 서버에 요청한다.
  • public 캐시라고 한다. 웹 브라우저/로컬에 저장된 캐시는 private 캐시
    • Cache-Control: public: 응답이 public 캐시에 저장되어도 된다.

캐시 무효화

  • Cache-Control: no-cache, no-store, must-revalidate
  • Pragma: no-cache (HTTP 1.0 하위 호환)
  • 웹브라우저가 임의로 캐시를 해버릴 수 있다. 그래서 캐시하면 안된다고 명시해야 한다.

reference