# 질문과 답변

## Q. 캐시망에서 형제 캐시 사이 인터넷 트랜짓을 허용하지 않는다는 의미?

### 자훈

* 형제 캐시를 통해 외부로 메시지를 보내는 것이 허용되지 않는다 -> 질의를 통해 캐싱된 응답이 있으면 받아오는 것만 가능
* 다른 캐시를 통한 인터넷 트랜짓이 허용된다면?
  * 캐시망을 사용하면 캐시망 내부의 여러 캐시들에 특정 요청에 대해 캐싱된 응답이 하나만 존재할 것으로 기대 -> 여러 캐시에 동일한 응답이 캐싱되어있을 가능성이 생긴다?
  * 캐시망 내 여러 캐시가 요청을 보내 빈번한 인터넷 트랜짓이 발생한다면 같은 레이어의 캐시들에서 (형제 캐시) 일관성이 없는 여러 요청들을 캐싱하여 관리해야 하는 부담 (부모 캐시가 담당해야 할 역할) 이 생길 수 있다?

> 우빈 코멘트: 캐시망 안에서도 중복된 사본이 존재할 수 있다. (20장 ICP 참고)

### 명근

캐시 프록시가 클라이언트로부터 요청을 받을 때 이에 대한 응답으로

* 본인이 가지고 있는 캐싱 오브젝트
* 없다면, 형제 캐시 프록시가 가지고 있는 캐싱 오브젝트

로 응답한다.

그러나, 원 서버에 요청할 때는 형제 캐시를 거쳐 가지 않는다.

> 부모 캐시의 경우에는 거쳐 갈 수 있다. 이미 원서버로 향하는 길이 부모 캐시로 향하는 길과 같기 때문.

**용어 설명**

**캐시망**

캐시들로 이루어진 망. 그 사이에 캐시들 중 같은 레이어에 있는 캐시를 형제 캐시로 일컫음.

**인터넷 트랜짓**

보다 작은 네트워크 망이 큰 외부 네트워크에 연결하는 행위

### 일식

* internet transit의 예로는 ISP가 더 큰 internet 에 접속할 수 있게 하는 것 등을 말한다.
* 따라서 형제 캐시 사이 인터넷 트랜짓을 허용한다면, 캐시 hierarchy의 대원칙을 위배하는 게 아닐까.
* 즉, parent cache를 통해 특정 문서를 받아야 하는데 직접 인터넷에서 받으면, 그 캐시망 혹은 구조를 위배할 것.

**ref**

* <https://en.wikipedia.org/wiki/Internet_transit>
* <https://en.wikipedia.org/wiki/Peering>

## Q. 캐시 서버는 캐싱된 응답의 메타데이터를 어떻게 관리할까

### 자훈

* 캐시 서버 구현마다 다르다(...)
* Example (AWS S3)
  * HTTP/1.1 에 정의된 metadata
    * Cache-Control
    * Content-Disposition
      * attachement 를 값으로 넣어주면 파일을 렌더링하지 않고 바로 다운로드
    * Content-Type
    * Content-Language
    * Expires
    * Content-Encoding
  * S3 전용 metadata
    * Website Redirect Location
      * web site 에서 해당 리소스에 접근했을 때 다른 URL로 redirection
    * x-amz-meta-\[user-defined-tag]
      * 사용자 정의 메타데이터
      * 객체에 추가적인 설명을 넣을 때 사용
    * x-amz-server-side-encryption
      * 데이터 암호화 옵션
    * x-amz-version-id
      * 파일의 버전을 표시
    * x-amx-delete-marker
      * 파일 삭제 시 바로 파일을 삭제하지 않고 해당 태그의 값을 true 로 변경

### 명근

#### 캐싱된 응답의 메타데이터?

캐시 프록시는 언제 만료될 것인지, 언제 서버에서 전송되었는지, ..., 경우에 따라서는 (책에 나와 있는 대로 `정교한 캐시의 경우`) 클라이언트의 요청도 저장하곤 한다.

#### 이걸 어떻게 관리??

이러한 데이터는 캐싱된 응답과 함께 하나의 오브젝트로 관리되지 않을까? 찾아도 잘.... 안 나오는데ㅠㅠ

왜냐하면 특정 요청에 대한 응답 자체도 헤더와 바디가 합쳐진 메시지 형태로 한꺼번에 내려주기 때문에..

### 일식

* 응답 객체의 헤더를 통해 관리하지 않을까.
* 만일 연산이 필요한 데이터라면 메모리에서만 관리할 듯.
* (찾기 힘들어요..ㅠ)

**ref**

* 비공식적 두뇌.

## Q. HTTPS 요청도 인터셉트 프락시가 가로채서 캐싱해 줄 수 있나?

### 자훈

* Client - Intercept proxy server 사이에 HTTPS connection 이 맺어지는 것이기 때문에 암호화된 요청 메세지의 decryption 이 가능해 HTTP 요청 캐싱과 다를 것이 없을 것으로 생각된다?(...)

### 명근

#### 어떤 상황인가?

* Client 는 원 서버 또는 특정 프록시에 요청을 보낸다.
* 그 사이에 Client 에게는 보이지 않는 인터셉트 프록시가 데이터를 가로채 분석하고 캐싱하여 관리한다.

#### 인터셉트 프록시가 HTTPS 요청을 가로챌 수 있다면?

요청에 대한 응답을 캐싱하여 효율을 높일 수 있지만,

Client 와 Server 사이에만 유효한 Encrypted Data 가 중간자공격으로 인해 Decrypt 되어 감시당하거나 변조될 수 있다는 뜻. 뭔가 위험해 보인다.

#### 중간에 있는 인터셉트 프록시가 HTTPS Connection 을 대신 받아 맺는 것이 가능한가?

중간자 공격에 의해서만 가능하다.

프록시 용도로 사설 기관 또는 신뢰 가능한 루트 기관으로부터 서명을 부여 받을 수 있음.

[그 이상은 이해가 가지 않는다](https://ryusstory.tistory.com/entry/HTTPS-Interception-Proxy)

### 일식

* 인터셉트 프락시는 원래 하는 일이 클라이언트에서 서버로 가는 트래픽을 가로채 캐시된 응답을 돌려주는 것.(p.167)
* `Finally intercepting connections can cause problems for HTTP caches, as some requests and responses become uncacheable by a shared cache.`
* 할 수 있으나, uncachable한 응답을 캐싱하면 문제가 발생할 수 있다.

**ref**

* <https://en.wikipedia.org/wiki/Proxy_server>

## Q. 같은 캐시망 내에서 형제 캐시가 데이터 있음을 어떻게 알 수 있을까?

### 자훈

* 캐시망 내의 통신은 HTTP 보다 가볍고 빠른 ICP 를 사용하여 이루어짐
* Internet Cache Protocol
  * 웹 캐시 조정을 위한 UDP 기반의 프로토콜 (UDP 로 제한될 필요는 없음)
    * 조회를 위한 가벼운 통신이 필요하기 때문에 UDP 사용
  * 여러 캐시를 사용하는 단일 사이트에서 요청 객체에 대한 적절한 위치를 찾기 위한 목적
  * 계층적 구조로 구성되며 부모와 형제가 존재
  * 로컬 캐시에서 요청 응답을 찾지 못하면 부모 캐시로 요청을 전달할 수 있음
  * 형제 캐시는 같은 계층에 존재하며 형제 캐시 사이 부하 분산이 목적
  * sibling cache cluster 로 요청이 오면 ICP 를 사용해 sibling cache 들에게 질의한다
    * object가 sibling cache 에 캐싱되어 있는 경우 origin server 에는 요청하지 않으며, 이것을 'near miss' 라고 함
  * ICP 는 캐시 사이 RTT ,origin server 로의 요청. 불필요한 복제를 줄일 수 있지만 캐시 서버 사이의 통신횟수를 증가시켜 성능이 줄어들 수 있다
* ICP packet

```
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Opcode    |    Version    |         Message Length        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                         Request Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                            Options                            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                          Option Data                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       Sender Host Address                     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   |                            Payload                            |
   /                                                               /
   /                                                               /
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```

```
Opcode
   Value    Name
   -----    -----------------
       0    ICP_OP_INVALID
       1    ICP_OP_QUERY
       2    ICP_OP_HIT
       3    ICP_OP_MISS
       4    ICP_OP_ERR
     5-9    UNUSED
      10    ICP_OP_SECHO
      11    ICP_OP_DECHO
   12-20    UNUSED
      21    ICP_OP_MISS_NOFETCH
      22    ICP_OP_DENIED
      23    ICP_OP_HIT_OBJ
```

* ICP OP QUERY
  * payload 에 요청자의 host address (최초 요청 client) 와 요청 URL 을 포함

```
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                     Requester Host Address                    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                                                               |
      /                       Null-Terminated URL                     /
      /                                                               /
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    응답으로 HIT, MISS, ERR, NOFETCH, DENIED, HIT_OBJ 중 하나를 내려줘야 함
```

* ICP OP HIT
  * 요청 URL 이 로컬 캐시에 존재하며 요청자의 접근을 허용
* ICP OP MISS
  * 요청 URL 이 존재하지 않음, 그러나 해당 캐시가 요청 URL 을 찾아오게 할 수 있음
* ICP OP ERR
  * 요청 메세지를 처리하는 도중 예외가 발생했음을 알림

> ref1. [RFC 2186 - Internet Cache Protocol (ICP), version 2](https://tools.ietf.org/html/rfc2186)
>
> ref1. [ICP, Internet Cache Protocol](http://www.networksorcery.com/enp/protocol/icp.htm)
>
> ref2. [Internet Cache Protocol - Wikipedia](https://en.wikipedia.org/wiki/Internet_Cache_Protocol)

## must-revalidate vs no-cache

### 논의 결과

1. no-store: 캐시에 사본을 저장할 수 없다.
2. no-cache: 캐시에 사본을 저장하되, **클라이언트에 보내기 전 무조건 재검사**한다. 클라이언트에서 max-stale 등으로 여유를 주어도 무조건 재검사해야 함.
3. must-revalidate: 유효기간이 만료되지 않았을 땐 재검사하지 않아도 된다. 만료되었을 때는 재검사해야 한다. must-revalidate + max-age=0 조합은 no-cache와 같다.
4. max-age: 만료 시간만 정한다. 클라이언트에서 max-stale을 보냈다면, 재검사할 필요가 없을 때는 오래된 문서를 보낼 수 있다.
5. 재검사가 필요한 경우 서버가 응답하지 않으면 어느 경우든 에러를 내려 주어야 한다.

### 명근

#### no-cache

* cache 된 데이터를 가져와도 되지만 서버를 통해 항상 validate 한 뒤 가져오도록 해야 함.
* 그러나 stale 된 데이터를 줄 수도 있음.

  > 서버가 응답하지 못 한다면 상황에 따라 유저를 위해 stale 된 데이터를 내려준다.

#### must-revalidate

* 만료되었다면 무조건 서버로부터 validate 한 데이터를 가져와야 함.
* stale 된 데이터에 대해 504 error 를 발생.
* critical transaction 에서 사용하기 적합함.

### 일식

* content router는 cached content에 접근할 수 있게 하므로, 검색하여 데이터가 있음을 알 수 있지 않을까?

**ref**

* <https://tools.ietf.org/html/rfc3040>
