HTTP 디렉티브 & 응답코드
Validation Part 요약
Last-Modified with If-Modified-Since
Last-Modified
: header field that informs last modified timeIf-Modified-Since
: Field that asks if there has been any modification after the given time.
ETag with If-Match
ETag
: Field that informs any Entity Tag of text, determined in a serverIf-Match
: Field to compare if text's Entity Tag is matched, use the same process method with IMS
Cache Control Part 요약
Pragma
: no-cache (Applicable to HTTP 1.0)Cache-Control
: no-cacheAge
: Field that informs the age of textExpires
: Field that informs when the text will expireDate
: Field that shows the time of web serverCache-Control
: Field that informs the oldest age of text
Expire
Expires: Fri, 30 Oct 1998 14:19:41 GMT
- 얼마동안 Fresh한 상태인가 ?
- 만료시간 이후에 Cache는 항상 Origin 서버에 변경 여부를 확인
- 절대적인 만료시간을 지정하거나 마지막 접근시간 또는 최종 변경 시간을 설정
- 모든 Cache가 지원하며 Static Image에 매우 효과적 (상당히 먼 미래로 설정)
- 정기적으로 변경되는 페이지도 효과적 (Cache가 만료시간 이후 자동으로 갱신)
- 과거 또는 바로 현재 시간으로 설정하면 Non-cacheable 효과
- 로컬 시간이 아닌 GMT (Greenwich Mean Time)으로 설정
- Origin 서버와 Cache는 시간 동기화가 필요하며 Object 변경 시 만료시간 업데이트에 주의
Pragma
Pragma: no-cache
- HTTP 1.0 규정으로 클라이언트 및 Cache 서버 요청/응답 헤더에 존재
- 클라이언트가 해당 객체가 경로상의 어떠한 Cache에서도 캐싱하지 않기를 요청
- 많은 Browser에서 여전히 사용하고 있으므로 역방향 호환성을 위해서 사용
- Origin 서버의 소프트웨어에 의해 무시될 수 있음
- HTTP 1.1에서 Cache-Control 필드로 변경됨
Cache-Control
- HTTP 1.1 규정
- 콘텐츠 제작자가 Cache를 제어하기 위해서 설정
- Cache-Control 헤더 필드에 max-age 디렉티브가 지정되어 있는 경우 Expires 헤더 필드보다 max-age 디렉티브의 지정이 우선됩니다.
Cache-Control: max-age
>Expire
max-age=[seconds]
- Expire와 비슷하게 Fresh한 상태로 여길 수 있는 최대 시간을 설정
- 만료시간과 마찬가지로 특정 시간이라기보다는 요청 시간과 관련
- 요청 받은 시간으로부터 설정해준 [초]까지 컨텐츠 업데이트 불필요
Private
- 요청한 클라이언트에게만 캐싱을 허용
- private을 명시적으로 지정하지 않으면 public으로 간주
Public
- 기본값으로써 모든 클라이언트 및 Cache에서 캐싱 허용
- HTTP 인증이 요구되는 경우는 자동적으로 응답을 캐시하지 않음
no-cache
- 클라이언트 요청 및 Origin 응답 헤더에 존재
- 매회 Cached 객체를 사용자에게 전달하기 전에 Cache에서 Origin 서버로 유효성 확인
- no-cache 필드가 존재하는 요청은 Cache에 저장되어지지 않고 Forwarding 되어짐 (-> Origin Server)
- 인증이 중요시 되는 경우 유용하며 계속적으로 업데이트되어야 할 객체에 유용
no-store
- 어떠한 경우라도 객체가 캐시 되지 않도록 함
- no-cache는 Cache 서버의 설정에 따라 무시될 수 있지만, no-store는 무시될 수 없음
- 동적 데이터, 개인정보 등에 사용
must-revalidate
- Origin 서버가 Cache에게 객체의 변경 여부에 대한 헤더 정보를 반드시 따르도록 규정
- 이 헤더를 설정함으로써 Cache가 Origin 서버에서 설정한 값을 철저하게 준수해야 함
- Cached 객체가 Stale 상태라면 새로운 요청은 반드시 Origin 서버에서 Re-validate 해야 함
Proxy-revalidate
Cache-Control: max-age=3600, must-revalidate
- must-revalidate와 비슷하지만, 오직 Proxy Cache만 사용
Validation
- Cache에 저장된 문서가 Origin 서버에 있는 것과 동일한 것인지 비교
- 콘텐츠의 변경 여부를 확인하기 위해 Origin 서버와 Cache간에 확인하는 절차
Validator
Expire
,Cache-control
,Last-Modified
및Etag
(HTTP/1.1)- Validator가 모두 없을 경우, 캐싱 하지 않음
클라이언트 (클라이언트 요청 헤더)
If-Modified-Since (IMS)
- 브라우저나 캐시서버에 의해 전송
- 이전에 서버로부터 수신한 Last-Modified 값임
If-None-Match
- IMS를 인식하지 못하는 서버를 위해 전송
- 이전에 서버로부터 수신한 Etag 값
Origin 서버 (서버 응답 헤더)
Expire
- 객체의 만료시간을 설정 (절대값 혹은 상대값)
- Non-cacheable하게 할 경우 과거 또는 서버의 시간과 동일하게 설정
Last-Modified
Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT
- Origin 서버의 응답 헤더에 존재
- 요청된 객체가 마지막으로 업데이트된 시간
- 요청된 객체가 마지막으로 업데이트된 시간
- Cache 서버는 이 값으로 객체의 신선도를 체크
ETag
- HTTP 1.1 규정으로 오리진 서버의 응답 헤더에 존재
- 오리진 서버에서 생성되는 인자로써 컨텐츠 업데이트 마다 변경
- 일반적으로 Cache는 Last-Modified 시간을 사용해 컨텐츠 업데이트 여부를 판단
- Etag 또한 많이 사용되고 있는 추세
- 요청된 객체가 마지막으로 업데이트된 시간
- Cache 서버는 이 값으로 객체의 신선도를 체크
If-Modified-Since
- 클라이언트 또는 Cache 요청 헤더에 존재
- 클라이언트 및 Cache는 저장된 객체의 Last-Modified 값을 Origin 서버로 확인 요청
- Origin 서버의 Last-Modified 값이 If-Modified-Since 값보다 최근일 경우, 객체는 Re-load
- 시간이 같을 경우 Origin 서버는 304 Not Modified 전송, Cache는 카운터만 리셋
If-Match
- Cache는 If-Match 요청으로 컨텐츠의 ETag 변경 여부를 확인
Cacheable
- 만료시간(Expire)이 설정된 경우
- Cache-Control: no-cache로 지정되지 않은 경우
- 위의 설정이 모두 없는 경우 default로 cacheable임
- HTTP/1.1 규정
Non-Cacheable
- Pragma: no-cache로 지정한 경우 (HTTP/1.0)
- Cache-Control: no-cache로 지정한 경우 (HTTP/1.1)
- GET Method에서 동적 데이터 요청 시
- POST Method 이용 시
- Set-Cookie 이용 시
Stale
- Cacheable로 신선하지 않은 객체
- Fresh 상태에서 만료 시간이 경과한 객체
- 클라이언트의 다음 요청시 반드시 Re-validation 하거나 Re-load
Re-validation
: Cache가 Origin 서버에 해당 객체의 변경 여부를 확인하는 행위Re-load
: 객체가 변경되었으면 새로운 객체로 갱신하는 행위
캐시 Tip 7
- 고정된 URL 주소를 사용
- 공통의 이미지 라이브러리 사용
- 잘 바뀌지 않는 이미지나 페이지는 캐시 값을 크게
- 정기적으로 업데이트되는 페이지는 적절한 캐시 값 설정
- 만약, 리소스가 바뀌면 이름 바꾸기
- 불필요한 파일 변경 하지 않기
- 쿠키는 필요할 때만 사용
HTTP 응답코드
- 1xx: 요청을 받았으며 프로세스를 계속해서 진행
201 Created
- 요청이 성공적이었으며 그 결과 새로운 리소스가 생성됨, 이 응답은 일반적으로 POST 요청 또는 일부 PUT 요청 이후 전달
206 Partial Content
- 클라이언트에서 복수의 스트림을 분할 다운로드를 하고자 범위 헤더를 전송했기 때문에 사용되며 클라이언트가 이어받기를 시도하면 웹서버가 이에 대한 응답코드로 206 Partial Content와 함께 Range 헤더(byte)에 명시된 데이터의 부분부터 전송을 시작
301 Moved Permanently
- 요청한 리소스의 URI가 변경되었음을 의미
304 Not Modified
- 클라이언트에게 응답이 수정되지 않았음을 알려주며 클라이언트는 계속해서 응답의 캐시된 버전을 사용할 수 있음
307 Temporary Redirect
- 클라이언트가 요청한 리소스가 다른 URI에 있으며, 이전 요청과 동일한 메소드를 사용하여 요청해야 할 때, 서버가 클라이언트에 이 응답을 직접 전송
400 Bad Request
- 이 응답은 잘못된 문법으로 인하여 서버가 요청을 이해할 수 없음을 의미
401 Unauthorized
- 클라이언트가 인증되지 않았거나 유효한 인증 정보가 부족하여 요청이 거부되었음을 의미
- 사용자가 로그인되지 않은 상태로 API를 호출한 경우
403 Forbidden
- 서버가 해당 요청을 이해했지만 권한이 없어 요청이 거부되었음을 의미하는 상태값이며 클라이언트가 해당 요청에 대한 권한이 없을 때 전달
- 사용자가 권한이 없는 요청을 하는 경우
403이 발생했다는 것은 "해당 요청에 대한 자원이 존재함"을 내포하고 있어 "리소스의 존재 여부"를 알 수 있으므로 취약점이 될 수 있어 보안 정책에 따라서 권한이 없음을 알려주는 것이 아니라 자원의 존재 자체를 숨겨 404 Not Found를 응답으로 전달해주는 것이 적합할 수도 있다. 대표적으로 다른 사용자 Github의 비공개 레포지토리에 접근하는 경우 403이 아닌 404를 응답으로 전달해준다.
404 Not Found
- 서버는 요청받은 리소스를 찾을 수 없음
500 Internal Server Error
- 웹 사이트 서버에 문제가 있음
502 Bad Gateway
- 서버가 게이트웨이로부터 잘못된 응답을 수신했음을 의미하며 인터넷상의 서버가 다른 서버로부터 유효하지 않은 응답을 받은 경우 발생
503 Service Unavailable
- 서버가 요청을 처리할 준비가 되지 않았으며 일반적인 원인은 유지보수를 위해 작동이 중단되거나 과부하가 걸린 서버
504 Gateway Timeout
- 웹페이지를 로드하거나 브라우저에서 다른 요청을 채우려는 동안 액세스하고 있는 다른 서버에서 적시에 응답을 받지 못했음을 의미, upstream(원본 서버)와 프록시 서버간의 통신 시간이 타임아웃을 초과했을 때 발생
- connect_timeout
- 주로 upstream 연결 지연으로 발생, 대부분의 upstream은 가까운 위치에 있어 자주 발생하지 않으나, 방화벽에 의해 proxy 연결이 차단될 경우 발생할 수 있다.
- 연결은 TCP/IP의 3-way handshake로 이루어지며, 지정된 시간 내에 SYN+ACK 응답을 받지 못하면 오류가 발생한다.
- send_timeout
- 데이터 전송 지연 시 발생한다. 대표적으로, 사용자가 대용량 파일 업로드 중 속도 저하로 인해 발생할 수 있다.
- read_timeout
- upstream에서의 응답이 지연되면 이 오류가 발생한다. 백엔드 서버에서 복잡한 작업을 수행하거나, 다른 이유로 인해 응답이 지연되는 경우가 대부분이다.
- 여기서 중요한 점은 클라이언트가 504 오류를 반환받더라도 요청은 이미 전송된 상태이므로, 리버스 프록시가 연결을 끊어도 upstream 작업은 계속 수행된다.