## 6.1 웹 중개자

- 웹 프락시 서버: 클라이언트 입장에서 트랜잭션을 수행하는 중개인.
    - 프락시 서버는 웹 클라이언트이자(서버에 요청 후, 응답 받음) 웹 서버(클라이언트에 요청 받고, 응답 전송)
        - 웹 클라이언트와, 서버의 규칙을 잘 따르도록 개발 해야함.
    - 트랜잭션은 완료하는 것이 클라이언트라는 점은 동일하지만, 프락시 서버가 제공하는 좋은 서비스를 이용

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

***공용 프락시***

- 여러 클라이언트가 공유하는 프락시. 프락시는 대부분 공용 프락시.
- 중앙 집중형 프락시 관리가 더 비용효율이 높고 쉬우며, 캐시 프락시와 같은 몇 프락시 애플리케이션은 사용자가 많을 수록 공통된 요청에서 이득을 취할 수 있어 유리함.

***개인 프락시***

- 하나의 클라이언트를 위한 프락시. 흔하지 않지만 클라이언트 컴퓨터에서 직접 실행되는 형태로 꾸준히 사용됨
- 어떤 브라우저 보조 제품들은 (ISP 서비스와 마찬가지로)  브라우저 기능 확장, 성능 개선, 무료 ISP 서비스용 광고 운영을 위해 작은 프락시를 컴퓨터에서 직접 실행

### 6.1.2 프락시 대 게이트웨이

- **프락시**: **같은 프로토콜**을 사용하는 둘 이상의 애플리케이션 연결
- **게이트웨이**: **다른 프로토콜**을 사용하는 둘 이상의 애플리케이션 연결
    - 다른 프토토콜로도 트랙잭션을 완료할 수 있게 하는 프로토콜 변환기.
- 실질적인 프락시와 게이트웨이의 차이점은 모호.
    - 브라우저와 서버는 다른 HTTP 버전을 구현하기 때문에, 프락시도 때때로  약간의 프로토콜 변환을 함
    - 상용 프락시 서버는 SSL 보안 프로토콜, SOCKS 방화벽, FTP 접근, 웹 기반 애플리케이션 지원을 위해 게이트웨이 기능 구현.

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

- 프락시는 보안 개선, 성능 향상, 비용 절약이 가능.
- 프락시는 부가적인 가치를 주는 여러 유용한 웹 서비스를 구현하기 위해 HTTP 트래픽 감시, 수정 가능

***어린이 필터***

- **필터링 프락시**: 특정 콘텐츠는 필터링을 위해 사용.
- 예: 교육컨텐츠는 제공하면서, 성인 콘텐츠는 차단함

***문서 접근 제어자***

- **접근 제어 프락시**: 프락시 서버는 웹 서버들과 웹 리소스에 대한 단일한 접근 제어 전력을 구현하고, [감사 추적(audit trail)](https://ko.wikipedia.org/wiki/%EA%B0%90%EC%82%AC%EC%9A%A9_%EA%B8%B0%EB%A1%9D)을 위해 사용
- 각기 다른 조직에서 관리되는 여러 종류의 많은 웹 서버에 대한 접근을 중앙 프락시에서 접근 제어설정 할 수 있음. 대기업 혹은 분산 관료 조직에 유용.
    - 예: 클라이언트 1은 제약없이 서버 A에 접근, 클라이언트2 는  서버B에 접근 전에 비밀번호를 요구
- 고의적으로 제어 프락시를 피하는 것을 방지하기 위해, 웹 서버는 프락시 서버로부터의 요청만 받도록 설정할 수 있음.

***보안 방화벽***

- **보안 방화벽:** 보안 강화를 위해 사용
- 들어가고 나가는 응용 레벨 프로토콜의 흐름을 네트워크 한 지점에서 통제.
- 트래픽을 세심히 살펴볼 수 있는 후크(hook) 제공.
    - 바이러스를 제거하는 웹, 이메일 프락시가 사용할 수 있음

***웹 캐시***

- **웹 캐시:** 인기 있는 문서의 로컬 사본을 관리하고, 같은 문서의 요청에 빠르게 제공해 커뮤니케이션을 줄이기 위해 사용.

***대리 프락시(Surrogate)***

- **대리 프락시(=리버스 프락시)**: 웹 서버인것처럼 위장하지만 웹 서버와 달리 요청 받은 콘텐츠를 찾기 위해 다른 서버와 커뮤니케이션
- 공용 콘텐츠에 대한 느린 웹 서버의 성능 개선을 위해 사용. 이 경우 대리 프락시를 서버 가속기라고 부름
- 콘텐츠 라우팅 기능과 결합해, 주문형 복제 콘텐츠의 분산 네트워크 만들기에 사용되기도 함.

***콘텐츠 라우터***

- **콘텐츠 라우터:**  인터넷의 트래픽 조건과 콘텐츠 종류에 따라 요청을 특정 웹서버로 유도하여, 사용자에게 제공할 여러 서비스를 구현하는 데 사용
- 예시:
    - 사용자/콘텐츠 제공자가 성능을 위해 돈을 냈다면, 콘텐츠 라우터는 요청을 가까운 복제 캐시로 전달
    - 사용자가 필터링 서비스에 가입했다면, HTTP 가 필터링 프락시를 통과하도록 함

***트랜스코더***

- 트랜스코딩: 데이터의 표현 방식을 자연스럽게 변환하는 것.
- **트랜스코더:** 콘텐츠를 클라이언트에 전달하기 전에 본문 포맷을 수정.
    - 이미지를 GIF→JPG로 변환하거나, 텍스트 파일을 압축하거나, 텍스트 크기를 변환한 웹 페이지를 생성하거나, 문서를 외국어 문서로 변환하는 것 등이 가능.

***익명화 프락시(Anonymizer)***

- HTTP 메시지에서 신원을 식별 가능 특성들을 제거해 개인 정보 보호와 익명성 보장에 기여하기 위해 사용.
    - 신원 가능 특성: 클라이언트 IP주소, From 헤더, Refere 헤더, 쿠키, URI 세션 아이디 등
- 예시:
    1. 사용자의 메시지에 `User-Agent` 헤더에서 컴퓨터, OS 제거.
    2. 이메일 주소를 보호하기 위해 `From` 헤더 제거
    3. 어떤 사이트를 거쳤는지 알기 어렵게 하기 위해 `Referer` 헤더 제거
    4. 프로필과 신원 정보를 없애기 위해 `Cookie` 헤더 제거 

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

### 6.3.1 프락시 서버 배치

- 사용 방향에 따라 프락시는 어디에든 배치될 수 있으나, 배치 될 수 있는 몇가지 방법을 소개

***출구(Egress) 프락시***

```
클라이언트 ←(로컬 네트워크)→ 프락시 ←(인터넷)→ 서버
```

- 로컬 네트워크와 더 큰 인터넷을 오가는 트래픽 제어를 위해 로컬 네트워크 출구에 배치.
    - 방화벽 제공, 인터넛 요금 절약 및 인터넷 트래픽 성능 개선을 위해 회사에서 사용 가능.
    - 부적절한 콘텐츠 필터링을 위해 학교에서 사용 가능

***접근(입구) 프락시 = ISP 접근 프락시***

```
클라이언트 ←→ 프락시 ←(인터넷)→ 서버 
```

- 고객으로부터의 모든 요청을 종합적으로 처리하기위해 ISP 접근 지점에 위치.
    - ISP는 사용자들의 다운로드 속도 개선(특히 고속 접속 사용자), 인터넷 대역폭 비용을 줄이기 위해 캐시 프락시를 사용하여 사본을 저장.

***대리 프락시***

```
클라이언트 ←(인터넷)→ 프락시 ←(로컬 네트워크)→ 서버
```

- 네트워크의 가장 끝에 있는 웹 서버들의 바로 앞에 위치.
    - 웹 서버로 향하는 모든 요청을 처리하고, 필요할 때만 웹 서버에 자원 요청
    - 웹 서버에 보안기능을 추가
    - 빠른 웹 서버 캐시를 느린 웹 서버 앞에 놓음으로 성능 개선
- 대리 프락시는 일반적으로 웹 서버의 이름과 IP주소로 가장하기 때문에, 모든 요청은 서버가 아닌 프락시로 가게됨.

***네트워크 교환 프락시***

```
클라이언트 ←(네트워크1)→ 프락시 ←(네트워크2)→ 서버
```

- 네트워크 사이의 인터넷 피어링 교환 지점에 위치
    - 캐시를 이용해 인터넷 교차로의 혼잡을 완화, 트래픽 흐름을 감시하기 위해 사용

### 6.3.2 프락시 계층

- 프락시는 계층이라고 불리는 연쇄 구성 가능.
    - 프락시 계층에서 메세지는 최종적으로 원 서버/클라이언트에 도착할때까지 프락시와 프락시를 거쳐 이동.
    - 예: 클라이언트 ↔프락시1 ↔ 프락시2 ↔ 프락시3 ↔ 서버
- 프락시 계층에서, 다음번 인바운드 프락시(서버 방향)을 부모, 다음번 아웃바운드 프락시(클라이언트 방향)을 자식이라고 부름.

***프락시 계층 콘텐츠 라우팅*** 

- 프락시 계층은 정적임. 프락시1 ↔ 프락시2 ↔ 프락시3
    - 계층이 반드시 정적이여야 하는 것은 아니며, 여러 판단 근거에 의해 유동적으로 보낼 수 있음
- 프락시가 상황에 맞게 부모 프락시나 서버에 라우팅하는 예
    - 요청된 객체가 콘텐츠 분산을 위해 돈을 지불한 웹 서버에 속하면, 프락시는 요청을 가가운 캐시서버에게 보내 캐시된 객체를 반환하거나, 그럴 수 없을 때는 원 서버에서 가져옴
    - 요청이 특정 종류의 이미지에 대한 경우, 접근 프락시는 요청을 특화된 압축 프락시에게 보내  그 프락시가 이미지를 가져와 압축하여 느린 모뎀으로 접속해도 빠르게 다운로드 할 수 있게 함
- 동적 부모 선택의 예
    - 부하 균형
        - 자식 프락시는 부하를 분산하기 위해 현재 부모의 작업량 수준에 근거하여 부모 프락시 선택
    - 지리적 인접성에 근거한 라우팅
        - 자식 프락시는 원 서버의 지역을 담당하는 부모를 선택할 수 있음
    - 프로토콜/타입 라우팅
        - 자식 프락시는 URIR에 근거하여 다른 부모/원 서버로 라우팅할 수 있음.
        - 특정 종류의 URI 요청을 특별한 프락시 서버로 보내 특별한 프로토콜로 처리할 수도 있음.
    - 유료 서비스 가입자를 위한 라우팅
        - 빠른 서비스를 위해 추가금을 지불했다면, URI는 대형 캐시나 성능 개선을 위한 압축 엔진으로 라우팅
- 동적 부모 라우팅 로직은 제품(설정파일, 스크립트 언어, 동적 실행 가능 플러그인 등)마다 다르게 구현됨.

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

- 클라이언트 트래픽이 프락시로 가도록 만드는 방법은 4가지가 있음

***클라이언트를 수정한다***

- 브라우저를 포함한 많은 웹 클라이언트들은 수동/자동 프락시 설정을 지원.
- 클라이언트가 프락시를 사용하도록 설정되어있다면, 클라이언트는 HTTP 요청을 바로/의도적으로 원서버가 아닌 프락시로 보냄

***네트워크 수정한다***

- 클라이언트가 모르는 상태에서, 네트워크 인프라를 가로채 웹 트래픽을 프락시로 조정하는 기법이 있음.
- 일반적으로 가로채기 위해 HTTP 트래픽을 지켜보고, 프락시로 보내는 스위칭 장치와 라우팅 장치를 필요로함.
    - 인터셉트 프락시(=투명 프락시)라고 함.

***DNS 이름 공간 수정한다***

- 대리프락시는 웹 서버의 이름과 IP주소를 직접 사용. 모든 요청은 대리프락시로 감
- DNS 이름 테이블을 수동으로 편집 혹은 적절한 프락시나 서버를 계산해주는 특별한 동적 DNS 이용해서 조정됨

***웹 서버 수정 한다***

- 웹 서버가 HTTP 리다이렉션(305)를 클라이언트에게 돌려주어, 요청이 프락시로 리다이렉트 되도록 설정
- 리다이렉트를 받은 클라이언트는 프락시와 트랜잭션 시작

## 6.4 클라이언트 프락시 설정

- 모든 현대적인 브라우저는 프락시를 사용할 수 있도록 설정 가능.
- 브라우저는 프락시를 설정하는 여러 방법 제공
    - 수동 설정 / 브라우저 기본 설정 / 프락시 자동설정(PAC) / WPAD 프락시 발견

### 6.4.1 클라이언트 프락시 설정: 수동

- 프락시를 사용하겠다고 명시적 설정하는 방법으로, 프락시의 호스트와 포트를 지정.
- 단순하지만 유연하지 못하고, 단 하나의 프락시 서버만 지정가능.
- 장애시의 대체 작동 지원도 없고, 큰 조직에서 관리 문제 야기

### 6.4.2 클라이언트 프락시 설정: PAC 파일

- 프락시 자동설정(Proxy auto-configuration, PAC)은 프락시 설정을 상황에 맞게 계산해주는 자바스크립트 프로그램
- 브라우저 설정에 PAC 파일의 URI를 설정하면, 브라우저는 매 접근마다 적절한 프락시 서버 계산을 위해 PAC 자바스크립트 로직 이용.
- 확장자는 `.pac` , MIME 타입은 `'application/x-ns-proxy-autoconfig'`

```jsx
/**
 * 적절한 프락시 서버를 계산해주는 해당 이름의 함수를 정의 해야 함.
 */
function FindProxyForUrl(url, host) {
	if (url.substring(0, 5) == "http:") {
		// "PROXY host:port" => 지정한 프락시를 이용해야함 
		return "PROXY http-proxy.mydomain.com:8080";
	} else if () {
		return "PROXY ftp-proxy.mydomain.com:8080"; 
	} else {
		return "DIRECT"; // "DIRECT" => 프락시 연결 없이 직접 이루어져야 함.
	}
	// "SOCKS host:port" => 지정한 SOCKS 서버를 사용해야함
}
```

### 6.4.3 클라이언트 프락시 설정: WPAD

- 웹 프락시 자동 발견 프로토콜(Web Proxy Autodiscovery Protocol, WPAD)은 여러 발견 메커니즘의 상승 전량을 이용해 브라우저에게 맞는 PAC 파일을 찾는 알고리즘
- WPAD는 올바른 PAC 파일을 알아내기 위해 일련의 리소스 발견 기법들을 하나씩 시도해봄
- 현재의 WPAD 명세는 다음 기법을 순서대로 정의
    - 동적 호스트 발견 규약(DHCP)
    - 서비스 위치 규약(SLP)
    - DNS 잘 알려진 호스트명
    - DNS SRV 레코드
    - DNS TXT 레코드 안의 서비스 URI

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

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

- 웹 서버와 웹 프락시의 메시지문법은 동일하지만, 클라이언트가 프락시 대신 서버로 요청 보내면 요청 URI가 달라짐
    - 클라이언트 → 웹 서버 요청: 요청줄은 스킴/호스트/포트번호가 없는 부분 URL을 가짐
    - 클라이언트 → 프락시 요청: 요청줄은 완전한 URI를 가짐
- HTTP 설계에는 가상 호스팅/프락시가 존재하기 전, 불필요한 정보발송을 피하기 위해 부분 URI만 전송.
    - 하지만 프락시에서는 목적지 서버의 커넥션을 맺어야하므로, 전체 URI가 필요.
- 클라이언트는 프락시 사용 여부에 따라 완전한 URI/부분 URI 요청을 보내도록 해야 함

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

- 가상 호스팅되는 웹서버는 여러 웹 사이트가 같은 물리적 웹 서버를 공유하므로 호스트명을 알아야함. 프락시와 같이 부분 URI에 대한 이슈가 발생
- 명시적 프락시는 완전한 URI를 갖게 하고, 가상으로 호스팅되는 웹 서버는 호스트와 포트에 대한 정보가 담겨있는 Host 헤더를 요구함으로써 해결.

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

- 명시적 프락시에 완전한 URI를 보내도록 클라이언트가 구현되었더라도, 인터셉트 프락시와 같이 클라이언트에게 보이지 않는다면, 클라이언트가 부분 URI를 보낼 수 있음

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

- 트래픽이 리다이렉트 될 수 있는 여러 방법이 존재하므로, 다목적 프락시 서버는 요청 메시지의 완전한 URI, 부분 URI를 모두 지원해야 함.
- 완전 URI, 부분 URI 사용 규칙
    - 완전한 URI가 주어지면 프락시가 사용
    - 부분 URI + Host헤더가 있다면 원 서버의 이름과 포트 번호를 알아내야 함.
    - 부분 URI + Host헤더가 없다면, 원 서버의 이름을 다음 방법으로 설정
        - 프락시가 대리 프락시라면, 프락시에 실제 서버의 주소, 포트번호가 설정되어있을 수 있음
        - 인터셉트 프락시가 가로챘던 트래픽을 받았을 때, 그 프락시가 원 IP주소/포트 번호를 사용할 수 있게 했다면 사용 가능
        - 모두 실패시, 원 서버를 알 수 있는 정보를 갖지 못한 것이므로, (Host 헤더를 지원하는 현대적 브라우저로 변경하라는) 에러메시지 반환.

### 6.5.5 전송 중 URI 변경

- 몇 프락시는 URI를 다음 홉으로 보내기 전에 정규화함.
- 포트 명시/이스케이프 등과 같은 무해한 변형도 상호 운용성 문제를 일으킬 수 있음
- 프락시 서버는 URI에 최대한 관대해야하고, 특히 일반적인 인터셉트 프락시가 URI를 전달할 때 절대 경로를 고쳐 쓰는 것을 금지. (예외: 빈 경로를 '/'로 교체)

### 6.5.6 URI 클라이언트 자동확장과 호스트명 분석(Hostname Resolution)

- 브라우저는 프락시가 없는 경우 사용자가 타이핑한 URI를 가지고 IP주소 찾음
- 호스트명이 발견되지 않으면, 호스트명의 약어를 타이핑한것으로 간주하고 자동화된 호스트명의 확장을 제공하기 위해  몇가지 시도를 함
    - 웹사이트 이름의 가운데 부분만 입력했다면, 'www.' 접두사와 '.com' 접미사를 붙임
    - 몇 브라우저는 해석할 수 없는 URI를 서드파티 사이트로 넘겨 오타 교정을 시도하고 의도했을 URI를 제시함
    - 대부분의 시스템에서 DNS는 사용자가 호스트며으이 압부분만 입력하면 자동으로 도메인을 검색하도록 설정되어있음.

### 6.5.7 프락시 없는 URI 분석(URI Resolution)

- 프락시 없는 브라우저 호스트명 자동확장 진행
    1. 사용자가 'oreilly' URI를 입력. 브라우저는 호스트명으로 간주하여, 기본 스킴을 'htt://', 기본 포트를 '80', 기본 경로를 '/' 로 간주
    2. 브라우저는 호스트 'oreilly'를 찾아봄. 실패
    3. 브라우저는 호스트명을 자동으로 확장한 후 DNS에 'www.oreilly.com'의 주소 분해(resolve) 요청. 성공.

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

- 명시적 프락시를 사용하면, 확장 기능을 수행 불가.
    - 사용자가 브라우저에 'oreilly'로 타이핑하면, 프락시는 'http://oreilly/'로 보냄
    - 이런 이유로 몇 프락시는 'www...com' 자동 확장이나, 지역 도메인 접미사 추가와 같은 브라우저의 편리한 서비스를 흉내내려고 시도

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

- 호스트명 분석은 보이지 않는 인터셉트 프락시와 함께일 때는 프락시가 아닐 때와 동일하게 동작.
- 그러나 서버로 커넥션이 만들어졌을 때에는 분명한 차이가 있음
- 인터셉트 프락시를 이용할 때의 트랜잭션
    1. 사용자가 브라우저에 'oreilly' 입력.
    2. 브라우저 호스트는 'oreilly'를 DNS를 통해 찾지만, 실패
    3. 브라우저는 'www.oreilly.com' 로 변환하는 자동확장 수행 후, DNS를 통해 찾는다. 성공.
    4. 호스트명을 성공적으로 분석하고, IP 주소 목록을 갖게되어 모든 IP 주소에 대해 시도. 일부 IP 주소는 죽은 것일 수도 있음. 인터셉트 프락시를 낀다면, 접속 시도는 원 서버가아닌 프락시 서버에 의해 종료되므로, 클라이언트는 웹 서버와 대화했다고 생각했지만, 웹서버는 죽어있을 수 있음.
    5. 프락시가 최종적으로 진짜 원 서버와 상호작용할 준비가 되었을 때, 프락시는 그 IP주소가 실제로는 다운되었음을 알게 됨. 브라우저에서 제공하는 수준의 장애 허용(fault tolerance)을 제공하기 위해, 프락시는 호스트 헤더에 들어있는 호스트명 재분석, 혹은 IP주소에 대한 역방향 DNS 룩업을 통해 다른 IP주소를 시도해야함. 
- 인터셉트 프락시/명시적 프락시 모두 죽은 서버의 DNS 분석에 대한 장애 허용을 지원해야 함.

## 6.6 메시지 추적

- 오늘날의 웹 요청의 상당수가 프락시를 지나가며, 성능상의 이유로 대리 캐시 저장고에 콘텐츠를 복제하는 방식이 흔해지고 있음.
- 프락시가 흔해지면서, 프락시를 넘나드는 메시지 흐름 추적 및 문제점 파악이 중요한 일이 되었음.

### 6.6.1 Via 헤더

- 메시지가 지나가는 각 중간 노드(프록시/게이트웨이)의 정보를 나열하는 필드. 노드를 지날 때마다 Via 목록 끝에 추가되어야함.
- Via헤더 필드는 메세지의 전달을 추적, 메세지 루프를 진단, 요청을 전송/응답을 반환 과정에 관여하는 모든 메세지 발송자들의 프로토콜을 다루는 능력을 알아보기 위해 사용.
- 프락시 또한 네트워크 라우팅 루프 감지를 위해 자신을 나타내는 고유한 문자열을 삽입한 Via 헤더 사용 가능.

***Via 문법***

```
Via: 1.1 proxy-62.irenes-isp.net, 1.0 cache.joes-hardware.com
```

```
Via               = "Via" ":" ( waypoint ) [", " ( waypoint )...]
waypoint          = ( received-protocol received-by [ comment ] )
received-protocol = [ protocol-name "/" ] protocol-version
received-by       = ( hostt [ ":" port ] ) | pseudonym
```

- 프로토콜 이름
    - 중개자가 받은 프로토콜로, HTTP라면 이름 생략.  '/'가 버전 앞에 구분 되어 붙음
- 프로토콜 버전
    - HTTP라면 표준 번호(1.0, 1.1)가 사용됨. 애플리케이션은 이를 통해 모든 중개자의 버전 확인.
- 노드 이름
    - 중개자의 호스트와 포트 번호(포트가 생략 가능. 기본 포트로 간주)
    - 정보 보호를 이유로 가명으로 대체할 수 있음
- 노드 코멘트
    - 중개자 노드를 서술하는 선택적 코멘트. 벤더, 버전 정보, 이벤트에 대한 진단 정보 등을 포함 가능

***Via 요청과 응답 경로*** 

- 요청/응답 메시지는 프락시를 지나므로 Via 헤더를 가짐.
- 요청과 응답은 같은 TCP 커넥션을 오가므로, 응답은 요청과 같은 경로로 되돌아가기때문에, 응답의 Via 헤더(a→b→c)는 요청 Via(c→b→a)의 반대 순서임

***Via와 게이트웨이***

- 몇 프락시는 서버에게 비 HTTP 프로토콜을 사용할 수 잇는 게이트웨이 기능 제공.
- Via헤더는 이러한 프로토콜 변환 기록도 기록하여, HTTP 애플리케이션이 프락시 연쇄에서 프로토콜 능력과 변환이 있었는지 알아챌 수 있음.

***Server 헤더와 Via 헤더***

- Server 응답 헤더 필드는 원 서버에 의해 사용되는 소프트웨어를 알려주며, Server 헤더는 원 서버를 위해 존재하므로 프락시가 수정해서는 안됨.

```
Server: Apache/1.3.14 (Unix) PHP/4.0.4
Server: Netscape-Enterprise/4.1
Server: Microsoft-IIS/5.0
```

***Via가 개인정보 보호와 보안에 미치는 영향***

- Via 문자열에 보안상의 문제로 정확한 호스트명이 들어가면 안되는 경우가 있음.
    - 예: 프락시 서버가 네트워크 방화벽의 일부인 경우, 방화벽 뒤의 호스트 이름, 포트를가 악의적으로 이용되지 않도록 전달하지 말아야 함.
- 프락시는 호스트명을 적당한 가명으로 교체하거나, Via 경유지 항목들을 하나로 합칠 수 있음.
    - 경유지가 같은 조직의 통제 하에 있고 가명으로 교체되지 않는 이상, 합치면 안됨.
    - 수신된 프로토콜 값이 달라도 합치면 안됨

### 6.6.2 TRACE 메서드

- HTTP/1.1의 TRACE 메서드는 요청 메시지의 프락시 연쇄를 따라가면서 어떤 프락시를 지나가고 어떻게 각 프락시가 요청 메시지를 수정하는지 관찰/추적 가능.
- TRACE 요청이 목적지 서버에 도착했을 때, 서버는 전체 요청 메세지를 HTTP 응답 메세지의 본문에 포함시켜 송신자에게 그대로 돌려보냄.
- 클라이언트는 TRACE 응답에서 클라이언트는 메시지와, 지나간 프락시 목록을 검사할 수 있음
    - TRACE 응답의 Content-Type은 message/http, 상태는 200 OK

***Max-Forwards***

- 일반적으로 TRACE 메시지는, 중간 프락시 갯수를 신경쓰지 않고 경로를 여행.
- Max-forwards 헤더를 이용하여 TRACE, OPTIONS 요청의 프락시 홉(hop) 개수를 제한 가능.
    - 무한 루프에 빠지는지 프락시 연쇠 테스트, 연쇄 중간의 특정 프락시 서버들의 효과 체크에 유용
- Max-forwards의 값이 0이라면, 메시지를 더 이상 전달하지 말고, 클라이언트에 돌려줌.
    - 0보다 크다면, 다음으로 전달될 때 1을 감소하고 갱신

## 6.7 프락시 인증

- 프락시는 접근 제어 장치로서 제공 가능.
- 프락시 인증: 사용자가 유효한 접근 권한 자격을 프락시에 제출하지 않는 한, 콘텐츠에 대한 요청을 차단하는  매커니즘
    - 제한된 콘텐츠에 대한 요청이 프락시 서버에 도착시, `407 Proxy Authorization Required` 상태 코드를 어떻게 자격을 제출하는지 설명하는  `Proxy-Authenticate` 헤더 필드와 함께 반환
    - 클라이언트는 `407` 응답을 받으면, 사용자에게 요구되는 자격을 수집한다.
    - 자격 획득시, 해당 자격을 `Proxy-Authenticate` 헤더 필드에 담아 요청을 다시 보냄
    - 유효하다면 프락시는 원 요청을 연쇄에따라 통과시키고, 유효하지 않으면 `407` 응답 전송
- 프락시 인증은 인증에 참여하는 프락시가 연쇄 상에 여러 개 있으면 잘 동작하지 않음.

## 6.8 프락시 상호운용성

- 클라이언트, 서버, 프락시는 여러 버전에 대해  벤더에 의해 만들어지며, 각각 다른 버그를 가지고 있음.
- 프락시 서버는 위처럼 서로 다른 클라이언트, 서버 사이를 중개해야 함

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

- 프락시는 지원할 수 없는 메서드, 이해할 수 없는 헤더도 그대로 전달해야 하며, 같은 이름의 헤더 필드가 여러 개 여도 상대적인 순서를 유지해야 함.

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

- HTTP OPTIONS 메서드는 서버나 웹 서버의 특정 리소스가 어떤 기능을 지원하는지(메서드 등) 클라이언트/프락시가 알아볼 수 있게 해줌
- OPTIONS 요청의 URI가 `*` 라면, 요청은 서버 전체의 능력에 대해 물음

    ```
    OPTIONS * HTTP/1.1
    ```

- OPTIONS 요청의 URI가 실제 리소스라면, 요청은 특정 리소스에 대해 가능한 기능에 대해 물음

    ```
    OPTIONS http://www.joes-hardware.com/index.html HTTP/1.1
    static HTML file wouln't accept a POST method.
    ```

- 성공한다면, 서버에서 지원/지정한 리소스에 대한 가능한 기능을 서술하는 헤더를 포함한 `200 OK` 응답 반환
    - 서버에 의해 어떤 메서드가 지원되는지 서술하는 HTTP/1.1이 명시한 헤더는 Allow 헤더뿐.

### 6.8.3 Allow 헤더

- Allow 헤더는 요청 URI에 의해 식별되는 자원에 대해 지원되는 메서드/서버가 지원하는 모든 메서드를 열거

    ```
    Allow: GET, HEAD, PUT
    ```

- 지원했으면 하는 메서드를 추천하기 위해 요청 헤더로 사용할 수 있음. 서버가 해당 메서드를 지원해야 할 의무는 없으며, 지원하는 메서드만 포함시켜 응답해야 함
- 프락시는 모르는 메서드가 있다하더라도 Allow 필드를 수정할 수 없음
