• ETag 헤더는 캐시 관련 헤더
  • 서버에서 제공되는 컨텐츠의 식별번호 → 웹서버에서 제공하는 컨텐츠도 각각의 고유 식별정보을 가짐
  • ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자
  • 웹 서버가 내용을 확인하고 변하지 않았으면, 웹 서버로 full 요청을 보내지 않기 때문에, 캐쉬가 더 효율적이게 되고, 대역폭도 아낄 수 있음
  • 내용이 변경되었다면, "mid-air collisions"이라는 리소스 간의 동시 다발적 수정 및 덮어쓰기 현상을 막는데 유용하게 사용
  • 특정 URL 의 리소스가 변경된다면, 새로운 ETag 가 생성
  • ETag 헤더는 지문(finger printer)과 같은 역할을 하면서 다른 서버들이 추적하는 용도에 이용
  • ETag 헤더를 비교하여 리소스가 서로 같은지의 여부를 빠르게 판단할 수 있지만, 서버에서 무기한으로 지속될 수 있도록 설정할 수도 있음
  • 캐시버서와 웹브라우저는 ETag 헤더를 이용해서 캐싱된 컨텐츠들이 유효한지 갱신이 필요한지를 결정


ETag의 두 가지종류 → Strong ETag와 Weak ETag

1. Strong ETag

  • Strong ETag는 바이트 단위로 컨텐츠가 동일함을 의미
  • Strong ETag를 가지고 있는 캐싱된 컨텐츠는 Range 요청에 대해서 응답이 가능
  • Strong ETag 예시
    Strong ETag : "abcdefg"

2. Weak ETag

  • Weak ETag는 바이트단위로 동일 X
  • 일반적으로 캐시된 컨텐츠로는 사용 가능
  • 바이트 단위까지 같지는 않기 때문에 Range 요청에 대한 응답이 불가능
  • Weak ETag 예시
    Weak ETag : w/"abcdefg"


실제 헤더의 ETag 값 예시

  • ETag 값은 보통 "리소스의 해시값 - 마지막 수정 시간의 해시값" 으로 구성
  • 아래 예시를 보면 대시(-)를 기준으로 "48ff5"는 리소스의 해시값, "55559540ad680"은 마지막 수정 시간의 해시값
  • 캐시서버는 일반적으로 자신의 캐싱된 컨텐츠를 비교할때 ETag 값을, If-Match, If-None-Match와 함께 사용

문법

1. W/ Optional

  • 'W/'는 weak validator가 사용 의미 → 대/소문자를 구분
  • Weak validators는 만들기는 쉽지만 비교하기에는 효율성이 떨어짐
  • 'W/'를 사용하지 않는 Strong validators는 비교하기에는 이상적이지만 효율적으로 만들기 어려움
  • 동일한 자원의 두 가지 Weak validator Etag 값은 동일할 수 있지만, 바이트 단위까지 동일하지 않음

2. etag_value

  • etag_value는 요청된 값을 ASCII 코드와 같이 고유한 형태로 나타냄 → 예 : "675af34563dc-tr34"
  • ETag의 값을 생성하는 방법(Method)은 단순히 한가지로 정해져있지 않음
  • 콘텐츠의 해시, 마지막으로 수정된 타임스탬프의 해시, 혹은 그냥 개정번호를 이용

3. ETag 사용 형식

ETag: W/"<etag_value>"
ETag: "<etag_value>"

4. ETag 사용 예시

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
ETag: W/"0815"



공중 충돌 방지(Avoiding mid-air collisions)

  • ETag 헤더는 If-Match 헤더와 함께 사용함으로 공중 편집 충돌(mid-air edit collisions)을 감지 가능
  • 예를 들어 MDN을 편집할 때 현재 위키 콘텐츠가 해시되어 응답의 Etag를 넣음
    ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4
  • Wiki 페이지(데이터 게시)에 변경 사항을 저장하는 POST 요청에는 신선도(freshness)를 확인할 ETag 값이 있는 If-Match 헤더가 포함.
    If-Math: "33a64df551425fcc55e4d42a148795d9f25f89d4"
  • 해시가 일치하지 않으면 문서가 중간에 편집되었음을 의미하며 412 응답코드(Precondition Failed) 오류가 발생


변경되지 않은 리소스 캐싱(Caching of unchanged resources)

  • ETag 헤더의 또 다른 사용 사례는 변경되지 않은 리소스(Caching of unchanged resources)를 캐시하는 것
  • 사용자가 주어진 URL(기존 ETag 보유)을 다시 방문할 때, 클라이언트는 If-None-Match 헤더 필드를 활용하여 기존의 컨텐츠가 변경되었는지 확인
    If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
  • 서버는 클라이언트의 ETag(If-None-Match와 함께 전송됨)를 현재 버전의 리소스에 대한 ETag와 비교하고 두 값이 일치하면(즉, 리소스가 변경되지 않은 경우) 서버는 304 Not Modified 상태를 다시 보냄
  • 응답의 캐시된 버전이 여전히 사용할 수 있음을 클라이언트에 알림(freshness)


클라이언트와 서버 간 통신 과정 설명

1. 첫 요청에 대한 응답

  • 클라이언트가 서버에게 요청을 보냄
    $ curl -H "Accept: application/json" -i http://localhost:8080/spring-boot-rest/foos/1
  • 서버는 ETag 헤더를 응답 Header에 담아 클라이언트에게 응답
    HTTP/1.1 200 OK
    ETag: "f88dd058fe004909615a64f01be66a7"
    Content-Type: application/json;charset=UTF-8
    Content-Length: 52

2. 재요청에 대한 응답

  • 클라이언트는 재요청할 때 ETag를 Header의 If-None-Match 헤더에 담아 서버에 요청을 보냄.

    $ curl -H "Accept: application/json"
      \ -H 'If-None-Match: "f88dd058fe004909615a64f01be66a7"'
      \ -i http://localhost:8080/spring-boot-rest/foos/1

  • 리소스가 바뀌지 않았기 때문에 서버는 304 Not Modified를 클라이언트에게 응답 (ETag는 이전 요청에 대한 응답과 같음)

    HTTP/1.1 304 Not Modified
    ETag: "f88dd058fe004909615a64f01be66a7"

  • PUT 메소드를 사용하여 서버의 컨텐츠를 변경

    $ curl -H "Content-Type: application/json"
       -i -X PUT --data '{ "id":1, "name":"Transformers2"}'
       http://localhost:8080/spring-boot-rest/foos/1

  • 서버의 컨텐츠가 정상적으로 변경되었다는 내용을 서버가 응답

    HTTP/1.1 200 OK
    ETag: "d41d8cd98f00b204e9800998ecf8427e"
    Content-Length: 0

  • 클라이언트가 이전 재요청 내용을 다시 서버에게 보냄 → 요청을 다시 할 때는 마지막으로 가지고 있던 ETag를 담아서 보냄

    $ curl -H "Accept: application/json"
       -H 'If-None-Match: "f88dd058fe004909615a64f01be66a7"'
       -i http://localhost:8080/spring-boot-rest/foos/1

  • 클라이언트에서 보낸 ETag와 서버의 ETag가 다르기 때문에 요청을 처리 → 리소스가 바뀌었으니 새로운 ETag를 Header에 담아 보내고, 새로운 요청을 처리했기 때문에 서버는 200 OK를 응답

    HTTP/1.1 200 OK
    ETag: "03cb37ca667706c68c0aad4cb04c3a211"
    Content-Type: application/json;charset=UTF-8
    Content-Length: 56

3. 304 Not Modified 응답 코드

  • 캐시를 목적으로 사용하는 status code
  • 클라이언트에게 응답이 수정되지 않았음을 알려줌
  • 클라이언트는 서버에게 304 응답 코드를 받으면, 클라이언트는 계속해서 응답의 캐시된 버전을 사용 가능

'HTTP > HTTP 헤더' 카테고리의 다른 글

HTTP 프로토콜 Expires 헤더  (0) 2022.06.25
HTTP 프로토콜 Expect 헤더  (0) 2022.06.25
HTTP 프로토콜 Date 헤더  (0) 2022.06.25
HTTP 프로토콜 Content-Type 헤더  (0) 2022.06.25
HTTP 프로토콜 Content-Encoding 헤더  (0) 2022.06.25

+ Recent posts