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 헤더 필드를 수정할 수 없다.

HTTP 완벽가이드 5장

5장 웹서버

5. 1 웹 서버가 하는 일

  1. 커넥션을 맺는다. 클라이언트의 접속을 받아들이거나, 원치 않는 클라이언트라면 닫는다.
  2. 요청을 받는다. HTTP 요청 메시지를 네트워크로부터 읽어드린다.
  3. 요청을 처리한다. 요청 메시지를 해석하고 행동을 취한다.
  4. 리소스에 접근한다. 메시지에서 지정한 리소스에 접근한다.
  5. 응답을 만든다. 올바른 헤더를 포함한 HTTP 응답 메시지를 생성한다.
  6. 응답을 보낸다. 응답을 클라이언트에게 돌려준다.
  7. 트랜잭션을 로그로 남긴다. 로그 파일에 트랜잭션 완료에 대한 기록을 남긴다.

5.2 단계 1: 클라이언트 커넥션 수락

클라이언트가 이미 서버에 대해 열려있는 지속적 커넥션을 갖고 있다면, 클라이언트는 요청을 보내기 위해 그 커넥션을 사용할 수 있다.

5.2.1 새 커넥션 다루기

  • 클라이언트가 웹서버에 TCP 커넥션 요청을 하면, 웹 서버는 커넥션을 맺고 IP 주소를 추출하여 어떤 클라이언트가 있는지 확인한다.
  • 서버는 새 커넥션을 커넥션 목록에 추가하고 커넥션에서 오가는 데이터를 지켜보기 위한 준비를 한다.
  • 웹 서버는 어떤 커넥션이든 마음대로 거절하거나 즉시 닫을 수 있다.

5.2.2 클라이언트 호스트 명 식별

  • 웹 서버는 역방향 DNS를 사용해서 클라이언트의 IP 주소를 호스트명으로 변환하도록 설정되어 있다.
  • 호스트 명 룩업은 꽤 시간이 많이 걸릴 수 있어 웹 트랜잭션을 느려지게 할 수 있다.

5.2.3 ident를 통해 클라이언트 사용자 알아내기

  • ident 프로토콜은 서버에게 어떤 사용자 이름이 HTTP 커넥션을 초기화 했는지 찾아낼 수 있게 한다.
  • 웹 서버 로깅에서 유용하여, 일반 로그 포맷의 두 번째 필드는 각 HTTP 요청의 사용자 이름을 담는다.

5.3 단계 2: 요청 메시지 수신

커넥션에 데이터가 도착하면, 웹 서버는 네트워크 커넥션에서 그 데이터를 읽어 들이고 파싱하여 요청 메시지를 구성한다.

  • 요청줄을 파싱하여 요청 메서드, 지정된 리소스의 식별자, 버전 번호를 찾는다.
  • 메시지 헤더들을 읽는다. 각 메시지 헤더는 CRLF로 끝난다.
  • 헤더의 끝을 의미하는 CRLF로 끝나는 빈 줄을 찾아낸다.
  • 요청 본문이 있다면, 읽어 들인다.

5.3.1 메시지의 내부 표현

웹 서버는 요청 메시지를 쉽게 다룰 수 있도록 내부의 자료 구조에 저장한다.

5.3.2 커넥션 입력/출력 처리 아키텍쳐

  • 웹 서버는 수천 개의 커넥션을 동시에 열 수 있도록 지원한다.
  • 커넥션들은 웹 서버가 전 세계의 클라이언트들과 각각 한 개 이상의 커넥션을 통해 통신할 수 있게 해준다.
  • 웹 서버 아키텍쳐의 차이에 따라 요청을 처리하는 방식도 달라진다.

단일 스레드 웹 서버

  • 한 번에 하나씩 요청을 처리한다.
  • 트랜잭션이 완료되면, 다음 커넥션이 처리된다.
  • 처리 도중에 모든 다른 커넥션은 무시된다.

멀티프로세스와 멀티스레드 웹 서버

  • 웹 서버는 요청을 동시에 처리하기 위해 여러 개의 프로세스 혹은 고효율 스레드를 할당한다.
  • 커넥션을 처리 할 때 만들어진 수많은 프로세스나 스레드는 많은 메모리나 시스템 리소스를 소비한다.
  • 많은 멀티스레드 웹 서비스가 스레드/프로세스의 최대 개수에 제한을 건다.

다중 I/O 서버

  • 커넥션의 상태가 바뀌면, 그 커넥션에 대한 작은 양의처리가 수행된다.
  • 그 처리가 완료되면, 커넥션은 다음 상태 변경을 위해 열린 커넥션 목록으로 돌아간다.
  • 스레드와 프로세스는 유휴 상태의 커넥션에 얽혀 기다리느라 리소스를 낭비하지 않는다.

다중 멀티스레드 웹서버

  • CPU 여러 개의 이점을 살리기 위해 멀티스레딩과 다중화를 결합한다.
  • 여러 개의 스레드는 각각 열려있는 커넥션을 감시하고 각 커넥션에 대해 조금씩 작업을 수행한다.

5.4 단계 3: 요청 처리

웹 서버가 요청을 받으면, 서버는 요청으로부터 메서드, 리소스, 헤더, 본문을 얻어내어 처리한다.

5.5 단계 4: 리소스의 매핑과 접근

웹 서버는 리소스 서버다. 클라이언트가 웹 서버에 리소스를 요청하면, 웹 서버는 요청 메시지의 URI에 대응하는 알맞는 콘텐츠나 콘텐츠 생성기를 찾아서 클라이언트로 전달한다.

5.5.1 Docroot

  • 리소스 매핑을 하는데 요청 URI를 웹 서버의 파일 시스템 안에 있는 파일 이름으로 사용하는 것이 가장 쉽다.
  • 일반적으로 웹 서버 파일 시스템의 특별한 폴더를 웹 콘텐츠를 위해 예약해 둔다.
  • 이 폴더는 문서 루트 혹은 docroot로 불린다.

가상 호스팅된 docroot

  • 각 사이트에 그들만의 분리된 문서 루트를 주는 방법이다.
  • 하나의 웹 서버 위에서 두 개의 사이트가 완전히 분리된 콘텐츠를 갖고 호스팅 되도록 할 수 있다.

사용자 홈 디렉터리 docroots

  • 사용자들이 한 대의 웹 서버에서 각자의 개인 웹사이트를 만들 수 있도록 해주는 것이다.
  • 보통 사용자 이름이 오는 것으로 시작하는 URI는 그 사용자의 개인 문서 루트를 가리킨다.
  • GET /~jeus/index.html HTTP/1.0

5.5.2 디렉터리 목록

  • 웹 서버는 경로가 파일이 아닌 디렉터리 URL에 대한 요청을 받을 수 있다.
  • 사용자가 어떤 디렉터리에 대한 URL을 요청했는데, 그 디렉터리가 index.html이란 이름을 가진 파일을 갖고 있다면, 서버는 그 파일의 콘텐츠를 반환한다.
  • 웹 서버는 기본 디렉터리 파일로 사용될 파일 이름의 집합인 DirectoryIndex 지시자를 사용해서 색인 파일로 사용될 모든 파일의 이름을 우선순위로 나열한다.

5.5.3 동적 콘텐츠 리소스 매핑

  • 웹 서버는 URI를 동적 리소스에 매핑할 수 있다.
  • 애플리케이션 서버라고 불리는 것들은 웹 서버를 복잡한 백엔드 애플리케이션과 연결하는 일을 한다.

5.5.4 서버사이드 인클루드(Server-Side Includes, SSI)

  • 어떤 리소스가 서버사이드 인클루드를 포함하고 있다면, 서버는 그 리소스의 콘텐츠를 클라이언트에게 보내기 전에 처리한다.
  • 서버는 콘텐츠에 변수 이름이나 내장된 스크립트가 될 수 있는 어떤 특별한 패턴이 있는지 검사를 받는다.

5.5.5 접근제어

  • 접근제어 되는 리소스에 대한 요청이 도착했을 때 웹 서버는 클라이언트의 IP주소에 근거하여 접근을 제어할 수 있고 혹은 리소스에 접근하기 위한 비밀번호를 물어볼 수 있다.

5.6 단계 5: 응답 만들기

5.6.1 응답 엔터티

만약 트랜잭션이 응답 본문을 생성한다면, 그 내용을 응답 메시지와 함께 돌려보낸다.

  • 응답 본문의 MIME 타입을 서술하는 Content-Type 헤더
  • 응답 본문의 길이를 서술하는 Content-Length 헤더
  • 실제 응답 본문의 내용

5.6.2 MIME 타입 결정하기

mime.types

  • 웹 서버는 각 리소스의 MIME 타입을 계산하기 위해 확장자별 MIME 타입이 담겨 잇는 파일을 탐색한다.

매직 타이핑

  • 웹 서버는 각 파일의 MIME 타입을 알아내기 위해 파일의 내용을 검사해서 알려진 패턴에 대한 테이블에 해당하는 패턴이 있는지 찾아 볼 수 있다.

유형 명시

  • 특정 파일이나 디렉터리 안의 파일들이 파일 확장자나 내용에 상관없이 어떤 MIME 타입을 갖도록 웹 서버를 설정할 수 있다.

유형 협상(Type negotiation)

  • 웹 서버는 한 리소스가 여러 종류의 문서 형식에 속하도록 설정할 수 있다.

5.6.3 리다이렉션

  • 웹 서버는 요청을 수행하기 위해 브라우저가 다른 곳으로 가도록 리다이렉트 할 수 있다.
  • 리다이렉션 응답은 3XX 상태코드로 지칭된다.

영구히 리소스가 옮겨진 경우

  • 리소스는 새 URL이 부여되어 새로운 위치로 옮겨졌거나 이름이 바뀔 수 있다.
  • 웹 서버는 클라이언트에게 리소스 위치가 변경되었음을 알려준다.
  • 301 Moved Permanently 상태 코드가 사용된다.

임시로 리소스가 옮겨진 경우

  • 리소스가 임시로 옮겨지거나 이름이 변경되었지만, 서버는 클라이언트가 나중에는 원래 URL로 찾아오고 북마크도 갱신하길 원치 않는다.
  • 303 See Ohter307 Temporary Redirect 상태 코드가 사용된다.

URL 증강

  • 서버는 종종 문맥 정보를 포함ㅎ시키기 위해 재 작성된 URL로 리다이렉트한다.
  • 요청이 도착했을 때, 서버는 상태 정보를 내포한 새 URL을 생성하고 사용자를 이 새 URL로 리다이렉트한다.
  • 클라이언트는 상태정보가 추가된 완전한 URL을 포함한 요청을 다시 보낸다.
  • 303 See Ohter307 Temporary Redirect 상태 코드가 사용된다.

부하 균형

  • 서버가 과부화된 요청을 받으면, 서버는 클라이언트를 덜 부하가 걸린 서버로 리다이렉트 할 수 있다.
  • 303 See Ohter307 Temporary Redirect 상태 코드가 사용된다.

친밀한 다른 서버가 있을때

  • 서버는 클라이언트에 대한 정보를 갖고 있는 다른 서버로 리다이렉트 할 수 있다.
  • 303 See Ohter307 Temporary Redirect 상태 코드가 사용된다.

디렉터리 이름 정규화

  • 클라이언트가 디렉터리 이름에 대한 URI를 요청하는데 /을 빠뜨렸다면, 웹 서버는 /를 추가한 URI로 리다이렉트한다.

5.7 단계 6: 응답 보내기

  • 서버는 여러 클라이언트에 대한 많은 커넥션을 가질 수 있다. 서버는 커넥션 상태를 추적해야 하며 지속적인 커넥션은 특별히 주의해서 다룰 필요가 있다.
  • 비지속적인 커넥션이라면, 서버는 모든 메시지를 전송했을 때 자신쪽의 커넥션을 닫을 것이다.
  • 지속적인 커넥션이라면, 서버가 Content-length 헤더를 바르게 계산하기 위해 특별한 주의를 필요로 하는 경우나, 클라이언트가 응답이 언제 끝나는지 알 수 없는 경우에, 커넥션은 열린 상태를 유지한다.

5.8 단계 7: 로깅

트랜잭션이 완료 되었을 때 웹 서버는 트랜잭션이 어떻게 수행되었는지에 대한 로그를 로그파일에 기록한다.

HTTP 완벽가이드 4장

4장 커넥션 관리

4.1 TCP 커넥션

  • 모든 HTTP통신은 네트워크 프로토콜의 집합인 TCP/IP를 통해 이루어진다.
  • 커넥션이 맺어지면, 메시지가 손실, 손상되거나 순서가 바뀌지 않고 안전하게 전달된다.

커넥션 과정

1) 브라우저가 https://bebiangel.github.io 라는 호스트 명을 추출한다.

2) 브라우저가 호스트 명에 대한 IP 주소를 찾는다.

3) 브라우저가 포트 번호(80)를 얻는다.

4) 브라우저가 IP 주소의 80포트로 TCP 커넥션을 생성한다.

5) 브라우저가 서버로 HTTP GET 요청 메시지를 보낸다.

6) 브라우저가 서버에서 온 HTTP 응답 메시지를 읽는다.

7) 브라우저가 커넥션을 끊는다.

4.1.1 신뢰할 수 있는 데이터 전송 통로인 TCP

TCP는 HTTP에게 신뢰할만한 통신 방식을 제공한다.

4.1.2 TCP 스트림은 세그먼트로 나뉘어 IP 패킷을 통해 전송된다

TCP는 IP 패킷 이라는 작은 조각을 통해 데이터를 전송한다.

4.1.3 TCP 커넥션 유지하기

TCP커넥션은 여러 개를 가지고 있고, 포트 번호를 통해서 여러개의 커넥션을 유지한다.

<발신지 IP 주소, 발신지 포트, 수신지 IP주소, 수신지 포트> 네 가지 항목으로 커넥션을 생성하고, 서로 다른 TCP 커넥션은 일부는 같을 수 있으나 모든 항목이 같을 수는 없다.

4.2 TCP의 성능에 대한 고려

  • HTTP는 TCP 바로 위에 있는 계층이기 때문에 HTTP 트랜잭션의 성능은 TCP 성능에 영향을 받는다.
  • HTTP의 커넥션 최적화 요소들을 통해서 더 좋은 성능의 HTTP 애플리케이션을 설계하고 구현한다.

4.2.1 HTTP 트랜잭션 지연

  • 트랜잭션을 처리하는 시간은 TCP 커넥션을 설정하고, 요청을 전송하고, 응답 메시지를 보내는것에 비하면 상당히 짧다

트랜잭션을 지연시키는 원인

1) 클라이언트가 URI에 기술된 호스트에 방문한적이 없다면, DNS 이름 분석을 사용하여 호스트명을 IP 주소로 변환하는데 수십 초의 시간이 걸린다.

2) 클라이언트는 TCP 커넥션 요청을 서버에게 보내고 서버가 커넥션 허용 응답을 회신하기를 기다린다. 서버에서 수백개의 HTTP 트랜잭션이 만들어진다면 많은 소요시간이 걸린다.

3) 커넥션이 맺어지고 클라이언트는 HTTP 요청을 전송한다. 서버에서는 요청 메시지를 읽고 처리하는데 시간이 소요된다.

4) 서버에서 HTTP 응답을 보내는데 시간이 걸린다.

4.2.2 성능 관련 중요 요소

고성능의 HTTP 소프트웨어를 개발하기 위해서 알아야 할 요소들

  • TCP 커넥션의 핸드셰이크 설정
  • 인터넷의 혼잡을 제어하기 위한 TCP의 느린 시작(slow-start)
  • 데이터를 한데 모아 한 번에 전송하기 위한 네이글(nagle) 알고리즘
  • TCP의 편승 확인응답을 위한 확인응답 지연 알고리즘
  • TIME_WAIT 지연과 포트 고갈

4.2.3 TCP 커넥션 핸드셰이크 지연

  • TCP 커넥션을 열때, 커넥션을 맺기 위한 조건을 맞추기 위해 연속적으로 IP 패킷을 교환한다.
  • 작은 크기의 데이터 전송시에 커넥션을 사용한다면, HTTP 성능을 저하시킬 수 있다.

핸드셰이크 순서

1) 커넥션 생성시에 작은 TCP 패킷을 서버에게 보내는데, 커넥션 생성 요청이라는 의미를 가진SYN 플래그를 가진다.

2) 서버가 커넥션을 받으면 커넥션 매개변수를 산출하고, 커넥션 요청이 받아들여졌음을 의미하는 SYNACK 플래그를 포함한 TCP 패킷을 클라이언트에게 보낸다.

3) 클라이언트는 커넥션이 잘 맺어졌음을 서버에게 다시 확인응답 신호를 보낸다. 클라이언트는 확인응답 패킷과 데이터를 함께 보낼수 있다.

4.3 HTTP 커넥션 관리

4.3.1 흔히 잘못 이해하는 Connection 헤더

  • HTTP Connection 헤더 필드는 토큰을 쉼표로 구분하여 가지고 있으며, 다른 커넥션에 전달되지 않는다.
  • Connection 헤더에 있는 모든 헤더 필드는 메시지를 다른 곳으로 전달하는 시점에 삭제되어야한다.

4.3.2 순차적인 트랜잭션 처리에 의한 지연

  • 여러개의 리소스를 받아와야 하는 화면이 있다면, 각각의 리소스의 HTTP 트랜잭션을 만들어야한다.
  • 특정 브라우저의 경우 객체를 화면에 배치하려면 객체의 크기를 알아야 하기 때문에, 모든 객체를 내려받기 전까지는 빈 화면을 보여준다.

HTTP 커넥션의 성능을 향상시키는 기술

병렬(parallel) 커넥션

여러 개의 TCP 커넥션을 통한 동시 HTTP 요청

지속(persistent) 커넥션

커넥션을 맺고 끊는 데서 발생하는 지연을 제거하기 위한 TCP 커넥션의 재활용

파이프라인(piplined) 커넥션

공유 TCP 커넥션을 통한 병렬 HTTP 요청

다중(multiplexed) 커넥션

요청과 응답들에 대한 중재

4.4. 병렬 커넥션

  • 브라우저가 HTML 페이지를 보여주는데 필요한 리소스를 순서대로 받는다면 너무 느리다.
  • HTTP는 클라이언트가 여러 개의 커넥션을 맺음으로써 여러 개의 HTTP 트랜잭션을 병렬로 처리할 수 있게 한다.

4.4.1 병렬 커넥션은 페이지를 더 빠르게 내려받는다

  • 커넥션의 대역폭 제한과 커넥션이 동작하지 않고 있는 시간을 활용하면, 객체가 여러개 있는 웹페이지를 더 빠르게 내려받을수 있을 것이다.
  • 각 커넥션의 지연 시간을 겹치게 하면 총 지연 시간을 줄일 수 있다.
  • 인터넷 대역폭을 한 개의 커넥션이 다 써버리지 않고, 나머지 객체를 내려받는 데에 남은 대역폭을 사용한다.

4.4.2 병렬 커넥션이 항상 더 빠르지는 않다

  • 클라이언트의 네트워크 대역폭이 좁을 때는 대부분 시간을 데이터 전송하는 데만 쓸 것이다.
  • 제한된 대역폭 내에서 각 객체를 전송받는 것은 느리기 때문에 성능상의 장점이 사라진다.
  • 서버는 다른 여러 사용자의 요청도 함께 처리해야 하기 때문에 수백 개의 커넥션을 허용하는 경우는 드물다.

4.5 지속 커넥션

  • 클라이언트가 같은 사이트에 여러 개의 커넥션을 맺는 속성을 지역성(site locality)라 한다.
  • HTTP/1.1을 지원하는 기기는 처리가 완료된 후에도 TCP 커넥션을 유지하여 앞으로 있을 HTTP 요청에 재사용이 가능하다.
  • 처리가 완료된 후에도 계속 연결된 상태로 있는 TCP 커넥션을 지속 커넥션이라고 부른다.

4.5.1 지속 커넥션 vs 병렬 커넥션

병렬 커넥션 단점

  • 각 트랜잭션마다 새로운 커넥션을 맺고 끊기 때문에 시간과 대역폭이 소요된다.
  • 각각의 새로운 커넥션은 TCP 느린 시작 때문에 성능이 떨어진다.
  • 실제로 연결할 수 잇는 병렬 커넥션의 수에는 제한이 있다.

지속 커넥션 장점

  • 커넥션을 맺기 위한 사전 작업과 지연을 줄여주고, 커넥션의 수를 줄여준다.

지속 커넥션 단점

  • 지속 커넥션을 잘못 관리할 경우, 계속 연결된 상태로 잇는 수많은 커넥션이 쌓인다.
  • 로컬의 리소스 그리고 원격의 클라이언트와 서버의 리소스에 불필요한 소모를 발생한다.

지속 커넥션은 병렬 커넥션과 함께 사용될 때에 가장 효과적이다.

4.5.2 HTTP/1.0+의 Keep-Alive 커넥션

  • 커넥션을 맺고 끊는 데 필요한 작업이 없어서 시간이 단축된다.
  • keep-alive가 HTTP/1.1 명세에서는 빠졌지만, 아직 널리 사용되고 있어서 HTTP 애플리케이션은 그것을 처리할 수 있게 개발해야 한다.
  • keep-alive 헤더 사용은 선택 사항이지만, Connection:Keep-Alive 헤더가 있을 때만 사용 할 수 있다.

4.6 파이프라인 커넥션

  • 지속 커넥션을 통한 파이프라이닝은 keep-alive 커넥션의 성능을 높여준다.

파이프라인의 제약조건

  • HTTP 클라이언트는 커넥션이 지속 커넥션인지 확인하기 전까지는 파이프라인을 이어서는 안된다.
  • HTTP 응답은 요청 순서와 같게 와야한다.
  • HTTP 클라이언트는 커넥션이 언제 끊어지더라도, 완료되지 않은 요청이 파이프라인에 있으면 언제든 다시 요청을 보낼 준비가 되어 있어야 한다.
  • HTTP 클라이언트는 POST 요청같이 반복해서 보낼 경우 문제가 생기는 요청은 파이프라인으로 보내면 안된다.

4.7 커넥션 끊기에 대한 미스터리

  • 커넥션 관리(언제 어떻게 끊기는지)는 명확한 기준이 없다.
  • HTTP 클라이언트, 서버 혹은 프락시든 언제든지 TCP 전송 커넥션을 끊을 수 있다.
  • 커넥션이 에러가 없더라도 언제든 끊을 수 있다.

HTTP 완벽가이드 3장

3장 HTTP 메시지

3.1 메시지의 흐름

3.1.1. 메시지는 원 서버 방향을 인바운드로 하여 송신된다.

  • 메시지가 원 서버로 향하는 것을 인바운드로 이동하는 것이다.
  • 모든처리가 끝난 뒤에 사용자 에이전트로 돌아오는 것은 아웃바운드로 이동하는 것이다.

3.1.2 다운스트림으로 흐르는 메시지

  • HTTP 메시지는 강물과 같이 흐른다.
  • 요청이나 응답 상관없이 메시지는 다운스트림으로 흐른다.

3.2 메시지의 각 부분

HTTP 메시지는 시작줄, 헤더, 본문으로 구성된 구조화된 블록이다.

시작줄은 어떤 메시인지 서술하고, 헤더는 속성, 본문은 데이터를 담고 있으며, 본문은 존재하지 않을 수 있다.

3.2.1 메시지 문법

요청메시지 형식

<메서드> <요청URL> <버전>
<헤더>

<엔터티 본문>

응답메시지 형식

<버전> <상태 코드> <사유 구절>
<헤더>

<엔터티 본문>

메서드

  • 클라이언트가 서버에 리소스 요청 시에 서버가 수행하길 원하는 동작이다.

요청URL

  • 리소스를 지칭하는 완전한 URL 혹은 URL의 경로 구성요소다.
  • 완전하지 않은 URL이라고 하더라도, 클라이언트와 서버와 직접 대화를 하면서 리소스를 가리키는 절대 경로이기만 하면, 문제가 없다.

버전

  • 사용중인 HTTP의 버전이다.
  • HTTP/<메이저>.<마이너> 로 구성된다.

상태 코드

  • 요청 중에 무엇이 일어났는지 설명하는 세 자리의 숫자다.
  • 각 코드의 첫 번째 자릿수는 상태의 일반적인 분류를 나타낸다.

사유 구절(reason-phrase)

  • 숫자로 구성된 상태 코드를 사람이 이해 가능하도록 나타내는 짧은 문구이다.

헤더들

  • 이름 : 공백 or 값 형태의 순서대로 0개 이상 나타난다.

엔터티 본문

  • 임의의 데이터 블록을 포함하지만, 모든 메시지가 엔터티 본문을 갖지 않는다.
  • 널리 쓰이는 규칙이나 지키지 않는 구현체와의 호환을 위해, 클라이언트와 서버는 마지막 CRLF(빈줄) 없이 끝나는 메시지도 받아들일 수 있도록 해야 한다.

3.2.2. 시작줄

요청줄

  • 서버에게 리소스에 대해 무언가를 해달라고 요청한다.
  • 요청 URL, 어떤 동작을 해야하는지에 대한 메서드, HTTP버전을 포함한다.

응답줄

  • 수행 결과에 대한 상태 정보결과 데이터를 클라이언트에게 돌려준다.
  • HTTP버전, 숫자로 된 상태 코드, 수행 상태에 대해 설명해주는 사유구절을 포함한다.

메서드

  • 요청의 시작줄은 메서드로 시작하며, 서버가 무엇을 해야하는지 말해준다.
메서드 설명 본문이 있는가?
GET 서버에서 어떤 문서를 가져온다. 없음
HEAD 서버에서 어떤 문서에 대해 헤더만 가져온다. 없음
POST 서버가 처리해야 할 데이터를 보낸다. 있음
PUT 서버에 요청 메시지의 본문을 저장한다. 있음
TRACE 메시지가 프락시를 거쳐 서버에 도달하는 과정을 추적한다. 없음
OPTIONS 서버가 어떤 메서드를 수행할 수 있는지 확인한다. 없음
DELETE 서버에서 문서를 제거한다. 없음

상태코드

  • 응답의 시작줄에 위치하며, 클라이언트에게 무엇이 일어났는지 말해준다.
  • 현재 버전의 HTTP는 적은 수의 코드만 정의되어 있다.
전체 범위 정의된 범위 분류
100-199 100-101 정보
200-299 200-206 성공
300-399 300-305 리다이렉션
400-499 400-405 클라이언트 에러
500-599 500-505 서버 에러

사유 구절

  • 응답 시작줄의 마지막 구성요소로, 상태 코드에 대한 글로 된 설명을 제공한다.
  • HTTP 명세는 사유 구절이 어떻게 구성되어야 하는지에 대한 엄격한 규칙이 존재하지 않는다.

버전 번호

  • HTTP/x.y 형식으로 요청과 응답 메시지에 모두 존재한다.
  • HTTP로 대화하는 애플리케이션들에게 대화 상대의 능력과 메시지의 형식에 대한 단서를 제공해주기 위한것이다.

3.2.3 헤더

  • HTTP 헤더는 여러 헤더 필드를 정의한다.

  • 애플리케이션은 자유롭게 자신만의 헤더를 만들 수 있다.

    HTTP/1.0 200 OK
    Content-Type: image/gif
    Content-Length: 8572
    Server: Test Server

    Version 1.0

3.2.4 엔터티 본문

  • HTTP 메시지의 구성 요소 중 선택적으로 HTTP가 수송하도록 설계된 화물이라고 할 수 있다.
  • 이미지, 비디오, HTML문서, 소프트웨어 애플리케이션, 전자우편 등 여러 종류의 디지털 데이터를 실어 나른다.

3.3 메서드

  • 모든 서버가 모든 메서드를 구현하지는 않는다.

3.3.1 안전한 메서드

  • GET, HEAD 는 안전한 메서드로 HTTP 요청 후에 서버에서 어떠한 자원의 변경이 일어나지 않는다.

3.3.2 GET

  • 가장 흔히 사용되는 메서드로 서버에게 리소스를 달라고 요청시에 사용된다.

3.3.3 HEAD

  • GET처럼 행동하지만, 서버는 응답으로 헤더만을 돌려준다.
  • 리소스를 가져오지 않고도 그에 대해 무엇인가를 알아 낼 수 있다.
  • 응답의 상태 코드를 통해, 개체가 존재하는지 확인 할 수 있다.
  • 헤더를 확인하여 리소스가 변경되었는지 검사할 수 있다.

3.3.4 PUT

  • 서버가 요청의 본문을 가지고 요청 URL의 이름대로 새 문서를 만들거나, 이미 URL이 존재한다면 본문을 사용해서 교체하는 것이다.

3.3.5 POST

  • 서버에 입력 데이터를 전송하기 위해 설계되었다.
  • HTML 폼을 지원하며, 담긴 데이터는 서버로 전송된다.

3.3.6 TRACE

  • 클라이언트에게 자신의 요청이 서버에 도달했을 때 어떻게 보이게 되는지 알려준다.
  • 클라이언트는 자신과 목적지 서버 사이에 있는 모든 HTTP 애플리케이션의 요청/응답 연쇄를 따라가면서 자신이 보낸 메시지가 망가졌거나 수정되었는지, 만약 그렇다면 어떻게 변경되었는지 확인할 수 있다.

3.3.7 OPTIONS

  • 웹 서버에게 여러 가지 종류의 지원 범위에 대해 물어본다.
  • 리소스에 대해 실제로 접근하지 않고도 어떻게 접근하는 것이 최선인지 확인할 수 있는 수단을 클라이언트 애플리케이션에게 제공한다.

3.3.8 DELETE

  • 서버에게 요청 URL로 지정한 리소스를 삭제할 것을 요청한다.

3.4 상태 코드

3.4.1 100-199: 정보성 상태 코드

  • HTTP/1.1에서 도입되었다.

3.4.2 200-299: 성공 상태 코드

  • 클라이언트가 요청을 보내고, 요청이 성공한다.
  • 서버는 성공을 의미하는 상태 코드의 배열을 갖고 있으며, 각각의 요청에 대응한다.

3.4.3 300-399: 리다이렉션 상태 코드

  • 클라이언트가 관심있어 하는 리소스에 대해 다른 위치를 사용하라고 말해주거나 그 리소스의 내용 대신 다른 대안 응답을 제공한다.

3.4.4 400-499: 클라이언트 에러 상태 코드

  • 클라이언트가 서버에게 알 수 없는 요청을 보냈을때 나타난다.

3.4.5 500-599: 서버 에러 상태 코드

  • 클라이언트가 올바른 요청을 보냈음에도 서버 자체에서 에러가 발생하는 경우다.

3.5 헤더

3.5.1 일반 헤더

  • 클라이언트와 서버 양쪽 모두가 사용하고 메시지에 대한 아주 기본적인 정보를 제공한다.
  • ex)Date: Tue, 3 Oct 1974 02:16:00 GMT

일반 캐시 헤더

HTTP 애플리케이션에게 매번 원 서버로부터 객체를 가져오는 대신, 로컬 복사본으로 캐시할 수 있도록 해준다.

3.5.2 요청 헤더

  • 요청 메시지에서만 의미를 갖는다.
  • 요청이 최초 발생한 곳에서 누가 혹은 무엇이 그 요철을 보냈는지에 대한 정보나 클라이언트의 선호나 능력에 대한 정보를 제공한다.
  • ex)Accept: */*

3.5.3 응답 헤더

  • 응답 메시지는 그들만의 응답 헤더를 갖는다.
  • 누가 응답을 보내고 있는지, 응답자의 능력은 어떻게 되는지 알려주면, 응답에 대한 특별한 설명도 제공할 수 있다.
  • ex)Server: Tiki-Hut/1.0

3.5.4 엔터티 헤더

  • 요청과 응답 양 타입의 메시지에 모두 나타날 수 있다.
  • 개체의 타입부터 주어진 리소스에 대해 요청할 수 있는 유효한 메서드들까지, 광범위한 정보를 제공한다.
  • ex)Content-Type: texthtml; charset=iso-latin-1

3.5.5 확장 헤더

  • 애플리케이션 개발자들에 의해 만들어졌지만 HTTP 명세에는 추가되지 않은 비표준 헤더다.
Your browser is out-of-date!

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

×