HTTP 완벽가이드 13장

13장 다이제스트 인증

목표: 기본 인증과 호환되는 더 안전한 대체재로서의 다이제스트 인증을 알아본다.

1. 다이제스트 인증의 개선점

특징

  • 비밀번호를 절대로 네트워크를 통해 평문으로 전송하지 않는다.
  • 인증 체결을 가로채서 재현하려는 악의적인 사람들을 처단한다.
  • 구현하기에 따라서, 메시지 내용 위조를 막는것이 가능하다.
  • 그 외의 잘 알려진 형태의 공격을 막는다.

1.1 비밀번호를 안전하게 지키기 위해 요약 사용하기

  • 다이제스트 인증을 요약하면 “절대로 비밀번호를 네트워크를 통해 보내지 않는다” 이다.
  • 클라이언트는 비밀번호를 비가역적으로 뒤섞은 지문(fingerprint) 혹은 요약(digest)를 보낸다.

1.2 단방향 요약

  • 요약은 ‘정보 본문의 압축’이다.
  • 요약은 단방향 함수로 동작하고, 무한 가지의 모든 입력 값들을 유한한 범위의 압축으로 변환한다.
  • 만약 비밀번호를 모른다면 서버에게 보내줄 알맞은 요약을 추측하기 위해 많은 시간을 소모하게 된다.
  • 요약은 비밀번호를 그대로 전송해야 할 필요성에서 해방시켜준다.

1.3 재전송 방지를 위한 난스(nonce) 사용

  • 요약은 비밀번호 자체와 다름 없으므로 요약을 가로챈다면 요약을 서버로 재전송할 수 있다.
  • 재전송을 막기 위해서 서버는 클라이언트에게 난스라고 불리는 특별한 증표를 넘겨준다.
  • 난스는 약 1밀리초마다, 인증할때마다 바뀌게 된다.

1.4 다이제스트 인증 핸드 셰이크

  1. 서버는 난스 값을 계산한다.
  2. 서버는 난스를 WWW-Authenticate 인증요구 메시지에 담아, 알고리즘 목록과 함께 클라이언트에 보낸다.
  3. 클라이언트는 알고리즘을 선택하고 비밀번호와 그 외 데이터에 대한 요약을 계산한다.
  4. 클라이언트는 Authorization 메시지에 요약을 담아 서버에게 돌려준다.
  5. 서버는 요약, 선택한 알고리즘, 그 외 보조 데이터들을 받고, 클라이언트가 했던 그대로 요약을 계산한다. 서버는 자신이 계산한 요약과 네트워크로 전송되어 온 요약이 서로 같은지 확인한다.

2. 보호 수준(Quality of Protection) 향상

  • qop 필드는 클라이언트와 서버가 어떤 보호 기법을 어느 정도 수준으로 사용할 것인지 협상할 수 있게 해준다.

2.1 메시지 무결성 보호

  • 무결성 보호가 적용되었을 때 계산되는 엔터티 본문은, 메시지 본문의 해시가 아닌 엔터티 본문의 해시이다.
  • 송신자에 의해 어떠한 전송 인코딩이 적용되기도 전에 먼저 계산되고 그 후 수신자에 의해 제거된다.

2.2 다이제스트 인증 헤더

  • 기본, 다이제스트 인증은 WWW-Authentication 헤더에 담겨 전달되는 인증요구와, Authentication 헤더에 담겨 전달되는 인기 응답을 포함한다.
  • 다이제스트는 Authentication-Info 헤더를 추가했다.
  • 3단계 핸드셰이크를 완성하고 다음번 사용할 난스를 전달하기 위해 인증 성공 후에 전송된다.
  • 3. 다이제스트 인증 작업시 고려할것들

3.1 다중 인증요구

  • 서버는 한 리소스에 대해 여러 인증을 요구할 수 있다.
  • 다양한 인증 옵션을 제공하는 경우, ‘가장 허약한 부분‘에 대한 보안우려가 있다는 것이 명확하다.

3.2 오류처리

  • 지시자나 그 값이 적절하지 않거나 요구된 지시자가 빠져 있으면, 응답은 400 Bad Request이다.
  • 인증 서버는 uri 지시자가 가리키는 리소스가 요청줄에 명시된 리소스와 같음을 확인해야 한다.
  • 반복된 실패에 대해서는 따로 기록해 두는 것이 좋다.

3.3 보호 공간(Protection Space)

  • 영역 값은 접근한 서버의 루트 URL과 결합되어 보호 공간을 정의한다.
  • 영역 값은 원 서버에 의해 할당되는 문자열이며 인증 제도에 추가적인 의미를 더한다.
  • 보호 공간은 어떤 자격이 자동으로 적용되는 영역을 정한다.

3.4 URI 다시 쓰기

  • 프락시는 가리키는 리소스의 변경 없이 구문만 고쳐서 URI를 다시 쓰기도 한다.
    • 호스트 명은 정규화되거나 IP 주소로 대체된다.
    • 문자들은 % escape 형식으로 대체될 수 있다.
    • 서버로부터 가져오는 리소스에 영향을 주지 않는, 타입에 대한 추가 속성이 URI의 끝에 붙거나 중간에 삽입될 수 있다.

3.5 캐시

Authorization 헤더를 포함한 요청과 그에 대한 응답을 받은 경우, 두 Cache-Control 지시자 중 하나가 응답에 존재하지 않는 한 다른 요청에 대해 응답을 반환해서는 안된다.

4. 보안에 대한 고려사항

4.1 헤더 부당 변경

헤더 부당 변경에 대해 안전한 시스템을 제공하기 위해서, 양 종단 암호화헤더에 대한 디지털 서명이 필요하다.

4.2 재전송 공격

  • 폼 데이터를 전송할 때 이전에 사용했던 자격을 재사용해도 문제없이 동작한다면, 큰 문제가 생기게 된다.
  • 재전송 공격을 완전히 피하기 위해서는 매 트랜잭션마다 유일한 난스 값을 사용하는 것이다.
  • 서버는 매 트랜잭션마다 난스와 함께 타임아웃 값을 발급한다.

4.3 다중 인증 메커니즘

  • 클라이언트에게 항상 가장 강력한 인증제도를 선택하도록 한다.
  • 가장 강력한 인증 제도만을 유지하는 프락시 서버를 사용한다.

4.4 사전 공격

  • 전형적인 비밀번호 추측 공격이다.
  • 비밀번호 만료 정책이 없고, 충분한 시간이 있고, 비밀번호를 크래킹할 비용을 치를 수 있다면, 비밀번호를 쉽게 수집할 수 있다.
  • 크래킹하기 어렵도록 복잡한 비밀번호를 사용하고 괜찮은 비밀번호 만료 정책을 사용하는 것이 좋다.

4.5 악의적인 프락시와 중간자 공격

  • 프락시중 하나가 악의적이거나 보안이 허술하다면 클라이언트는 중간자 공격에 취약한 상태가 될 수 있다.
  • 프락시는 보통 정교한 프로그래밍 인터페이스를 제공하므로 그러한 프락시들을 이용하는 플러그인을 이용하여 트래픽을 가로채 수정하는 것이 가능하다.
  • 이 문제를 해결하기에는 한계가 있으므로, 클라이언트가 가능한 가장 강력한 인증을 선택하도록 설정한다.

4.6 선택 평문 공격

  • 보안이 허술하거나 악의적인 프락시가 트래픽 중간에 끼어든다면, 클라이언트가 응답 계산을 하기 위한 난스를 제공 할 수 있다.
  • 응답을 계산하기 위해 알려진 키를 사용하는 것은 응답의 암호 해독을 쉽게 한다.
  • 클라이언트가 서버에서 제공된 난스 대신 선택적인 c난스 지시자를 사용하여 응답을 생성할 수 있도록 설정하는 것이 좋다.

4.7 비밀번호 저장

  • 다이제스트 인증 비밀번호 파일이 유출되면 영역의 모든 문서는 공격자에게 노출된다.
  • 비밀번호 파일이 평문으로 된 비밀번호를 포함하고 있다고 생각하고 안전하게 보호한다.
  • 영역 이름이 유일함을 보장한다.

HTTP 완벽가이드 12장

12장 기본인증

목표 : HTTP 인증과 그것의 기본이 되는 기본 인증을 알아본다.

1. 인증

1.1 HTTP의 인증요구/응답 프레임워크

1.2 인증 프로토콜과 헤더

  • HTTP에는 기본 인증과 다이제트스트 인증이 존재한다.
단계 헤더 설명 메서드/상태
요청 첫 번째 요청에는 인증 정보가 없다 GET
인증요구 WWW-Authenticate GET 서버는 사용자에게 사용자 이름과 비밀번호를 제공하라는 의미로 401 상태 정보와 함께 요청을 반려한다. 401 Unauthorized
인증 Authorization 클라이언트는 인증 알고리즘과 사용자 이름,비밀번호를 기술한 Authorization 헤더를 보낸다. GET
성공 Authentication-Info 인증 정보가 정확하면, 서버는 문서와 함께 응답한다. 200 OK

2. 기본 인증

  • 기본 인증은 HTTP/1.0에 기술되어 있었지만, RFC 2617로 옮겨졌다.

2.1 기본 인증의 예

  1. 사용자가 리소스를 요청한다.
  2. 서버가 WWW-Authenticate 헤더와 함께 리소스를 접근하는데 필요한 비밀번호를 요구하는 401 Authorization Required 응답을 반환한다.
  3. 브라우저에서 401 응답을 받고 사용자 이름과 비밀번호를 입력하는 화면을 띄운다. 브라우저는 정보들을 콜론으로 이어 붙이고, base-64방식으로 인코딩하고, Authorization 헤더에 그 값을 담아 서버로 다시 보낸다.
  4. 서버는 사용자 이름과 비밀번호를 디코딩하고, 그 값이 정확한지 확인하고, 문제 없으면 HTTP 200 OK 메시지와 함께 요청받았던 문서를 보낸다.

2.2 Base-64 사용자 이름/비밀번호 인코딩

  • HTTP 기본 인증은 사용자 이름과 비밀번호를 클론으로 이어서 합치고, base-64인 코딩 메서드를 사용해 인코딩 한다.
  • base-64 인코딩은 8비트 바이트로 이루어져 있는 시퀀스를 6비트 덩어리의 시퀀스로 변환한다.
  • base-64 인코딩은 국제 문제나 HTTP 헤더에서 사용할 수 없는 문자를 보내야 할 때 유용하다.

2.3 프락시 인증

  • 중개 프락시 서버를 통해 인증 할 수 있다.
  • 프락시 서버에서 접근 정책을 중앙 관리 할 수 있기 때문에, 회사 리소스 전체에 대해 통합적인 접근 제어를 하기 위해서 프락시 서버를 사용하면 좋다.

3. 기본 인증의 보안 결함

  • 기본 인증은 사용자 이름과 비밀번호를 쉽게 디코딩 할 수 있는 형식이므로 노출되어서는 안된다.
  • 메시지의 인증 헤더를 건드리지 않고, 그 외 다른 부분을 수정해서 트랜잭션의 본래 의도를 바꿔버리는 프락시나 중개자가 중간에 개입하는 경우, 기본 인증은 정상적인 동작을 보장하지 않는다.

코드스피츠85 2회

왜 프론트엔드 개발자를 무시할까?

  • 잘 모르기 때문에..
  • 프로그래밍 모델, 컴퓨터 내부, 컴퓨터 사이언스 내용에 대한 부족
  • 바깥에 표현하는거에 관심
  • 중급 이상이 넘어가면 얘기가 안통한다고 생각하게 됨

Parallelism 병렬성

  • 병렬성이 동시성을 이해하는 것보다 쉽다.
  • Worker가 동시에 투입되고 일을 동시에 처리할 수 있다.
  • 프론트엔드에서는 네트워크에 무언가 요청을 하면 네트워크 서버가 돌고 클라이언트에서 돌고있다.
  • Task에 할당되는 worker가 별도로 존재해서 자기만의 속도와 스케줄로 일을 처리한다.
  • 각각의 Task가 하나의 메모리를 동시에 같이 사용하면 문제가 생긴다.
  • 하나의 Task가 메모리를 사용하고 있으면 나머지 Task를 Blocking을 하는 방법을 사용
  • 자바스크립트는 병행성이 막혀있다(es2018 이전까지)
  • 함수형은 프로그래밍은 공유를 하지말고 특정 메모리만 쓰도록 한다
  • 객체지향 프로그래밍은 공유하는 메모리를 인정할 수 밖에 없다 → 객체 식별을 새로 만들어진 값으로 하는게 아니라 포인터 참조로 되기 때문에 각각의 Task들이 하나의 메모리를 참조 할 수 있다

Concurrency 동시성

  • 엄밀히 말하면 동시에 일어나지 않음
  • 마치 동시에 일어나는 것처럼 보이는거임
  • 메모리를 동시에 쓰는 경우가 없다
  • 자바스크립트에서는 병행성이 없고 동시성만 있다
  • 동시성과 병행성의 가장 큰 차이는 Worker가 몇명인지이다.

실제 세계의 Concurrency

  • 한번에 하나만 하긴 하더라도 굉장히 복잡하게 많은 일을 한다

자바스크립트 Concurrency

engine work

  • 브라우저는 렌더링을 포함한 수많은 엔진들이 하는 일들을 한다. (통신 준비, favicon 요청, console 초기화, 메모리 initialize 등등) → 멀티스레드로 수행한다.
  • 자바스크립트 코드가 영향을받는 메모리 블럭을 수행할 때는 하나의 스레드를 사용한다.
  • 자바스크립트 메모리에 영향을 주지않는다면 여러개의 스레드를 사용한다
  • queue에 걸리는게 없다면 engine work가 할일을 계속 수행한다
  • queue에 실행할 일이 생기면 run JS 실행한다
  • 실행이 끝나면 다시 engine work 수행한다.

check queue

  • 자바스크립트 명령을 적재해 둔게 있는지 없는지 검사한다.
  • callback queue를 바라본다.

callback queue

  • 브라우저 로딩에 들어가는 스크립트 callback queue
  • 이벤트 리스너 callback queue

생산자 & 소비자 ⇒ 멀티 스레드 패턴

  • 소비자가 하나의 스레드 메모리에서 읽기만 한다.
  • 소비자가 하나만 두는 것을 파이프 패턴이라 한다.
  • network, timer, message, dom event는 멀티스레드로 돌리더라도 synchronize 문제가 생기지 않는다.

  • callback queue를 중심으로 동시성과 병행성이 나뉜다.
  • 병행성에서는 생산만, 동시성에서는 소비만 하는 패턴

setTimer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
const Item = class{
time;
block;
constructor(block, time) {
this.block= block;
this.time = time + performance.now();
}
const queue = new Set;

const f = time=> {
queue.forEach(item=>{
if(item.time > time) return;
queue.delete(item);
item.block();
});
requestAnimationFrame(f);
}
requestAnimationFrame(f);

const timeout = (block, time) => queue.add(new Item(block, time));
```

- 함수는 어떻게 1초후에 일어나는걸까?
- 밀리세컨마다 1초지났는지 계속 확인하다가 1초지났을때 실행한다
- 푸쉬형을 선호한다 이벤트 기반의 프로그램을 짠다
- 원하는 사건에 내 코드가 호출되었으면 좋겠다
- 클릭할때 리스너가 뜨길 원한다(어떻게 동작하는지는 관여하고 싶ㅍ지 않다)
- 브라우저는 개발자를 바보로 만든다...ㅠㅠ
- 컴퓨터 사이언스로 보면 우리는 부탁만하는거다;
- `performance.now()` 브라우저가 시작되고 몇초가 지났는지(나노초 가능)

value 값

- 불변
- 메모리 자체가 아닌 그 자체로 판단

배열은 여러개일수도 있고 똑같은 값을 넣을수도있다

Set은 중복된 객체를 넣지 않기 위함

객체 지향에서 객체에대한 collection은 배열이 아니라 Set이다

## Non Blocking For

const working = _ => {};
for(let i=0; i< 100000; i++) working();

const nbFor = (max, load, block) => {
let i = 0;
const f = time => {
let i = 0;
const f = time => {
let curr =load;
while(curr-- && i < max) {
block();
i++;
}
console.log(i);
if(i<max-1) requestAnimationFrame(i);
};
requestAnimationFrame(i);
}
}

nbFor(100, 10, working);
-> 10씩 끊어서 분산해서 처리한다

const nbFor = (max, load, block) => {
let i = 0;
const f = time => {
let i = 0;
const f = time => {
let curr =load;
while(curr-- && i < max) {
block();
i++;
}
console.log(i);
if(i<max-1) timeout(f, 0);
};
timeout(f, 0);
}
}

## Generator

자바스크립트에서 인터페이스는 특정키나 값이 들어있는 형태를 지칭한다 ⇒ 오브젝트의 형태

루프의 주인공은 이터레이터다

이터레이터에게 넥스트 함수를 호출하면 오브젝트를 리턴한다

value, done이라는 키를 가진 오브젝트를 리턴

const infinity = (function*() {
let i= 0;
while(true) yield i++;
})();
console.log(infinity.next());

generator를 호출하면 iterator 객체가 나온다

generator 자체로는 for..of를 사용 못함

infinity 만들자마 즉시 호출이므로 iterator 객체이다

function* 는 서스펜드 구간을 생성한다

동기명령은 멈출수 없지만 generator는 멈출수 있다

메모리 적재시에 명령마다 레코드라는것으로 감싸서 적재해두었고 하나를 실행할때마다 레코드를 풀어서 실행 → 서스펜드

yield 호출시에 서스펜드(멈춤)

resume(다시 시작)

명령어를 중간에 끊을수 있기 때문에 무한 크기의 배열을 만들수 있다

const gene = function*(max, load, block) => {
let i = 0, curr = load;
while(i<max){
if(curr--){
block();
i++;
}else{
curr=load;
console.log(i);
yield;
}
}

const nbFor = (max, load, block)=>{
const iterator = gene(max, load, block);
const f=_=>iterator.next().done||timeout(f);
timeout(f,0);
};

지역변수를 사용한다

제어구조를 외부에서 통제하도록 되어있다

## Promise

const gene2 = function*(max, load, block) => {
let i = 0;
while(i < max){
yield new Promise(res => {
let curr = load;
while(curr– && i<max){
block();
i++;
}
console.log(i);
timeout(res, 0);
});
}
};
const nbFor = (max, load, block)=>{
const iterator = gene(max, load, block);
const next = ({value, done})=> done || value.then(v=>next(iiterator.next()));
next(iterator.next());
};

```
callback 스타일은 제어권을 잃는다

우리가 원하는 시간에 callback이 오면 좋겠다

서버 응답은 우리가 원하는데로 오지 않는다

제어권을 통제하기 위해서는 프로미스 객체를 가지고 있다가 내가 원할때 then을 호출 →반제어권

promise와 callback의 차이 → 내가 원할때 then을 호출할 수 있다

promise.then으로 쓰면 callback과 똑같다

generator와 promise를 섞어서 사용하면 외부제어에 일부를 개입할 수 있는 제어 역전을 결정할 수 잇따

HTTP 완벽가이드 11장

11장 클라이언트 식별과 쿠키

목표

서버가 통신하는 대상을 식별하는 데 사용하는 기술을 알아본다

1. 개별접촉

웹 서버는 요청을 보낸 사용자를 식별하거나 방문자가 보낸 연속적인 요청을 추적하기 위해 약간의 정보를 이용한다. 현대의 웹사이트 들은 개인화된 서비스를 제공하기 위해 여러가지 방식을 사용한다.

개별 인사

사용자에게 특화된 환영 메시지나 페이지 내용을 만든다

사용자 추천

고객의 흥미가 무엇인지 파악하고 고객에게 맞춤으로 제품을 추천한다

저장된 사용자 정보

온라인 쇼핑 고객은 주소와 신용카드 정보를 매번 입력하는 것을 싫어한다

온라인 쇼핑이 고객을 식별하고 나면 쇼핑을 더 편리하게 하도록 사용자 정보를 사용한다

세션 추적

HTTP 트랜잭션은 상태가 없어서 각 요청 및 응답은 독립적으로 일어난다

많은 웹사이트에서 사용자가 사이트와 상호작용 할 수 있게 남긴 사용자 정보를 유지하기 위한 HTTP 트랜잭션을 식별할 방법이 필요하다

2. HTTP 헤더

가장 일반적인 HTTP 요청 헤더 기술

  • From: 사용자의 이메일 주소
  • User-Agent: 사용자의 브라우저
  • Referer: 사용자가 현재 링크를 타고 온 근원 페이지
  • Authorization: 사용자 이름과 비밀번호
  • Client-ip: 클라이언트의 IP주소
  • X-Forwarded-For: 클라이언트의 IP주소
  • Cookie: 서버가 생성한 ID 라벨

3. 클라이언트 IP 주소

초기에는 사용자 식별에 클라이언트의 IP 주소를 사용하려고 하였다

확실한 IP 주소를 가지고 있고, 그 주소가 절대 바뀌지 않고, 웹 서버가 요청마다 클라이언트의 IP를 알 수 있다면, 문제가 되지 않는다

클라이언트 IP로 사용자를 식별한다면 많은 단점을 가지게 된다

  • 만약 여러 사용자가 같은 컴퓨터를 사용한다면 그들을 식별할 수 없다
  • 인터넷 서비스 제공자(ISP)는 사용자가 로그인하면 동적으로 IP 주소를 할당하기 때문에, 사용자는 매번 다른 주소를 받아, 웹 서버는 사용자를 IP 주소로 식별 할 수 없다
  • 사용자들은 인터넷 사용시에 네트워크 주소 변환(Network Address Translation) 방화벽을 사용하는데, 방화벽은 사용자의 실제 IP를 숨기고 방화벽 IP 주소로 변환하므로 식별이 어렵다
  • HTTP 프락시와 게이트웨이는 원 서버에 새로운 TCP 연결을 한다. 웹 서버는 클라이언트의 IP 주소 대신 프락시 서버의 IP 주소를 본다

4. 사용자 로그인

웹 서버는 사용자 이름과 비밀번호로 인증할 것을 요구해서 명시적으로 식별 요청할 수 있다

HTTP는 WWW-AuthenticateAuthorization 헤더를 사용해 웹 사이트에 사용자 이름을 전달하는 자체적인 체계를 가지고 있다.

1) 서버에서, 사용자가 사이트에 접근하기 전에 로그인을 시키고자 한다면 HTTP 401 ?Login Required 응답 코드를 브라우저에 보낼 수 있다.

2) 브라우저는 로그인 화면을 보여주고, 다음 요청부터 Authorization 헤더에 정보를 기술하여 보낸다.

5. 뚱뚱한 URL

웹 사이트는 사용자의 URL마다 버전을 기술하여 사용자를 식별하고 추적하기도 한다.

웹 서버는 URL에 있는 상태 정보를 유지하는 하이퍼링크를 동적으로 생성한다.

뚱뚱한 URL은 사이트를 브라우징 하는 사용자를 식별하는데 사용할 수 있지만, 여러 문제들을 가지고 있다.

  • 브라우저 보이는 URL이 새로운 사용자들에게는 혼란을 준다.
  • URl은 특정 사용자와 세션에 대한 상태 정보를 포함하므로, 해당 주소를 공유하게 된다면 개인정보를 공유하게 되는 것이다.
  • URL로 만드는 것은 URL이 달라지기 때문에 기존 캐시에 접근할 수 없다는 것을 의미한다.
  • 뚱뚱한 URL에 해당하는 HTML 페이지를 다시 그려야한다.
  • 사용자가 특정 뚱뚱한 URL을 북마킹하지 않는 이상, 로그아웃하면 모든 정보를 잃는다.

6. 쿠키

사용자를 식별하고 세션을 유지하는 방식중에서 가장 널리 사용되는 방식이다.

쿠키는 매우 중요한 웹 기술이며, 새로운 HTTP 헤더를 정의한다.

6.1 쿠키의 타입

  • 세션 쿠키(session cookie)지속 쿠키(persistent cookie) 타입으로 나뉜다.
  • 세션 쿠키는 사용자가 브라우저를 닫으면 삭제된다.
  • 지속 쿠키는 디스크에 저장되어, 브라우저를 닫거나 컴퓨터를 재시작하더라도 남아있다.

6.2 쿠키는 어떻게 동작하는가

쿠키는 서버가 사용자에게 “안녕, 내 이름은…”라고 적어서 붙이는 스티커와 같다.

웹 서버는 사용자를 식별하기 위해 임의의 이름=값 형태로 쿠키에 할당한다.

할당된 리스트는 Set-Cookie 또는 Set-Cookie2 같은 HTTP 응답 헤더에 기술되어 사용자에게 전달한다.

6.3 쿠키 상자: 클라이언트 측 상태

쿠키는 브라우저가 서버 관련 정보를 저장하고, 사용자가 해당 서버에 접근할 때마다 그 정보를 함께 전송하는 것이다.

브라우저는 쿠키 정보를 저장할 책임이 있는데, 이 시스템을 클라이언트 측 상태라고 한다.

6.4 사이트마다 각기 다른 쿠키들

브라우저는 쿠키 전부를 모든 사이에 보내지 않고, 보통 두세 개의 쿠키만을 보낸다. 이유는 다음과 같다.

  • 쿠키를 모두 전달하면 성능이 크게 저하된다.
  • 대부분 서버에 특화된 이름/값 쌍을 이루므로, 대부분 사이트에서는 인식하지 않는 무의미한 값이다.
  • 특정 사이트에서 제공한 정보를 신뢰하지 않는 사이트에 가지고 갈 수 있으므로 잠재적인 개인정보 문제를 일으킬 수 있다.

6.5 쿠키 구성요소

현재 사용되는 쿠키로 Version 0(넷스케이프 쿠키)Version 1(RFC 2965) 쿠키가 존재한다.

Version 0(넷스케이프 쿠키)

  • 최초의 쿠키 명세

    Set-Cookie: name=value [;expires=date] [;path=path] [;domain=domain] [;secure]
    Cookie: name1=value1 [;name2=value2]…

Version 1 (RFC 2965) 쿠키

  • 쿠키의 확장 버전으로 Version 0 시스템과도 호환된다.

  • 넷스케이프 버전보다 복잡하며, 아직 모든 브라우저나 서버가 완전히 지원하지 않는다.

    주요 변경사항

    • 쿠키마다 그 목적을 설명하는 설명문이 있다.
    • 쿠키의 생명주기를 결정할 수 있다(Max-Age)
    • URL의 포트번호로도 쿠키를 제어할 수 있다.
    • 브라우저가 닫히면 쿠키를 강제로 삭제할 수 있다.

6.6 쿠키와 세션 추적

쿠키는 웹 사이트에 수차례 트랜잭션을 만들어내는 사용자를 추적하는 데 사용한다.

Amazon.com 사이트에 방문하면 일어나는 트랜잭션의 연속을 알아본다.

  • a) 브라우저가 Amazon.com 페이지를 처음 요청한다.
  • b) 서버는 클라이언트를 전자상거래 소프트웨어 URL로 리다이렉트 시킨다.
  • c) 클라이언트는 리다이렉트 URL로 요청 보낸다.
  • d) 서버는 응답에 두 개의 세션 쿠키를 기술하고 사용자를 다른 URL로 리다이렉트 시키며, 클라이언트는 다시 이 쿠키들을 첨부하여 요청을 보낸다.
  • e) 클라이언트는 새로운 URL을 요청을 팡서 받은 두 개의 쿠키와 함께 보낸다.
  • f) 서버는 home.html 페이지로 리다이렉트 시키고 쿠키 두 개를 더 첨부한다.
  • g) 클라이언트는 home.html 페이지를 가져오고 총 네 개의 쿠키를 전달한다.
  • h) 서버는 콘텐츠를 보낸다.

6.7 쿠키와 캐싱

쿠키 트랜잭션과 관련된 문서를 캐싱하는 것은 주의해야 한다.

이전 사용자의 쿠키가 다른 사용자에게 할당되어 누군가의 개인정보가 유출될 수 있다.

캐시를 다루는 기본 원칙

캐시되지 말아야 할 문서가 있다면 표시하라

  • 문서가 Set-Cookie 헤더를 제외하고 캐시를 해도 될 경우라면 Cache-Control: no-cache="Set-Cookie" 를 명시적으로 기술한다.

Set-Cookie 헤더를 캐시하는 것에 유의하라

  • 같은 Set-Cookie 헤더를 여러 사용자에게 보내게 되면, 사용자 추적을 실패하게 된다.
  • 원 서버는 Cache-Control: must-revalidate, max-age=0 헤더를 캐시된 문서에 추가함으로써 재검사가 일어나게 할 수 있다.

Cooke 헤더를 가지고 있는 요청을 주의하라

  • 요청이 Cookie 헤더와 함께 오면, 결과 콘텐츠가 개인정보를 담고 있을 수도 있다는 힌트이다.
  • Set-Cookie가 있는 이미지에 대해서는 캐시를 하지만 Set-Cookie가 있는 텍스트는 캐시를 하지 않는 캐시도 있다.
  • 캐시 이미지에 파기 시간이 0인 Cookie 헤더를 설정해서 매번 재검사를 하도록 강제한다.

HTTP 완벽가이드 10장

10장 HTTP/2.0

1. HTTP/2.0의 등장 배경

HTTP/1.1의 특징

  • 메시지 포맷 단순성과 접근성에 중심을 두고 최적화 되었다.
  • 커넥션 하나를 통해서 요청&응답을 하므로 회전 지연(latency)을 피할수 없다.

2. 개요

  • HTTP/2.0은 서버와 클라이언트 사이의 TCP커넥션 위에서 동작한다.
  • 요청과 응답은 스트림을 통해 보내지며, 하나의 커넥션에 여러개의 스트림이 동시에 만들어질 수 있다.
  • 스트림에 대한 흐름 제어와 우선순위 부여 기능을 제공한다.
  • 서버는 클라이언트에게 필요하다고 생각하는 리소스라면 그에 대한 요청을 명시적으로 받지 않더라도 능동적으로 클라이언트게 보내줄 수 있다.

3. HTTP/1.1과의 차이점

3.1 프레임

  • HTTP/2.0에서 모든 메시지는 프레임에 담겨 전송된다.

  • R: 예약된 2비트 필드, 값의 의미가 정의되어 있지 않으며, 반드시 0이어 한다.

  • 길이: 페이로드의 길이를 나타내는 14비트 무부호 정수

  • 종류: 프레임의 종류

  • 플래그: 플래그 값의 의미는 프레임의 종류에 따라 다르다.

  • R: 예약된 1비트 필드, 값의 의미가 정의되어 있지 않으며, 반드시 0이어야 한다.

  • 스트림 식별자: 31비트 스트림 식별자, 커넥션 전체와 연관된 프레임을 의미한다.

3.2 스트림과 멀티플렉싱

  • HTTP/2.0 커넥션을 통해 클라이언트와 서버 사이에서 교환되는 프레임들의 독립된 양방향 시퀀스
  • 한쌍의 HTTP요청과 응답은 하나의 스트림을 통해 이루어진다.
  • 하나의 커넥션에 여러 개의 스트림이 동시에 열릴 수 있다.
  • 스트림은 우선순위 따라서 요청이 처리 될 수 있다.

3.3 헤더 압축

  • 과거에는 웹페이지 방문시에 요청이 많지 않았기 때문에 헤더의 크기가 큰 문제가 되지 않았으나, 최근에는 웹페이지 하나에 수십, 수백개의 요청이 이루어지므로 헤더의 크기가 회전 지연과 대역폭에 영향을 끼친다.
  • HTTP/2.0에서는 메시지의 헤더를 합축하여 전송한다.

3.4 서버 푸시

  • HTTP/2.0은 서버가 하나의 요청에 대한 응답으로 여러 개의 리소스를 보낼 수 있도록 해준다.
  • 서버가 클라이언트에게 어떤 리소스를 요구할 것인지 미리 알 수 있는 상황에서 유용하다.

HTTP 완벽가이드 9장

9장 웹 로봇

1. 크롤러와 크롤링

  • 웹 크롤러란? 웹페이지를 한 개 가져오고, 그 다음 그 페이지가 가리키는 모든 웹페이지를 가져오는 작업을 재귀적으로 반복하는 방식으로 웹을 순회하는 로봇이다.
  • 인터넷 검색엔진은 웹을 돌아다니면서 모든 문서를 끌어오기 위해 크롤러를 사용한다.
  • 사용자가 특정 단어로 검색을 할때, 가져와야 하는 페이지들이 수십억 개나 되므로, 검색엔진 로봇들은 가장 복잡한 로봇들중 하나가 되었다.

1.1 어디에서 시작하는가: ‘루트 집합’

  • 크롤러가 방문을 시작하는 URL들의 초기 집합을 루트 집합이라고 한다.
  • 모든 링크를 크롤링하면 관심있는 웹페이지들의 대부분을 가져오게 될 수 있도록 충분히 다른 장소에서 URL들을 선택해야 한다.
  • 일반적으로 좋은 루트 집합은 크고 인기 있는 웹 사이트, 새로 생성된 페이지들의 목록, 자주 링크되지 않는 잘 알려지 있지 않은 페이지들의 목록으로 구성된다.

1.2 링크 추출과 상대 링크 정상화

  • 크롤러는 검색한 각 페이지 안에서 크롤링할 URL 링크들을 추가한다.
  • HTML 파싱을 해서 링크들을 추출하고 상대 링크를 절대 링크로 바꿔야 하낟.

1.3 루프와 중복

  • 순환은 크롤러를 루프에 빠뜨려서 빙빙 돌게 만들거나, 같은 페이지를 반복해서 가져오는데 시간을 허비하도록 만들 수 있다.
  • 같은 페이지를 반복해서 가져오면, 웹 서버에 부담이 가고, 웹 사이트를 압박하여 실제 사용자도 사이트에 접근할 수 없도록 막아버리게 만들 수 도 있다.
  • 크롤러는 루프 자체가 문제가 되지 않더라도, 많은 중복된 페이지들을 가져오게 되므로, 애플리케이션이 중복된 컨텐츠로 넘쳐나게 만들수 있다.

1.5 빵 부스러기의 흔적

  • 전 세계 웹 콘텐츠들을 크롤링하기 위해서는 빠른 속도가 중요하다.
  • 웹 크롤러들은 방문한 곳을 관리하기 위해 사용하는 유용한 기법들이 있다.

트리와 해시 테이블

  • 복잡한 로봇들은 방문한 URL을 추적하기 위해 검색 트리나 해시 테이블을 사용한다.

느슨한 존재 비트맵

  • 공간 사용을 최소화하기 위해 존재 비트 배열과 같은 느슨한 자료구조를 사용한다.

체크포인트

  • 로봇 프로그램이 갑작스럽게 중단될 경우를 대비해, 방문한 URL의 목록이 디스크에 저장되었는지 확인한다.

파티셔닝

  • 각각이 분리된 한 대의 컴퓨터인 로봇들이 동시에 일하고 있는 농장(farm)을 이용한다.
  • 각 로봇엔 URL들의 특정 한 부분이 할당되어 그에 대한 책임을 갖는다.

2. 로봇의 HTTP

  • 로봇들은 HTTP 요청을 만들고 스스로를 클라이언트로서 적절한 HTTP 요청 헤더를 사용해야 한다.

2.1 요청 헤더 식별하기

  • 로봇 대부분은 약간의 신원 식별 헤더(능력, 신원, 출신)를 구현하고 전송한다.
  • 이 정보들은 크롤러의 소유자를 찾아낼 때와 서버에게 로봇이 어떤 종류의 콘텐츠를 다룰 수 있는지에 대한 약간의 정보를 주려 할 때 유용하다.

User-Agent

  • 서버에게 요청을 만든 로봇의 이름

From

  • 로봇의 사용자/관리자의 이메일 주소를 제공한다.

Accept

  • 서버에게 어떤 미디어 타입을 보내도 되는지 말해준다.

Referer

  • 현재의 요청 URL을 포함한 문서의 URL을 제공한다.

2.2 가상 호스팅

  • 로봇은 Host 헤더를 지원해야 한다.
  • 요청에 Host 헤더를 포함 하지 않으면 로봇이 어떤 URL에 대해 잘못된 콘텐츠를 찾게된다.

2.3 조건부 요청

  • 수십억 개의 웹페이지를 다운 받을 수 도 있으므로, 콘텐츠가 변경되었을때만 가져오도록 하는 것이 효과적이다.
  • 시간이나 엔터티 태그를 비교함으로써 그들이 받아간 마지막 버전 이후에 업데이트 된 것이 있는지 알아보는 조건부 HTTP요청을 구현한다.

2.4 응답 다루기

  • 로봇들은 주 관심사가 단순히 GET 메서드로 콘텐츠를 요청해서 가져오는 것이므로 응답다루기 를 거의 하지 않는다.
  • 로봇들은 최소한 일반적인 상태 코드나 예상할 수 있는 상태 코드를 다룰 수 있어야한다.
  • HTTP 헤더에 임베딩된 정보를 따라 로봇들은 엔터티 자체의 정보를 찾을 수 있다.
  • 메타 http-equiv 태그와 같은 메타 HTML 태그는 리소스에 대해 콘텐츠 저자가 포함시킨 정보다.

2.5 User-Agent 타기팅

  • 웹 사이트들은 그들의 여러 기능을 지원할 수 있도록 브라우저의 종류를 감지하여 그에 맞게 콘텐츠를 최적화한다.
  • 사이트는 로봇에게 콘텐츠 대신 에러 페이지를 제공한다.

3. 부적절하게 동작하는 로봇들

폭주하는 로봇

  • 로봇이 논리적인 에러를 갖고 있거나 순환에 빠졌다면 웹 서버에 극심한 부하를 안겨준다.
  • 서버에 과부하를 유발하여 다른 누구에게도 서비스를 못하게 만드는 일이 발생할 수 있다.

오래된 URL

  • 웹 사이트의 콘텐츠들이 많이 바뀌었다면, 로봇들은 존재하지 않은 URL에 대한 요청을 많이 보낼 수 있다.
  • 존재하지 않는 문서에 대한 접근 요청이나, 에러 페이지를 제공하는 부하로 인해 웹 서버의 수용 능력이 감소될 수 있다.

길고 잘못된 URL

  • 웹 사이트에게 크고 의미 없는 URL을 요청한다면, 웹 서버의 처리 능력에 영향을 주고, 접근 로그를 어지럽게 채우게 된다.

호기심이 지나친 로봇

  • 로봇들은 사적인 데이터에 대한 URL을 얻어 인터넷 검색엔진이나 기타 애플리케이션을 통해 쉽게 접근할 수 있도록 만들 수 있다.
  • 로봇들이 비밀번호 파일이나 신용카드 정보와 같이 민감한 데이터를 가져가는 것이 가능하다는 것을 사이트 구현자들이 인지해야 할 필요가 있다.

동적 게이트웨이 접근

  • 로봇은 게이트웨이의 콘텐츠에 대한 URL로 요청을 할 수 있다.
  • 보통 특수 목적을 위한 경우이므로 처리 비용이 많이 든다.

4. 로봇 차단하기

  • robots.txt 는 로봇의 접근을 제어하는 정보를 저장하는 파일의 이름이다.
  • 어떤 로봇이 서버의 어떤 부분에 접근할 수 있는지에 대한 정보가 담겨있다.
  • 웹 사이트의 어떤 리소스에 접근하기 전에 해당 사이트의 robots.txt를 요청하고, 해당 사이트의 웹 페이지를 가져올 수 잇는 권한이 있는지 확인하고 페이지를 가져온다.

4.1 웹 사이트와 robots.txt 파일들

  • 웹 사이트의 어떤 URL을 방문하기 전에, 해당 사이트에 robots.txt 파일이 존재한다면 로봇은 반드시 그 파일을 가져와서 처리해야 한다.

4.2 robots.txt 파일 포맷

User-Agent: Slurp
User-Agent: webcrawler
Disallow: /private

User-Agent: *
Disallow:
  • 각 레코드는 특정 로봇들의 집합에 대한 차단 규칙의 집합을 기술한다.
  • 각 레코드는 규칙 줄들의 집합으로 되어 있으며 빈 줄이나 파일 끝 문자로 끝난다.

User-Agent

  • 로봇의 이름은 로봇의 HTTP GET 요청 안의 User-Agent헤더를 통해 보내진다.
  • 로봇이 자신의 이름에 대응하는 User-Agent줄을 찾지 못하였고 와일드 카드를 사용한 User-Agent: * 줄도 찾지 못했다면, 대응하는 레코드가 없는것이므로, 접근에는 어떤 제한도 없다.

Disallow & Allow

  • User-Agent 줄 바로 다음에 온다.

  • 특정 로봇에 대해 어떤 URL 경로가 명시적으로 금지되어 있고 명시적으로 허용되는지 기술한다.

    5. 검색엔진

  • 웹 로봇은 인터넷 검색엔진에서 사용자들이 어떠한 문서라도 찾을 수 있도록 도와준다.

5.1 검색 과정

  • 검색엔진들은 전 세계의 웹페이지들에 대해 풀 텍스트 색인(full-text indexes) 라고 하는 로컬 데이터베이스를 생성한다.
  • 검색엔진 크롤러들은 웹페이지들을 수집하여 풀 텍스트 색인에 추가한다.
  • 크롤링을 한 번 하는데 걸리는 시간이 상당한 데 비해 웹페이지륻은 매 순간 변화하기 때문에, 풀 텍스트 색인은 웹의 특정 순간에 대한 스냅숏에 불과하다.
  • 풀 텍스트 색인은 단어 하나를 입력받아 그 단어를 포함하고 있는 문서를 즉각 알려줄 수 있는 데이터베이스이다.
  • 사용자가 질의를 보내고나면 게이트웨이 프로그램은 웹 UI질의를 풀 텍스트 색인을 검색할 때 ㅅ용되는 표현식으로 변환한다.
  • 질의의 결과를 확인하기 위해 검색엔진이 색인을 한번 사용했다면, 게이트웨이 애플리케이션은 그 결과를 이용해 최종 사용자를 위한 결과 페이지를 즉석에서 만들어낸다.

HTTP 완벽가이드 8장

8장 통합점: 게이트웨이, 터널, 릴레이

1. 게이트웨이

  • 복잡한 리소스들을 한 개의 어플리케이션으로만 처리할 수 없다는 문제를 해결하기 위해서 만들었다.
  • 리소스와 애플리케이션을 연결하는 역할을 한다.
  • 요청을 받고 응답을 보내는 포털 같이 동작하는데, 동적인 콘텐츠를 생성하거나 데이터베이스에 질의를 보낼 수 있다.
  • HTTP 트래픽을 다른 프로토콜로 자동으로 변환하여, HTTP 클라이언트가 다른 프로토콜을 알 필요 없이 서버에 접속할 수 있게 한다.

2. 프로토콜 게이트웨이

  • 게이트웨에서 HTTP 트래픽을 바로 보낼 수 있다.
  • 브라우저에 명시적으로 게이트웨이를 설정하여 자연스럽게 트래픽이 게이트웨이를 거쳐가게 하거나, 게이트웨이를 대리 서버(리버스 프락시)로 설정할 수 있다.

3. 리소스 게이트웨이

  • 일반적으로 애플리케이션 서버는 목적지 서버와 게이트웨이를 한 개의 서버로 결합한다.

3.1 공용 게이트웨이 인터페이스

  • 공용 게이트웨이 인터페이스(CGI)는 최초의 서버 확장이자 지금까지도 가장 널리 쓰이는 서버 확장이다.
  • CGI 애플리케이션이 서버와 분리되면서 다양한 언어로 구현되며, 거의 모든 HTTP서버가 지원한다.
  • CGI가 내부에서 어떤 처리를 하는지 사용자에게 보이지 않고, 내부적으로 일반적인 요청을 만든다.

3.2 서버 확장 API

  • 서버 개발자는 웹 개발자가 자신의 모듈을 HTTP와 직접 연결할 수 있는 강력한 인터페이스인 서버 확장 API를 제공한다.
  • 확장 API는 프로그래머가 자신의 코드를 서버에 연결하거나 서버의 컴포넌트를 자신이 만든 것으로 교체해버릴 수 있게 한다.

4. 애플리케이션 인터페이스와 웹 서비스

  • 애플리케이션을 연결하면서 데이터를 교환하려는 두 애플리케이션 사이에서 프로토콜 인터페이스를 맞추는 일이 가장 까다로운 이슈이다.
  • 웹 애플리케이션이 서로 통신하는데 사용할 표준과 프로토콜 집합을 개발하였다.
  • 웹 서비스는 SOAP를 통해 XML을 사용하여 정보를 교환한다.

5. 터널

  • HTTP 프로토콜을 지원하지 않는 애플리케이션에 HTTP 애플리케이션을 사용해 접근하는 방법을 제공한다.
  • HTTP 커넥션을 통해서 HTTP가 아닌 트래픽을 전송할 수 있고, 다른 프로토콜을 HTTP 위에 올릴 수 있다.
  • 주로 HTTP 커넥션 안에 HTTP가 아닌 트래픽을 얹기 위해서 사용한다.

5.1 CONNECT로 HTTP 터널 커넥션 맺기

  • 웹 터널은 HTTP의 CONNECT 메서드를 사용해 커넥션을 맺는다.
  • CONNECT 메서드는 터널 게이트웨이가 임의의 목적 서버와 포트에 TCP 커넥션을 맺고 클라이언트와 서버 간에 오는 데이터를 무조건 전달하기를 요청한다.

CONNECT 요청

  • 시작줄을 제외하고는 다른 HTTP 메서드와 같다.

  • 각 행은 CRLF로 끝나고, 헤더 목록의 끝은 빈 줄의 CRLF로 끝난다.

    CONNECT home.netscape.com:443 HTTP/1.0
    User-agent: Mozilla/4.0

CONNECT 응답

  • 클라이언트는 요청을 전송한 다음, 게이트웨이의 응답을 기다린다.

  • 커넥션이 메시지를 전달하는 대신 바이트를 그대로 전달하기 때문에 콘텐츠의 형식을 기술하는 Content-Type 헤더를 포함할 필요가 없다.

    HTTP/1.0 200 Connection Established
    Proxy-agent: Netscape-Proxy/1.1

5.2 데이터 터널링, 시간, 커넥션 관리

  • 터널을 통해 전달되는 데이터는 게이트웨이에서 볼 수 없어서, 게이트웨이는 패킷의 순서나 흐름에 대한 어떤 가정도 할 수 없다.
  • 게이트웨이는 커넥션이 맺어지는 대로 헤더를 포함해서 읽어들인 모든 데이터를 서버에 전송해야 한다.
  • 터널의 어느 부분이든 커넥션이 끊어지면, 그 곳으로부터 온 데이터는 반대편으로 전달되고, 그 다음 커넥션이 끊어졌던 터널의 끝단 반대편의 커넥션도 프락시에 의해서 끊어진다.

5.3 SSL 터널링

  • 웹 터널은 방화벽을 통해서 암호화된 SSL 트래픽을 전달하려고 개발되었다.
  • SSL 트래픽을 HTTP 커넥션으로 전송하여 80포트의 HTTP만을 허용하는 방화벽을 통과 시킨다.

5.4 SSL 터널링 vs HTTP/HTTPS 게이트웨이

  • HTTPS 프로토콜은 다른 프로토콜과 같은 방식으로 게이트웨이를 통과할 수 있다.
  • 게이트웨이가 FTP를 처리하는 방식과 같다.

단점

  • 클라이언트-게이트웨이 사이에는 보안이 적용되지 않은 일반 HTTP 커넥션이 맺어져 있다.
  • 프락시가 인증을 담당하고 있기 때문에, 클라이언트는 원격 서버에 SS?L 클라이언트 인증을 할 수 없다.
  • 게이트웨이는 SSL을 완벽히 지원해야 한다.

5.5 터널 보안에 대한 고려사항들

  • 터널 게이트웨으는 통신하고 있는 프로토콜이 터널을 올바른 용도로 사용하고 있는지 검증할 방법이 없다.
  • 터널의 오용을 최소화하기 위해서, 게이트웨이는 HTTPS 전용 포트인 443같이 잘 알려진 특정 포트만을 터널링할 수 있게 허용해야 한다.

6. 릴레이

  • HTTP 명세를 완전히 준수하지 않는 간단한 HTTP 프락시다.

  • 커넥션을 맺기 위한 HTTP 통신을 한 다음, 바이트를 전달한다.

  • 릴레이는 Connection 헤더를 제대로 처리하지 못해서 keep-alive 커넥션이 행(hang)에 걸리는 문제점이 생긴다.

  1. 웹 클라이언트는 Connection: Keep-Alive 헤더를 보내서, 릴레이에 커넥션을 맺기를 원한다는 내용의 요청 메시지를 전송한다.
  2. 릴레이가 HTTP 요청을 받지만, Connection 헤더를 이해하지 못하므로 요청을 서버로 넘긴다.
  3. 웹 서버가 프락시로부터 Connection: Keep-Alive헤더를 받으면, 릴레이가 keep-alive를 하기 바란다고 잘못된 결론을 내려버린다. 이 시점부터 웹 서버는 릴레이와 함께 keep-alive 통신을 하고, keep-alive의 규칙에 맞게 동작할 것이다.
  4. 릴레이는 웹 서버로부터 받은 Connection: Keep-Alive 헤더를 포함한 응답 메시지를 클라이언트에게 전달한다. 클라이언트와 서버는 keep-alive로 통신한다고 믿고 있지만, 실제로 통신하는 릴레이는 keep-alive가 무엇인지도 모른다.
  5. 원서버는 릴레이가 자신에게 커넥셔능ㄹ 계속 맺고 있기를 요청했다고 믿기 때문에 커넥션을 끊지 않을것이다. 따라서 릴레이는 커넥션이 끊길 때를 기다리며 계속 커넥션을 맺고(hang) 있을 것이다.
  6. 클라이언트가 응답 메시지를 받으면, 바로 다음 요청을 keep-alive 커넥션을 통해 릴레이에게 전송한다. 브라우저는 계속 돌고 있지만, 아무런 작업도 진행되지 않는다.

HTTP 완벽가이드 7장 part2

7장 캐시 part2

7.7 캐시처리 단계

단계 1: 요청받기

캐시는 네트워크로부터 들어오는 데이터를 읽어들인다.

단계 2: 파싱

캐시는 요청 메시지를 여러 부분으로 파싱하여 헤더 부분을 조작하기 쉬운 자료 구조에 담는다.

단계 3: 검색

캐시는 URL을 알아내고 그에 해당하는 로컬 사본이 있는지 검사한다.

만약 문서를 로컬에서 가져올 수 없다면, 캐시는 원 서버나 부모 프락시에서 가져오거나 혹은 실패를 반환한다.

캐시된 객체는 서버 응답 본문과 원 서버 응답 헤더를 포함하고 있으므로, 캐시 적중 동안 올바른 서버 헤더가 반환될 수 있다.

단계 4: 신선도 검사

HTTP는 캐시가 일정 기간 동안 서버 문서의 사본을 보유할 수 있도록 해준다.

이 기간 동안, 문서는 신선한 것으로 간주되고 서버를 통하지 않고 이 문서를 제공할 수 있다.

캐시된 사본을 신선도 한계를 넘을 정도로 오래 갖고 있었다면, 그 객체는 신선하지 않은 것으로 간주되며, 캐시는 그 문서를 제공하기 전에 문서에 어떤 변경이 있었는지 검사하기 위해 서버와 재검사를 해야 한다.

단계 5: 응답 생성

캐시는 캐시된 서버 응답 헤더를 토대로 응답 헤더를 생성한다.

캐시는 클라이언트에 맞게 이 헤더를 조정해야 하는 책임이 있다.

캐시는 캐시 신선도 정보(Cache-Control, Age, Expires 헤더)를 삽입하며, 요청이 프락시 캐시를 거쳐갔음을 알려주기 위해 종종 Via 헤더를 포함시킨다.

단계 6: 전송

캐시는 응답 헤더가 준비되면, 응답을 클라이언트에게 돌려준다.

단계 7: 로깅

대부분의 캐시는 로그 파일과 캐시 사용에 대한 통계를 유지한다.

각 캐시 트랜잭션이 완료된 후, 통계 캐시 적중과 부적중 횟수에 대한 통계를 갱신하고 로그 파일에 요청 종류, URL 그리고 무엇이 일어났는지를 알려주는 항목을 추가한다.

캐시 처리 플로 차트

7.8 사본을 신선하게 유지하기

캐시된 사본 모두가 서버의 문서와 항상 일치하는 것이 아니므로 캐시된 데이터는 서버의 데이터와 일치하도록 관리되어야 한다.

HTTP는 캐시된 사본이 서버와 일치하도록 문서 만료와 서버 재검사라는 단순한 메커니즘을 갖는다.

1. 문서 만료

HTTP는 Cache-ControlExpires라는 헤더들을 이용해서 원 서버가 각 문서에 유효기간을 붙일 수 있게 한다.

이 헤더들은 콘텐츠가 얼마 오랫동안 신선한 상태로 보일 수 있는지 좌우한다.

2. 유효기간과 나이

  • Cache-Control: max-age
    • max-age 값은 문서의 최대 나이를 정의한다. 문서가 처음 생성된 이후부터, 제공하기엔 더 이상 신선하지 않다고 간주될 때가지 경과한 시간의 최대값(초)이다.
    • Cache-Control: max-age=484200
  • Expires
    • 절대 유효기간을 명시한다. 만약 유효기간이 경과했다면, 그 문서는 더 이상 신선하지 않다.
    • Expires: Fri, 05 Oct 2019, 05:00:00 GMT

3. 서버 재검사

캐시된 문서가 만료되었다는 것은 검사할 시간이 되었음을 의미하며, 캐시가 원 서버에게 문서가 변경되었는지 여부를 확인하는 서버 재검사를 한다.

  • 재검사 결과 문서가 변경되었다면, 캐시는 그 문서의 새로운 사본을 가져와 오래된 데이터 대신 저장한 뒤 클라이언트에게 보내준다.
  • 재검사 결과 문서가 변경되지 않았다면, 캐시는 새 만료일을 포함한 새 헤더들만 가져와서 캐시 안의 헤더들을 갱신한다.

캐시는 문서의 신선도를 매 요청마다 검증할 필요가 없으며, 문서가 만료되었을 때 한번만 서버와 재검사를 하면 되기 때문에 서버 트래픽을 절약하고 사용자 응답 시간을 개선한다.

4. 조건부 메서드와의 재검사

  • HTTP는 캐시가 서버에게 조건부 GET 이라는 요청을 보낼 수 있도록 해준다.
  • 이 요청은 서버가 갖고있는 문서가 캐시가 갖고 있는 것과 다른 경우에만 객체 본문을 보내달라고 하는 것이다.
  • 조건부 GET은 GET 요청 메시지에 특별한 조건부 헤더를 추가함으로써 시작된다.
  • HTTP는 다섯 가지 조건부 요청 헤더 중 If-Modified-SinceIf-None-Match를 가장 유용하게 사용한다.

5. If-Modified-Since: 날짜 재검사

IMS요청은 서버에게 리소스가 특정 날짜 이후로 변경된 경우에만 요청한 본문을 보내달라고 한다.

  • 만약 문서가 주어진 날짜 이후에 변경되었다면, If-Modified-Since 조건은 참이고, GET 요청은 성공한다. 새 문서가, 새로운 만료 날짜와 그 외 다른 정보들이 담긴 헤더들과 함께 캐시에게 반환된다.
  • 만약 문서가 주어진 날짜 이후에 변경되지 않았다면 조건은 거짓이고, 서버는 304 Not Modified 응답 메시지를 클라이언트에 돌려준다. 효율을 위해 본문은 보내지 않는다.
  • If-Modified-Since 헤더는 Last-Modified 헤더와 함께 동작한다. 서버가 최근 변경 일시를 붙인다.

6. If-None-Match: 엔터티 태그 재검사

퍼블리셔가 문서를 변경했을 때, 그는 문서의 엔터티 태그를 새로운 버전으로 표현 할 수 있다.

엔터티 태그가 변경되었다면, 캐시는 새 문서의 사본을 얻기 위해 If-None-Match 조건부 헤더를 사용할 수 있다.

  • 캐시는 엔터티 태그 ‘V2.6’인 문서를 갖고있다.
  • 캐시는 서버에게 엔터티 태그가 ‘V2.6’이 아닌 경우에만 새 객체를 달라는 요청 방식으로 유효한지 여부를 재검사한다.
  • 서버의 엔터티 태그가 변하지 않았다면, 304 Not Modified 응답이 반환된다.

캐시가 객체에 대한 여러 개의 사본을 갖고 있는 경우, 하나의 If-None-Match에 여러개의 엔터티 태그를 포함 시킬 수 있다.

If-None-Match: "V2.4", "V2.5", "V2.6"

7. 약한 검사기와 강한 검사기

서버는 때때로 모든 캐시된 사본을 무효화시키지 않고 문서를 살짝 고칠 수 있도록 허용하고 싶은 경우가 있다.

  • 약한 검사기
    • 콘텐츠가 조금 변경되었더라도 그 정도면 같은 것이라고 서버가 주장할 수 있도록 해준다
    • 서버는 W/ 접두사로 약한 검사기를 구분한다.
    • If-None-Match: W/"v1.0"
  • 강한 검사기
    • 콘텐츠가 바뀔 때마다 바뀐다.

8. 언제 엔터티 태그를 사용하고 언제 Last-Modified 일시를 사용하는가

HTTP 클라이언트는 서버가 엔터티 태그를 반환했다면, 반드시 엔터티 태그 검사기를 사용해야 한다.

서버가 Last-Modified 값만을 반환했다면, 클라이언트는 If-Modified-Since 검사를 사용할 수 있다.

7.9 캐시 제어

HTTP는 문서가 만료되기 전까지 얼마나 오랫동안 캐시될 수 있게 할 것인지 서버가 설정할 수 있는 여러 가지 방법을 정의한다.

1. no-cache와 no-store 응답 헤더

Cache-Control: no-store
Cache-Control: no-cache
Pragma: no-cache
  • no-store가 표시된 응답은 캐시가 그 응답의 사본을 만드는 것을 금지한다.
  • no-cache로 표시된 응답은 사실 로컬 캐시 저장소에 저장될 수 있다.
  • Pragma: no-cache 헤더는 HTTP/1.0+와의 하위호환성을 위해 HTTP/1.1에 포함되어 있다.

2. Max-Age 응답 헤더

신선하다고 간주되었던 문서가 서버로부터 온 이후로 흐른 시간이고, 초를 나타낸다.

s-maxage 헤더는 max-age와 같지만, 공유된(공용) 캐시에만 적용된다.

Cache-Control: max-age=3600
Cache-Control: s-maxage=3600

서버는 최대 maximum aging을 0으로 설정함으로써, 캐시가 매 접근마다 문서를 캐시하거나 리프레시하지 않도록 요청할 수 있다.

3. Expires 응답 헤더

(deprecated) Expires 헤더는 초 단위의 시간 대신 실제 만료 날짜를 명시한다.

HTTP를 설계한 사람들은 많은 서버가 동기화 되어 있지 않거나 부정확한 시계를 갖고 있기 때문에, 만료를 절대시간 대신 경과된 시간으로 표현하는 것이 낫다고 판단한다.

Expires: Fri 05 Oct 2019, 05:00:00 GMT

4. Must-Revalidate 응답 헤더

캐시는 성능을 개선하기 위해 신선하지 않은 객체를 제공하도록 설정될 수 있다.

캐시가 만료 정보를 엄격하게 따르길 원한다면, 원 서버는 Cache-Control: must-revalidate 를 붙인다.

캐시가 이 객체의 신선하지 않은 사본을 원 서버와의 최초의 재검사 없이는 제공해서는 안 됨을 의미한다.

5. 휴리스틱 만료

만약 응답이 max-age 헤더나 expires 헤더 중 어느 것도 포함하지 않고 있다면, 캐시는 경험적인 방법으로(heurisitic) 최대 나이를 계산한다.

7.10 자세한 알고리즘

1. 나이와 신선도 수명

캐시된 문서가 신선하지 알려주려면, 캐시는 사본의 나이신선도 수명 단 두 가지만 계산하면 된다.

$충분히_신선한가 = ($나이 < $신선도_수명)

문서의 나이 = 서버가 문서를 보낸 후 그 문서가 나이를 먹은 시간의 총합

신선도 수명 = 아직 문서가 신선하다고 볼 수 있는 수명

2. 나이 계산

  • 응답이 서버에서 생서되었을 때부터 지금까지의 총 시간

  • 인터넷상의 라우터들과 게이트웨들 사이를 떠돌아다닌 시간과 응답이 캐시에 머물렀던 시간을 포함

    $겉보기_나이 = max(0, $응답을_받은_시각 - $Date_헤더값);
    $보정된_겉보기_나이 = max($겉보기_나이, $Age_헤더값);

    $응답_지연_추정값 = ($응답을_받은_시각 - $요청을_보낸_시각);
    $문서가_우리의_캐시에_도착했을_때의_나이 = $보정된_겉보기_나이 + $응답_지연_추정값;
    $사본이_우리의_캐시에_머무른_시간 = $현재_시각 - $응답을_받은_시각;

    $나이 = $문서가_우리의_캐시에_도착했을_때의_나이 + $사본이_우리의_캐시에_머무른_시간;

3. 완전한 나이 계산 알고리즘

문서에 대한 요청이 캐시에 도착했을 때, 문서의 현재 나이를 계산하기 위해 그 문서가 캐시에 얼마나 오랫동안 머물렀는지 알 필요가 있다.

$나이 = $문서가_우리의_캐시에_도착했을_때의_나이 + $사본이_얼마나_오래_우리의_캐시에_있었는지;

  • 언제 문서가 캐시에 도착했는지 = $time_got_response
  • 언제 현재 요청이 도착했는지 = $current_time

HTTP 완벽가이드 7장 part1

7장 캐시 part1

웹 캐시는 자주 쓰이는 문서의 사본을 자동으로 보관하는 HTTP 장치다.

웹 요청이 캐시에 도착했을 때, 캐시된 로컬 사본이 존재한다면, 그 문서는 원 서버가 아니라 그 캐시로 부터 제공된다.

7.1 불필요한 데이터 전송

  • 다수의 클라이언트가 하나의 페이지를 서버에 요청시에 서버는 같은 문서를 네트워크를 통해 각각 전송한다.
  • 값비싼 네트워크 대역폭을 잡아먹고, 전송을 느리게 만들며, 웹 서버에 부하를 준다.

7.2 대역폭 병목

  • 캐시는 네크워크 병목을 줄여준다.
  • 많은 네트워크가 원격 서버보다 로컬 네트워크 클라이언트에 더 넓은 대역폭을 제공한다.

7.3 갑작스런 요청 쇄도(Flash Crowds)

  • 많은 사람들이 거의 동시에 웹 문서에 접근할 때 트래픽이 급증하고 네트워크와 웹 서버의 장애를 일으키는데, 캐싱은 중요한 역할을 한다.

7.4 거리로 인한 지연

  • 클라이언트와 서버 사이에 라우터가 그지 많지 않더라도, 빛의 속도 그 자체가 유의미한 지연을 유발한다.
  • 클라이언트와 서버간의 거리가 멀수록, 커넥션의 개수가 많아지면, 네트워크 지연은 커지게 된다.

7.5 적중과 부적중

캐시 적중(cache hit)이란 캐시에 요청이 도착했을 때, 만약 그에 대응하는 사본이 있다면 그것을 이용해 요청을 처리하는 것이다.

캐시 부적중(cache miss)이란 대응하는 사본이 없다면 그냥 원 서버로 전달된다.

7.5.1 재검사(Revalidation)

  • 원 서버 리소스는 변경될 수 있기 때문에, 반드시 그들이 갖고 있는 사본이 최신인지 서버를 통해서 점검해야한다.
  • 신선도 검사HTTP 재검사라고 부른다.
  • 캐시는 스스로 원한다면 언제든지 사본을 재검사할 수 있다.
  • 캐시가 문서를 수백만 개씩 갖고 있는 경우에는 네트워크 대역폭이 부족하므로, 캐시는 클라이언트가 사본을 요청하였으며 그 사본이 검사를 할 필요가 있을 정도로 충분히 오래된 경우에만 재검사를 한다.

7.5.2 적중률

  • 캐시가 요청을 처리하는 비율을 캐시 적중률 이라고 부른다.
  • 캐시 적중률이 100%에 근접할 수록 모든 요청이 캐시에 적중한 것이다.
  • 일반적으로 40%면 웹 캐시로 괜찮다고 본다.

7.5.3 바이트 적중률

  • 문서들이 모든 같은 크기가 아니기 때문에 문서 적중률이 모든 것을 말해주지 않는다.
  • 바이트 단위 적중률은 캐시를 통해 제공된 모든 바이트의 비율을 표현한다.
  • 문서 적중률을 개선하면 전체 대기시간(지연)이 줄어든다.
  • 바이트 단위 적중률은 얼마나 많은 바이트가 인터넷으로 나가지 않았는지 보여준다.
  • 바이트 단위 적중률을 개선하면 대역폭 절약을 최적화한다.

7.5.4 적중과 부적중의 구별

  • HTTP는 클라이언트에게 응답이 캐시 적중이었는지 아니었는지에 대해서 말해주지 않는다.
  • 클라이언트는 Date 헤더 값을 현재 시각과 비교하여, 응답의 생성일이 더 오래되었다면 클라이언트는 응답이 캐시된 것임을 알아낼 수 있다.

7.6 캐시 토폴로지

7.6.1 개인 전용 캐시

  • 많은 에너지나 저장 공간을 필요로 하지 않으므로, 작고 저렴하다.
  • 웹 브라우저는 개인 전용 캐시를 내장하고 있다.
  • 대부분의 브라우저는 자주 쓰이는 문서를 개인용 컴퓨터의 디스크와 메모리에 캐시해 놓고, 사용자가 캐시 사이즈와 설정을 수정할 수 있도록 허용한다.
  • 크롬에서는 특별한 url인 about:cache 를 통해 확인한다.

7.6.2 공용 프락시 캐시

  • 로컬 캐시에서 문서를 제공하거나, 혹은 사용자의 입장에서 서버에 접근한다.
  • 공용 캐시에는 여러 사용자가 접근하기 때문에, 불필요한 트래픽을 줄일 수가 있다.
  • 캐시는 자주 찾는 객체를 단 한 번만 가져와 모든 요청에 대해 공유된 사본을 제공하여 네트워크 트래픽을 줄인다.

7.6.3 프락시 캐시 계층들

  • 작은 캐시에서 캐시 부적중이 발생했을 때 더 큰 부모 캐시가 그 ‘걸러 남겨진’ 트래픽을 처리하도록 하는 계층 을 만드는 방식이 합리적인 경우가 있다.
  • 클라이언트 주위에는 작고 저렴한 캐시를 사용하고, 계층 상단에는 많은 사용자들에 의해 공유되는 문서를 유지하기 위해 더 크고 강력한 캐시를 사용한다.

  • 캐시 계층이 깊다면 캐시의 긴 연쇄를 따라가게 되고, 각 중간 프락시는 성능 저하가 발생한다.

7.6.4 캐시망, 콘텐츠 라우팅, 피어링

  • 네트워크 아키텍쳐 중 캐시망을 만들고 복잡한 방법으로 서로 대화하여, 어떤 부모 캐시와 대화할 것인지, 아니면 요청이 캐시를 완전히 우회해서 원 서버로 바로 가도록 할것인지에 대한 커뮤니케이션 결정을 내린다.

HTTP 완벽가이드 6장

6장 프락시

6.1 웹 중개자

  • 웹 프락시 서버는 클라이언트 입장에서 트랜잭션을 수행하는 중개인이다.
  • 프락시는 클라이언트의 요청을 받게 되므로, 웹 서버처럼 요청과 커넥션을 적절히 다루고 응답을 돌려줘야 한다.
  • 프락시는 요청을 서버로 보내기도 하므로, 요청을 보내고 응답을 받는 HTTP 클라이언트 처럼 동작해야 한다.

6.1.1. 개인프락시와 공유 프락시

공용 프락시

  • 중앙 집중형 프락시를 관리하는 게 비용효율이 높고 쉽다. 여러 사용자들에게 공통된 요청에서 이득을 취하기 쉬우므로, 캐시 프락시 서버와 같은 프락시 서버는 사용자가 많을수록 효율이 좋다.

개인 프락시

  • 하나의 클라이언트만을 위하므로 개인 전용 프락시는 흔하지 않다.

6.1.2 프락시 대 게이트웨이

프락시

  • 같은 프로토콜을 사용하는 둘 이상의 애플리케이션을 연결한다.
  • 클라이언트와 서버 양쪽 모두에게 HTTP로 통신한다.

게이트웨이

  • 서로 다른 프로토콜을 사용한는 둘 이상의 애플리케이션을 연결한다.
  • 클라이언트와는 HTTP로 서버와는 POP으로 서로 다른 프로토콜로 말하더라도 서로 간의 트랜잭션을 완료하도록 한다.

6.2 왜 프락시를 사용하는가?

보안을 개선하고, 성능을 높여주며, 비용을 절약한다.

모든 HTTP 트래픽을 보고 건드릴 수 있기 때문에, 유용한 웹 서비스를 구현하기 위해 트래픽을 감시하고 수정한다.

ex)

  • 교육 콘텐츠에는 제한 없는 접근을 허용하면서 어린이에게 부적절한 사이트의 접근을 강제로 거부한다.
  • 대기업이나 분산된 조직에서 관리되는 다양한 종류의 수많은 웹 서버들에 대한 접근 제어를 수시로 갱신 할 필요 없이, 중앙 프락시 서버에서 접근 제어를 설정할 수 있다.
  • 바이러스를 제거하는 웹이나 이메일 프락시가 사용할 수 있는 트래픽을 세심하게 살펴볼 수 있는 훅을 제공한다.
  • 인터넷 트래픽 조건과 콘텐츠의 종류에 따라 요청을 특정 웹 서버로 유도하는 콘텐츠 라우터로 동작할 수 있다.

6.3 프락시는 어디에 있는가?

6.3.1 프락시 서버 배치

출구 프락시

  • 로컬 네트워크와 더 큰 인터넷 사이를 오가는 트래픽을 제어하기 위해 프락시를 로컬 네트워크의 출구에 넣을 수 있다.

접근(입구) 프락시

  • 고객으로 부터의 모든 요청을 종합적으로 처리하기 위해 프락시는 ISP 접근 지점에 위치한다.

대리 프락시

  • 네트워크의 가장 끝에 있는 웹 서버들의 바로 앞에 위치하여 웹 서버로 향하는 모든 요청을 처리하고 필요 할 때만 웹 서버에게 자원을 요청할 수 있다.

네트워크 교환 프락시

  • 캐시를 이용해 인터넷 교차로의 혼잡을 완화하고 트래픽 흐름을 감시한다.

6.3.2 프락시 계층

  • 프락시들이 연쇄적으로 구성되어있다.
  • 프락시 서버들은 부모와 자식의 관계를 갖는다.
  • 각각의 프락시 서버들의 여러가지 판단 근거에 의해 메시지를 다양하고 유동적으로 전송한다.

6.3.3 어떻게 프락시가 트래픽을 처리하는가

클라이언트 트래픽이 프락시로 가도록 만드는 방법이 네 가지 존재한다.

클라이언트를 수정한다

  • 대부분의 브라우저들은 수동 또는 자동 프락시 설정을 지원한다. 클라이언트는 HTTP 요청을 프락시로 보낸다.

네트워크를 수정한다

  • HTTP 트래픽을 지켜보고 가로채어 클라이언트 모르게 트래픽을 프락시로 보낸다.(인터셉트 프락시)

DNS 이름공간을 수정한다

  • 웹 서버 앞에 위치하는 대리 프락시 서버는 웹 서버의 이름과 IP주소를 자신이 직접 사용한다.

웹 서버를 수정한다

  • HTTP 리다이렉션 명령을 클라이언트에게 돌려줌으로써 클라이언트의 요청을 프락시로 리다이렉트 하도록 설장할 수 있다.

6.4 클라이언트 프락시 설정

많은 브라우저가 프락시를 설정하는 여러가지 방법을 제공한다.

  • 각 브라우저의 설정 메뉴에서 프락시 사용에 대한 설정을 할 수 있다.
  • PAC파일을 사용하면 프락시 설정을 상황에 맞게 자바스크립트 함수가 계산해서 적절한 프락시 서버를 선택한다.
  • WPAD는 브라우저에게 알맞은 PAC 파일을 자동으로 찾아준다.

6.5 프락시 요청의 미묘한 특징들

6.5.1 프락시 URI는 서버 URI와 다르다

6.5.2 가상 호스팅에서 일어나는 같은 문제

  • 스킴/호스트/포트번호 누락 문제는 가상으로 호스팅 되는 웹 서버의 문제와 같은 문제다.

6.5.3 인터셉트 프락시는 부분 URI를 받는다

6.5.4 프락시는 프락시 요청과 서버 요청을 모두 다룰 수 있다

  • 트래픽이 프락시 서버로 리다이렉트 될 수 잇는 여러가지 방법이 존재하기 때문에 다목적 프락시 서버는 요청 메시지의 와전한 URI와 부분 URI 모두 지원해야한다.
  • 완전한 URI가 주어졌다면, 그것을 사용한다.
  • 부분 URI 주어졌고 Host 헤더가 있다면, Host 헤더를 이용해 원 서버의 이름과 포트번호를 알아야한다.
  • 부분 URI가 주어졌으나 Host 헤더가 없다면, 원 서버를 알아내야 한다.

6.5.5 전송 중 URI 변경

6.5.6 URI 클라이언트 자동확장과 호스트 명 분석

6.5.7 프락시 없는 URI 분석

6.5.8 명시적인 프락시를 사용할 때의 URI 분석

6.5.9 인터셉트 프락시를 이용한 URI 분석

6.6 메시지 추적

  • 웹 요청시에 클라이언트에 서버로 향하는 도중에 둘 이상의 프락시를 거치는 것은 흔해졌다.
  • 프락시가 흔해지면서, 서로 다른 스위치와 라우터를 넘나드는 IP 패킷의 흐름을 추적하는것 못지않게 프락시를 넘나드는 메시지의 흐름을 추적하고 문제점을 찾아내는 것이 중요하다.

6.6.1 Via 헤더

  • 메시지가 지나는 각 중간 노드의 정보를 나열한다.

6.7 프락시 인증

  • 프락시는 접근 제어 장치로서 제공될 수 있다.
  • HTTP는 사용자가 유효한 접근 권한 자격을 프락시에 제출하지 않는 한 콘텐츠에 대한 요청을 차단하는 프락시 인증을 제공한다.

6.8 프락시 상호운용성

  • 클라이언트, 서버, 프락시는 여러 버전으로 여러 벤더 회사에 의해 만들어진다.
  • 제각각의 버그들이 생기므로 프락시 서버는 클라이언트와 서버를 중개해야 한다.

6.8.1 지원하지 않는 헤더와 메서드 다루기

  • 프락시 서버는 넘어오는 헤더 필드들을 모두 이해하지 못할 수 있다.
  • 이해할 수 없는 헤더 필드는 반드시 그대로 전달해야 하며, 같은 이름의 헤더 필드가 여러개 있는 경우에는 그들의 상대적인 순서도 반드시 유지해야한다.

6.8.2 Options: 어떤 기능을 지원하는지 알아보기

  • HTTP OPTIONS 메서드는 서버나 웹 서버의 특정 리소스가 어떤 기능을 지원하는지 알아볼 수 있게 해준다.

  • 요청의 URI가 별표(*)라면, 요청은 서버 전체의 능력에 대해 묻는 것이 된다.

    OPTIONS * HTTP/1.1

  • URI가 실제 리소스라면, 특정 리소스에 대해 가능한 기능들을 묻는 것이다.

    OPTIONS [http://bebiangel.github.io](http://bebiangel.github.io/index.html) HTTP/1.1

    static HTML file wouldn't accept a POST method.

6.8.3 Allow 헤더

  • 요청 URI에 의해 식별되는 자원에 대해 지원되는 메서드들이나 서버가 지원하는 모든 메서드를 열거한다.

    Allow: GET, HEAD, PUT

  • 클라이언트는 원 서버와 대화하는 다른 경로를 갖고 있을 수 있기 때문에, 프락시는 Allow 헤더 필드를 수정할 수 없다.

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×