• If-Range 헤더를 포함한 HTTP 요청 헤더는 범위 요청을 조건적으로 만듬
    • 조건이 만족된다면, 서버에서 206 Partial Content 응답과 범위 요청의 데이터를 HTTP 바디(body) 포함하여 전송
    • 조건을 만족하지 못한다면, 200 OK 상태 코드가 전체 리소스와 함께 반송됨
  • 다운로드를 재시작하거나, 저장된 리소스가 마지막 조각을 다운받은 후 수정되었는지 확인하는 경우 많이 사용
  • ETag 정보를 활용하기 때문에 If-Range 헤더는 캐시관련 헤더임
  • 캐시라는 동작은 항상 웹서버에서 제공하는 컨텐츠의 유효성을 체크해야 함 → 저장하고 있는 컨텐츠가 지금도 웹서버에서 제공하는 컨텐츠와 같은지 체크 필요
  • If-Range 헤더는 Last-Modified 유효 검사자, 또는 ETag와 함께 사용될 수 있지만, 동시에 사용은 불가
  • 웹서버에서 ETag를 지원하지 않는 경우도 있음
  • ETag를 지원하지 않는 경우에 If-Range 헤더의 값으로 클라이언트는 If-Modified-Since 헤더와 같이 Last-Modified 시간 정보를 기재 → ETag를 사용하지 못하지만, 기능에는 차이가 없음


If-Range 헤더가 사용되는 예시 상황

  1. 웹서버에서 어떤 프로그램 설치 파일을 다운로드 받고 있었는데, 알 수 없는 이유로 다운로드가 중간에 중단됨
  2. 당장 다운받을 수 없는 환경이라, 몇시간 뒤 다운 받아야하는 상황이 발생함
  3. 시간이 지나고 나서 다시 다운로드를 받으려고 하니 웹서버에서 제공하는 동일한 이름의 프로그램이 이전에 다운받는 것과 같은것인지 확인할 필요가 있음
  4. 멈춰있는 동안 프로그램의 버전이 업그레이드된 경우에는 이름이 같아도 내용이 다름
  5. 웹서버에게 중간에 다운로드가 끊어졌던 프로그램에 관련한 정보를 웹 서버에 전달해 주면, 웹 서버가 같은지 다른지 판단하여 프로그램을 전달
  6. 동일한 프로그램이 존재하는 경우에는 계속 다운받을 수 있는 것이고, 다른 프로그램이라면 프로그램이 변경되었기에 새로운 프로그램을 다운받아야함


If-Range 헤더가 없는 경우, If-Match 헤더를 사용해서 동일한 컨텐츠인지 확인하고 프로그램 다운로드 진행

  • 웹서버에 컨텐츠 변경이 없는 경우에는 If-Match 헤더를 사용하여도 큰 이상은 없음 -> 같은 컨텐츠기에 프로그램을 연속해서 다운 가능
  • 웹 서버에 컨텐츠 변경이 있는 경우는 복잡해짐 → 하나의 컨텐츠를 전달받기 위해서 총 2번의 요청, 2번의 응답이 상호 교환 필요

If-Match 헤더의 문제를 개선하기 위해 If-Range 헤더 사용

  • If-Range 헤더를 사용하게 되면 한번의 요청으로 모든 처리가 가능
  • 웹서버는 If-Range 헤더를 받게 되면, 컨텐츠가 변경된 경우는 새로운 컨텐츠 전체를 전달
  • 웹서버는 If-Range 헤더를 받게 되면, 컨텐츠가 변경되지 않은경우는 Range 헤더의 값에 해당되는 데이터만 전달
  • 컨텐츠 변경이 없는 경우는 If-Range 헤더는 If-Match 헤더를 사용했을 때와 같으나, 컨텐츠가 변경된 경우에 If-Range 헤더는 If-Match 헤더보다 처리 과정이 절반으로 줄어듬

If-Range 헤더 참고 사진

문법

If-Range: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
If-Range: <etag>

지시자

1. <etag>

  • 개체 태그는 요청한 리소스가 유일한 것을 표현
  • ASCII 문자열로 쌍따옴표("675af34563dc-tr34"처럼)로 묶여있음
  • 접두사로 W/가 있어 약한 비교 알고리즘을 사용되어야 하는 것을 표시
  • If-Range 헤더 사용 예제
    If-Range: Wed, 21 Oct 2015 07:28:00 GMT

2. <day-name>

  • "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 또는 "Sun" 중 하나가 표시
  • 대소문자 구분

3. <day>

  • 날짜
  • 두 글자로 표시
  • 예시 : "04" 또는 "23"

4. <month>

  • "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 중 하나가 표시
  • 대소문자 구분

5. <year>

  • 연도
  • 네 글자로 표시
  • 예시 : "1990" 또는 "2016"

6. <hour>

  • 시간
  • 두 글자로 표시
  • 예시 : "09" 또는 "23"

7. <minute>

  • 두 글자로 표시
  • 예시 : "04" 또는 "59"

8. <second>

  • 두 글자로 표시
  • 예시 : "04" 또는 "59"

9. GMT

  • 그리니치 표준시
  • HTTP 날짜는 현지 시각이 아닌, 언제나 GMT로 표현
  • If-None-Match 헤더는 If-Match 헤더와 비슷하지만 GET 방식에 있어서 차이가 있음
  • If-None-Match 헤더는 GET에서는 If-Modified-Since 헤더처럼 사용
  • If-None-Match 헤더를 이용해서 컨텐츠의 변경여부를 묻고 컨텐츠가 변경되지 않는 경우(기존 컨텐츠의 ETage정보가 요청의 If-None-Match 헤더의 ETag와 같다면) "304 Not Modified" 메시지를 전달


If-None-Match 헤더의 동작흐름

1. 먼저 GET으로 최초 이미지 컨텐츠를 요청한 후 ETag 정보를 받음

$ curl -H "Accept: application/json" -i http://localhost:8080/spring-boot-rest/foos/1
HTTP/1.1 200 OK
ETag: "f88dd058fe004909615a64f01be66a7"
Content-Type: application/json;charset=UTF-8
Content-Length: 52



2. 클라이언트가 If-None-Match 헤더에 동일한 ETag 를 전달하는 경우와 그렇지 않은 경우를 확인

  • 웹서버는 If-None-Match 헤더의 값이 같은 경우 304 상태 코드를 반환 → 정상 응답 코드

  • 웹서버는 If-None-Match 헤더의 값이 다른 경우 200 상태코드를 반환 → 정상 응답 코드

  • GET에서는 If-None-Match의 값이 ETag와 같을 경우 캐싱되어 있는 이미지를 사용할 수 있도록 304 상태코드를 반환

  • If-None-Match 헤더는 If-Modified-Since 헤더와 같은 목적으로 사용

    ## 확인한 ETag와 If-None-Match 헤더의 ETag가 동일한 경우
    $ curl -H "Accept: application/json" -H 'If-None-Match: "f88dd058fe004909615a64f01be66a7" -i http://localhost:8080/spring-boot-rest/foos/1
    HTTP/1.1 304 Not Modified
    ETag: "f88dd058fe004909615a64f01be66a7"
    
    ## 확인한 ETag와 If-None-Match 헤더의 ETag가 다른 경우
    $ 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


If-None-Match 헤더와 If-Modified-Since 헤더의 차이

  • If-Modified-Since 헤더는 시간 정보를 담기 때문에 웹서버나 클라이언트의 환경적인 측면에서 정보의 정확성이 보장 X
  • If-None-Match 헤더는 ETag 정보를 활용하기 때문에 컨텐츠의 변경 유무를 아주 정확하게 반영 가능


If-None-Match 헤더와 If-Match 헤더의 차이

  • If-Match 헤더는 PUT과 같이 덮어쓰기 위한 동작에 사용 → 새로운 파일 생성을 금지
  • If-None-Match 헤더는 신규로 생성하기 위한 동작에 사용 → 파일 덮어쓰기를 금지하는 컨셉
  • If-Modified-Since 헤더는 캐시동작에 있어서 유효한 컨텐츠를 클라이언트에게 제공할 수 있게 해 주는 중요한 정보
  • 중요한 If-Modified-Since 헤더의 정보에 오류가 있는 경우 웹 서버는 If-Modified-Since 헤더의 정보를 무시하고, 컨텐츠 전체를 서비스
    • If-Modified-Since 헤더의 표시 형식이 잘못 표기
    • 서버의 현재시간보다 If-Modified-Since의 표기 시간이 늦는 경우 문제 발생
  • 캐시 동작의 장점 중 하나는 네트워크 대역폭(Bandwidth) 절감 가능 → 프록시 서버에 캐시되어 있는 컨텐츠가 큰 용량인 경우 프록시 서버와 실제 서버간의 네트워크 대역폭을 절약 가능
  • If-Modified-Since 헤더는 If-UnModified-Since 헤더의 반대 의미
    • If-Modified-Since 헤더는 컨텐츠가 변경되었는지를 체크
    • If-Unmodified-Since 헤더는 변경되지 않았는지를 체크


If-Modified-Since (변경된 경우 중심)

  • If-Modified-Since 헤더를 이해하기 위해서는 Last-Modified 헤더의 의미를 먼저 알아야함

    • Last-Modified 헤더는 ETag와 같이 응답헤더
    • Last-Modified 헤더는 단어 의미와 같이 컨텐츠가 마지막으로 변경된 시점 정보를 값으로 가짐
    • 웹서버의 컨텐츠가 가장 마지막으로 수정된 시점을 표현


  • If-Modified-Since 헤더는 캐시(Cache)관련 헤더

    • 웹브라우져(클라이언트)나 캐시서버는 웹 서버의 응답 컨텐츠들을 디스크(Disk)나 램(RAM)에 저장
    • 캐싱(caching)된 이미지등의 컨텐츠들을 유효한지 여부 매번 확인 필요
    • 웹서버에서 컨텐츠가 변경되었는데, 그것을 반영하지 못하면 문제가 발생


  • If-Modified-Since 헤더는 웹브라우져나 캐시서버가 웹서버에게 컨텐츠가 변경되었는지 확인하는 용도로 사용

    1. 웹브라우져 ↔ 캐시서버 : 내가 가지고 있는 이미지를 웹 브라우저에게 직접 줘도 되는지 웹 서버에 확인
    2. 캐시 서버 ↔ 웹 서버 : 응. 나도 똑같은 이미지 가지고 있으니까, 캐시 서버 너가 직접 보내줘


1. If-Modified-Since 헤더 참고 사진



2. 컨텐츠 변경 시 : 200 OK 메시지와 함께 신규 컨텐츠 전송

  1. 클라이언트가 특정 컨텐츠를 요청
  2. 프록시 서버는 클라이언트의 요청을 받아 대신 실제 서버로 전달
  3. 실제 서버는 컨텐츠를 제공하는데 이때, 컨텐츠의 최종 수정시간을 Last-Modified 헤더에 포함하여 전달
  4. 프록시 서버는 실제 서버의 응답컨텐츠를 자신의 디스크(Disk)나 램(RAM)에 저장한후 그대로 클라이언트에게 전달

3. 컨텐츠 미 변경 시 : 304 Not Modified와 함께 페이로드(payload) 미전송

  1. 클라이언트가 같은 컨텐츠를 요청
  2. 프록시 서버는 클라이언트 요청을 받아 서버에 전달할때, 캐시되어 있는 컨텐츠임을 알고 If-Modified-Since 헤더에 Last-Modified 의 값(시간정보)을 표기하여 전달
  3. 실제 서버는 동일한 컨텐츠임을 확인하고 변경된 바가 없으니 직접 제공하라는 메시지를 전달(304 Not Modified)
  4. 프록시 서버는 자신의 디스크(Disk) 또는 램(RAM)에 저장되어 있는 컨텐츠를 클라이언트에게 전달

  • If-Match 헤더를 이해하기 위해서는 ETag 헤더를 먼저 이해하는 것이 좋음
  • ETag 헤더 → 웹서버가 제공하는 컨텐츠들에 각각 부여되는 일종의 식별자 같은 정보
  • 웹서버는 클라이언트에게 컨텐츠를 제공할때 ETag 정보를 같이 전달
  • 클라이언트와 프록시서버들은 웹 서버에게 전달받은 ETag 정보를 다음 요청(subsequence Request)에 활용 가능
  • 캐시기능에서 ETag를 활용 → 사용자가 요청한 컨텐츠가 이전에 제공했던 컨텐츠인지 새롭게 제공해야 할 컨텐츠인지 구별 가능
  • If-Match 헤더는 요청 헤더의 한 종류이고 헤더 값(Value)으로 서버에서 제공해준 ETag 정보를 표기
  • 저장된 리소스가 주어진 ETags의 하나와 일치하는 경우에만 요청을 조건부로 만들고 메소드를 적용
  • 웹서버가 가지고 있는 컨텐츠 별로 ETag 정보를 부여하여 관리하게 되는데, 컨텐츠의 변경시 동시 작업의 경우 컨텐츠 무결성이 훼손 가능 → 컨텐츠 무결성 훼손을 방지하기 위해 If-Match 헤더를 사용


"nature.jpg"라는 자연 이미지 파일 하나가 있다고 가정

  • 아래의 파일 이름(nature.jpg)은 같지만, 내용이 다르기 때문에 웹서버는 이를 구분해야 할때 ETag 정보를 활용 가능
  • 여름은 여름에 맞는 이미지를 서비스 컨텐츠고 제공해야함
  • 여름의 이미지는 겨울에 사용할 수 없기에, 겨울 이미지에 맞도록 변경

If-Match 헤더의 동작 흐름

1. 클라이언트 A와 클라이언트 B가 서버에게 전달받은 이미지는 같은 것이므로, ETag 정보도 같음 → 둘 다 ETag를 AABB로 가정

  • 클라이언트 A가 특정 컨텐츠(자연 이미지->여름)를 요청
  • 서버는 자연 이미지를 클라이언트 A에게 ETag 정보와 함께 정상적으로 전송
  • 클라이언트 B가 같은 이미지를 요청
  • 서버는 클라이언트 A에게 제공했던 같은 이미지를 B에게도 ETag 정보와 함께 전달
  • 클라이언트 A와 클라이언트 B가 서버에게 전달받은 내용은 같기때문에 같은 ETag 정보도 가지고 있음

2. 클라이언트 A가 겨울복장의 트와이스 이미지로 변경한 이후, 클라이언트 B가 ETag AABB 이미지를 변경 요청

  • 클라이언트 A가 PUT 요청방식(Method)를 이용하여 자연 이미지를 여름에서 겨울로 변경
  • 클라이언트 A가 이미지를 변경하였기에 서버가 기존에 가지고 있는 이미지의 ETag와 다른 Etag가 저장
  • 서버는 컨텐츠 이미지가 변경되었으므로 더이상 AABB 의 Etag 정보를 가진 컨텐츠를 제공 X
  • 클라이언트 B가 클라이언트 A가 작업을 한지 모르고 PUT 방식을 이용하여 이미지 변경 요청 → ETag AABB 이미지 변경 요청
  • 웹서버는 클라이언트 B가 전달해 준 ETag 정보(여름의 자연 이미지)와 다르기 때문에 실패라는 메시지를 클라이언트 B에게 전송

3. If-Match 헤더의 값으로 *(asterisk)" 를 사용

  • 컨텐츠의 내용은 모르지만 파일이 존재하는 경우, 클라이언트의 요청을 서버에서 처리할 수 있음
  • 클라이언트 B가 If-Match 의 값으로 특정 파일의 ETag AABB가 아닌 *(asterisk)를 사용했다면, 클라이언트 A가 이미 변경했음에도 불구하고 클라이언트 B가 요청한 이미지 변경 동작이 처리
  • If-Match 헤더에 *(asterisk)를 사용하면 파일 검증없이 변경이 됨으로 위험함 → 주의해서 사용해야함


문법

If-Match: <etag_value>
If-Match: <etag_value>, <etag_value>, …



지시자

1. <etag_value>

  • 요청된 리소스를 고유하게 나타내는 엔터티 태그
  • 큰따옴표(예: "675af34563dc-tr34") 사이에 배치된 ASCII 문자 문자열
  • W/"약함"을 나타내기 위해 접두사를 사용 가능
  • 리소스를 의미론적으로 나타내지만 바이트 단위로 나타내지 않음
  • If-Match 헤더에서 약한 엔터티 태그는 일치 X

2. * (asterisk)

  • 별표는 모든 리소스를 나타내는 특수 값

3. If-Match 헤더 사용 예시

If-Match: "bfc13a64729c4290ef5b2c2730249c88ca92d82d"
If-Match: "67ab43", "54ed21", "7892dd"
If-Match: *

※ 이미지 제공 : https://papers.co

Host 헤더

  • Host 헤더는 HTTP 1.1 버전에서 새로 추가된 헤더
    Host 헤더가 없는 HTTP 1.0 버전에서는 10개의 고객사 홈페이지를 운영하기 위해서는 1대의 물리적인 서버에서 운영 어려움 (거의 불가능)
  • Host 헤더가 없는 형태로 요청이 서버로 전송됨 → 웹서버는 Host 헤더가 요청으로는 어느 회사 홈페이지로 접속했는지 알 수 없음
  • HTTP 1.1 버전에서 Host 헤더가 HTTP 요청에 추가되면서, 흔히 알고 있는 가상 호스팅(Virtual Hosting)이 가능하게 됨
  • 가상 호스팅(Virtual Hosting)으로 IP가 같아도 고객사 도메인을 모두 구분하여 처리 가능
  • Host 헤더에는 클라이언트가 접속을 시도한 웹사이트 도메인 네임의 정보가 표시
  • IP 주소가 아닌 Host 헤더의 값을 가지고 고객사를 구분
  • IP 주소의 의미가 없어지면서 물리적인 한대의 웹서버에 여러개의 웹어플리케이션을 운영
    GET / HTTP/1.1
    Accept: */*
    User-Agent: Mozilla/5.0
    Host: www.Acompany.com

※ 참고

  • HTTP Host 헤더가 없기 때문에 클라이언트가 보낸 헤더의 내용만으로는 구분이 불가능 → IP 주소로 구분 가능
  • 한대의 물리적인 서버에 2개 이상의 NIC 포트가 있는 경우에는 포트 개수만큼의 웹어플리케이션 운영이 가능 → NIC 포트에 각각 다른 IP를 부여해야하기에 많은 IP가 사용됨


가상호스트(Virtual Hosts)

  • 웹 초창기 웹을 이용하는 클라이언트(사용자)는 극히 제한적
  • 웹 초창기 웹 서버의 역할 또한 정보를 제공하는 단순한 수준
  • 현재 웹서비스는 이메일, 웹하드, 쇼핑, 티켓구매, 은행등등 다양해졌고, 클라이언트(사용자)의 스펙트럼도 굉장히 넓어짐
  • 다양한 웹어플리케이션을 동작하기 위해서는 물리적인 웹서버의 수가 많이 필요 -> 많은 물리적인 웹 서버를 운영하는데 어려움이 있음

가상호스트(Virtual Hosts)가 적용 X

  • 10개의 어플리케이션의에는 10개의 서버가 필요
  • 어플리케이션들의 역할이 모두 다르기 때문에 서비스 IP나 도메인을 서로 다르게 설정 필요
  • 10개의 서버를 위치시킬 물리적인 공간이 필요
  • 10개의 웹어플리케이션중에서도 사용량이 적은 서비스의 경우에는 CPU, 메모리등의 서버 자원 낭비가 발생


가상호스트(Virtual Hosts)가 적용 O

  • HTTP 1.1에서는 가상호스트(Virtual Hosts)를 사용하기 위해 Host 헤더 추가
  • 단순한 Host 헤더 하나가 추가되었을 뿐인데, 웹서비스를 제공하는 경우 많은 이익이 생김
  • 가상호스트(Virtual Hosts)는 하나의 물리적인 서버에서 다수개의 웹서비스를 운영이 가능하게 한 기능 → 서비스 도메인(웹주소)은 서로 다르더라도 한개의 IP 주소로 모든 서비스를 가능
  • 웹호스팅 업체들은 HTTP의 가상호스트(Virtual Hosts)기능이 중요함

리다이렉션(Redirection)

  • 가상호스트(Virtaul Hosts)가 하나의 서버에서 복수개의 웹사이트를 운영 가능케 했다면, 리다이렉션은 하나의 사이트가 복수개의 웹서버를 이용할 수 있게 해줌
  • 가상호스트는 복수개를 하나로 모으는것이고, 리다이렉션은 하나를 복수개로 연결하는 것
  • 리다이렉션은 서버가 클라이언트(사용자)를 다른 URI로 전달
  • 리다이렉션은 매우 다양한 웹환경에서 필수 기능으로 웹어플리케이션의 리비젼, 컨텐츠 재배치등과 같이 어떤 변화에 유연하게 대처할 수 있게 해줌
  • 리다이렉션은 물리적으로 다른 서버로도 클라이언트를 안내할 수도 있지만, 동일서버의 다른 컨텐츠로 연결하는 것 역시 가능

리다이렉션(Redirection) 예시

  • 클라이언트가 첫번째 웹 서버의 컨텐츠를 요청
  • 첫번째 웹 서버는 컨텐츠 대신 301 Moved 상태코드를 클라이언트에게 전송 → 응답데이터에는 301 Moved 상태코드와 함께 리다이렉션을 수행할 URI 정보도 포함됨
  • 클라이언트는 3단계와 같이 리다이렉션할 URI로 새로운 접속과 요청을 시도
  • 리다이렉션 URI 주소를 가지고 있는 웹서버는 200 OK 상태코드와 함께 컨텐츠를 전송


http://naver.com 주소로 클라이언트의 요청하면 301 응답 코드와 https://www.naver.com 주소를 리다이렉션(Redirection) 응답으로 전달

  • 301 Moved permanently 응답 코드
  • Location 헤더내에 리다이렉션 할 웹사이트 주소 → https://www.naver.com
    $ curl -vv http://naver.com
    *   Trying 223.130.195.95:80...
    * Connected to naver.com (223.130.195.95) port 80 (#0)
    > GET / HTTP/1.1
    > Host: naver.com
    > User-Agent: curl/7.71.1
    > Accept: */*
    >
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 301 Moved Permanently
    < Server: NWS
    < Date: Sat, 06 Nov 2021 16:34:43 GMT
    < Content-Type: text/html
    < Transfer-Encoding: chunked
    < Connection: keep-alive
    < Location: http://www.naver.com/  # http://naver.com -> http://www.naver.com 전송
    < Vary: Accept-Encoding,User-Agent
    <
    <html>
    <head><title>301 Moved Permanently</title></head>
    <body>
    <center><h1>301 Moved Permanently</h1></center>
    <hr><center> NWS </center>
    </body>
    </html>
    * Connection #0 to host naver.com left intact

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

HTTP 프로토콜 If-Modified-Since헤더  (0) 2022.06.25
HTTP 프로토콜 If-Match 헤더  (0) 2022.06.25
HTTP 프로토콜 Expires 헤더  (0) 2022.06.25
HTTP 프로토콜 Expect 헤더  (0) 2022.06.25
HTTP 프로토콜 ETag 헤더  (0) 2022.06.25
  • 캐시서버(Cache server)는 저장한 컨텐츠들의 유효성 확인이 필수 → 클라이언트에게 캐시서버가 직접 컨텐츠를 전달해야 되는지 또는 그렇지 않은지에 대해 판단 (제공된 컨텐츠가 항상 신선해야함)
  • 캐시서버가 클라이언트에게 전달해주는 컨텐츠가 신선한지 확인하는 HTTP 헤더가 몇가지 있는데, Expires 헤더가 그 중 하나
  • Expires 헤더는 응답이 더 이상 신선하지 않다고 판단할 날짜/시간을 포함
  • Expires 헤더는 단어 뜻 그대로 컨텐츠의 유효기간
  • Expires 헤더에 명시되어 있는 기간이 지나게 되면, 더 이상 유효한지 아닌지를 실제 웹서버에서 확인 필요
  • 만약 웹서버가 제공하는 컨텐츠가 캐싱되지 않기를 원한다면, Expires 헤더의 값을 응답하는 Date 헤더의 값과 같거나 지난 날짜를 설정해서 전달하면 됨 → 0과 같은, 유효하지 않은 날짜는 과거의 시간을 나타내어 리소스가 이미 만료되었음을 의미
  • Cache-Control은 HTTP 1.1에서 등장한 헤더로, 응답 내에 "max-age" 혹은 "s-max-age" 디렉티브를 지닌 Cache-Control 헤더가 존재할 경우, Expires 헤더는 무시


문법

  • <http-date>에는 timestamp 값이 들어감
    Expires: <http-date>

Expires 헤더 사용 예제

Expires: Mon, 21 Aug 2017 09:00:05 GMT

Expires 예제 사진

  • POST 메소드와 PUT 메소드는 HTTP 요청 방식(Method)에 사용될 때, 클라이언트가 웹서버에게 어떤 데이터를 전달하고자 할때 사용
  • Expect 헤더는 클라이언트가 웹서버에게 어떤 데이터를 전달하고자 할때, 사용되는 헤더
  • Expect 헤더는 "돌다리도 두들고 보고 건너라 "에 속하는 헤더
  • 클라이언트가 웹서버에 데이터를 전달할때, TCP 3-way handshake를 통해 세션이 맺어지면 HTTP 통신할 준비가 되었다고 보고 바로 전달하려는 데이터를 보낼 것
  • 웹서버가 클라이언트에게 전달받아서 처리할 수 있는 데이터의 사이즈가 고정 → 클라이언트는 전송할 수 있는 데이터 사이즈를 확인하고 보내야 보다 안전하고 정확하게 전달 가능(Expect 헤더 기능)
  • Expect 헤더를 사용하면, 서버가 처리불가능한 데이터(payload)는 보내지 않게 되므로, 불필요한 네트워크 대역폭 사용의 낭비를 줄일 수 있음
  • 일반적인 브라우저는 Expect 헤더를 전송하지 않지만, cURL과 같은 몇가지 클라이언트들은 전송함


문법 → 현재는 "100-continue" 를 제외하고 어떤 Expect 헤더의 값에 사용 X

Expect: 100-continue



Expect 헤더를 추가하여 클라이언트와 웹 서버간 통신하는 방식

  • 클라이언트가 전달할 데이터가 있는데, 처리 가능한지를 서버에게 확인 요청. (Expect 헤더 사용)
  • 서버는 가능한 경우 클라이언트에게 100 Continue 응답 코드를 통해 알림 (100 Continue)
  • 클라이언트가 데이터를 서버에게 전송
  • 서버는 클라이언트에게 정상적으로 처리되었음을 알림

webdav 서버에서 Expect 헤더를 추가하여 테스트 (제한한 데이터 사이즈보다 작은 데이터 전송)

  • webdav서버의 upload 파일용량을 1024 byte로 제한
  • 클라이언트가 WEBDAV 서버에 I love you 라는 텍스트가 담긴 파일을 업로드
  • 페이로드 사이즈(payload)가 1024 보다 작기 때문에 정상적으로 서버에 생성되었음을 응답코드(201 Created)를 통해 확인 가능

webdav 서버에서 Expect 헤더를 추가하여 테스트 (제한한 데이터 사이즈보다 큰 데이터 전송)

  • webdav서버의 upload 파일용량을 1024 byte로 제한
  • 데이터 사이즈를 웹서버의 제한용량보다 크게 설정 → 컨텐츠 사이즈를 1029 로 설정
  • 웹서버에서 100 continue가 아닌 "413 Request Entity Too Large"라는 에러코드를 보내고 세션을 끊음
  • 웹서버에서 처리할 수 있는 용량을 초과할 경우 불필요한 데이터 전송이 이루어 지지 않음
  • 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