Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IV. 엔터티 인코딩 국제화] 15장 엔터티와 인코딩 (15.6~15.10) #24

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 228 additions & 0 deletions 15장-엔터티와 인코딩/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
# 15장 엔터티와 인코딩

## 15.6 전송 인코딩과 청크 인코딩

### 15.6.1 안전한 전송

전송 인코딩은 다른 프로토콜에서도 네트워크를 통한 **안전한 전송**을 위해 존재했다.
HTTP에서 전송된 메시지의 본문이 문제를 일으키는 경우 중 두 가지를 들면 다음과 같다.

- **알 수 없는 크기**
- **보안**

### 15.6.2 Transfer-Encoding 헤더

전송 인코딩 제어 및 서술하기 위해 정의된 헤더는 다음과 같다.

- **Transfer-Encoding**
안전한 전송을 위해 어떤 인코딩이 메시지에 적용되었는지 수신자에게 알려준다.

- **TE**
어떤 확장된 전송 인코딩을 사용할 수 있는지 서버에게 알려주기 위해 요청 헤더에 사용한다.

```
GET /new_products.html HTTP/1.1
Host: www.joes-hardware.com
User-Agent: Mozilla/4.61 [en] (WinNT; I)
TE: trailers, chunked
```

```
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Server: Apache/3.0
```

### 15.6.3 청크 인코딩

청크 인코딩은 메시지를 일정 크기의 청크 여럿으로 쪼갠다.
서버는 각 청크를 순차적으로 보낸다.

- **청크와 지속 커넥션**
지속 커넥션에서는, 본문을 쓰기 전에 반드시 Content-Length 헤더에 본문의 길이를 담아 보내야 한다.
콘텐츠가 서버에서 동적으로 생성되는 경우에는, 보내기 전에 본문의 길이를 알아내는 것이 불가능하다.
청크 인코딩은 서버가 본문을 여러 청크로 쪼개 보낼 수 있게 해줌으로써 이 딜레마에 대한 해법을 제공한다.
다음은 청크 분할 응답 이다.
```
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
7\r\n
Mozilla\r\n
9\r\n
Developer\r\n
7\r\n
Network\r\n
0\r\n
\r\n
```
참고 : https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Transfer-Encoding
- **청크 인코딩된 메시지의 트레일러**
다음 중 하나 이상의 조건을 만족하면 청크 메시지에 트레일러를 추가할 수 있다.

- 클라이언트의 TE 헤더가 트레일러를 받아들일 수 있음
- 트레일러가 응답을 만든 서버에 의해 추가됐고, 그 트레일러의 콘텐츠는 클라이언트가 이해하고 사용할
필요가 없는 선택적 메타데이터일 경우

트레일러로 보낼 수 있는 헤더의 예로는 Content-MD5 헤더가 있다.
Transfer-Encoding, Trailer, Content-Length를 제외한 어떤 HTTP 헤더도 트레일러로 보낼 수 있다.

### 15.6.4 콘텐츠와 전송 인코딩의 조합

콘텐츠 인코딩과 전송 인코딩은 동시에 사용될 수 있다.

### 15.6.5 전송 인코딩 규칙

전송 인코딩이 메시지 본문에 적용될 때, 몇 가지 규칙이 적용되어야 한다.

- 전송 인코딩의 집합은 반드시 'chunked'를 포함
- 청크 전송 인코딩이 사용되었다면, 메시지 본문에 적용된 마지막 전송 인코딩이 존재해야함
- 청크 전송 인코딩은 반드시 본문에 한 번 이상 적용되어야 함

## 15.7 시간에 따라 바뀌는 인스턴스

웹 객체는 정적이지 않다. 같은 URL은 시간에 따라 다른 버전의 객체를 가리킬 수 있다.

HTTP 프로토콜은 어떤 특정한 종류의 요청이나 응답을 다루는 방법들을 정의하는데,
이것은 **인스턴스 조작(instance manipluation)** 이라 불리며 객체의 인스턴스에 작용한다.

대표적인 두 방법이 `범위 요청`과 `델타 인코딩`이다.

## 15.8 검사기와 신선도

### 15.8.1 신선도

서버는 Expires나 Cache-Control 헤더를 통해 클라이언트에게 캐시의 신선도 판단 정보를 제공한다.

Expires의 경우 시계가 반드시 동기화 되어있을 때만 정확한 결과를 기대할 수 있다.
그러나, 항상 쉽지는 않다. 따라서 절대적인 시간보다는 상대시간을 이요해 만료를 정의하는
메커니즘이 더 쓸만하다.

**Cache-Control 헤더**는 문서의 최대 수명을 문서가 **서버를 떠난 후로부터의 총 시간을 초 단위**로 정한다.

수명은 시계 동기화에 의존하지 않으므로 더 정확한 결과를 말해줄 수 있다.

> 💡 Cache-Control 헤더 지시자 종류는 책 p.416 참고

### 15.8.2 조건부 요청과 검사기

HTTP는 클라이언트에게 **리소스가 바뀐 경우에만 사본을 요청**하는 **조건부 요청 방법**을 제공한다.
평범함 HTTP 요청이지만, 특정 조건이 참일 때에만 수행된다.

조건부 요청은 `'If-'`로 시작하는 조건부 헤더에 의해 구현된다.

각 조건부 요청은 특정 검사기 위에서 동작한다.
검사기는 문서의 테스트된 특정 속성이다. 개념적으로, 일련변호나 버전 번호 혹은 무서의 최종 변경일과
같은 검사기이다.

If-Modified-Since 헤더는 문서 인스턴스의 마지막 수정된 날짜를 검사하므로,
마지막 수정 날짜를 검사기라고 말할 수 있다.

다음은 각 조건부 헤더와 그 유형에 사용되는 검사기이다.

| 요청 유형 | 검사기 | 설명 |
| :------------------ | :------------ | :------------------------------------------------------------------------------------------------------------------------------------ |
| If-Modified-Since | Last-Modified | 지난 Last-modified 응답 헤더에 들어있었던 시각에 마지막으로 수정된<br>버전이 더 이상 최신 버전이 아니라면, 그 리소스의 사본을 보내라. |
| If-Unmodified-Since | Last-Modified | 지난 Last-modified 응답 헤더에 들어있었던 시각에 마지막으로 수정된<br>버전에서 변한 것이 없다면, 그 리소스의 사본을 보내라. |
| If-Match | ETag | 지난 ETag 응답 헤더에 들어있던 것과 엔터티 태그가 같다면, 그 리소스의 사본을 보내라. |
| If-None-Match | ETag | 지난 ETag 응답 헤더에 들어있던 것과 엔터티 태그가 다르다면, 그 리소스의 사본을 보내라. |

검사기는 약한 검사기와 강한 검사기 두 가지로 분류된다.

- 약한 검사기
- 리소스의 인스턴스를 고유하게 식별하지 못하는 경우가 있음
- 객체의 바이트 단위의 크기는 콘텐츠 크기가 같더라도 내용이 다를 수 있다.
- 강한 검사기
- 언제나 고유하게 식별한다.
- 리소스의 콘텐츠에 대한 암호 체크섬(MD5같은)

```
GET /announce.html HTTP/1.1
If-None-Match: W/"v4.0"
```

위의 예는 클라이언트가 약한 엔터티 태그를 사용해서 서버와 재검사 한다.
서버는 콘텐츠가 문서 버전 4.0 이후로 의미있는 변경이 있었을 때만 본문을 반환한다.

## 15.9 범위 요청

다운로드를 받다가 네트워크의 문제로 실패했을 경우, 범위 요청을 이용하여 특정 범위 이후부터
데이터 요청을 할 수 있다.

```
GET /bigfile.html HTTP/1.1
Host: www.joes-hardware.com
Range: bytes=4000-
```

클라이언트는 처음 4000 바이트 이후의 부분을 요청하는 예 이다.

모든 서버가 범위 요청을 받아들일 수 있는 것은 아니지만 대부분의 많은 경우 가능하다.
응답에 **Accept-Ragne** 헤더를 포함시키는 방법으로 알려줄 수 있다.

```
HTTP/1.1. 200 OK
Date: Sun, 17 Jan 2021 20:00 GMT
Server: Apache/1.2.4
Accept-Ranges: bytes
```

## 15.10 델타 인코딩

> 객체 전체가 아닌 변경된 부분에 대해서만 통신하여 전송량을 최적화하는, HTTP 프로토콜의 확장

아래는 델타 인코딩의 문서 요청, 생성, 적용에 대한 메커니즘이다.

1. 클라이언트는 서버에게 페이지를 요청한다.
```
GET /bigfile.html HTTP/1.1
Date: Sun, 17 Jan 2021 20:15:00 GMT
```
2. 서버는 요청에 대한 응답 메시지를 보낸다.
```
HTTP/1.1 200 OK
Content-type: text/html
Expires: Sur, 17 Jan 2021 21:00:00 GMT
ETag: abcdefghijk
...
```
3. 응답을 받아서 캐시 후, 다음날 같은 페이지로 접근을 했지만 캐시된 사본이 만료되어 서버에게 재요청한다.
이미 캐시된 사본이 있으므로 델타를 받아들이겠다는 의사를 밝히는 `델타 요청 메시지`를 보낸다.
- If-None-Match에 식별자인 ETag값
- A-IM 헤더 -> 인스턴스 조작의 종류 명시, 델타 알고리즘 정보
```
GET /bigfile.html HTTP/1.1
If-None-Match: abcdefghijk
A-IM: diffe
Date: Mon, 18 Jan 2021 09:15:00 GMT
```
4. 서버는 델타 응답 메시지를 보내준다.
- 특별한 응답 코드(226 IM Used)
- 델타 알고리즘 IM 헤더
- 새 ETag 헤더
- 델타를 계산한 기반 문서의 ETag값인 Delta-Base 헤더
```
HTTP/1.1 226 IM Used
IM: diffe
ETag: hijklmnop
Delta-base: abcdefghijk
...
```
5. 클라이언트는 델타 메시지를 받고 페이지의 캐시된 버전에 적용하여 최신 버전을 생성한다.

### 15.10.1 인스턴스 조작, 델타 생성기 그리고 델타 적용기

- 클라이언트는 A-IM 헤더를 사용해서 자신이 받아들일 수 있는 인스턴스 조작의 종류를 명시
- 서버는 IM 헤더에 사용한 인스턴스 조작의 종류를 명시

다음의 표는 IANA에 등록된 인스턴스 조작의 종류를 몇 가지 나열한다.

| 종류 | 설명 |
| :------- | :----------------------------------------------------------------------------------------------------------------- |
| vcdiff | vcdiff 알고리즘을 이용한 델타 |
| diffe | 유닉스 diff -e 명령을 이용한 델타 |
| gdiff | gdiff 알고리즘을 이용한 델타 |
| gzip | gzip 알고리즘을 이용한 압축 |
| deflate | deflate 알고리즘을 이용한 압축 |
| range | 현재 응답이 범위 선택에 대한 결과인 부분 콘텐츠 임을 말해주기 위해 서버 응답에서 사용 |
| identity | 클라이언트가 identity 인스턴스 조작을 받아들일 의사가 있음을 말해주기 위해 클라이언트 요청의<br>A-IM 헤더에서 사용 |