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 명세에는 추가되지 않은 비표준 헤더다.

HTTP 완벽가이드 2장

2장 URL과 리소스

2.1 인터넷의 리소스 탐색하기

URL은 브라우저가 정보를 찾는데 필요한 리소스의 위치를 가리킨다.

ex) http://www.joes-hardware.com/seasonal/index-fall.html 이라는 URL 을 불러온다고 하자.

  • http는 URL의 스킴으로 웹 클라이언트가 리소스에 어떻게 접근하는지 알려준다.
  • www.joes-hardware.com은 서버 위치로 웹 클라이언트가 리소스가 어디에 호스팅 되어 있는지 알려준다.
  • /seasonal/index-fall.html은 리소스의 경로로 서버에 존재하는 로컬 리소스들 중에서 요청받은 리소스가 무엇인지 알려준다.

URL을 사용하면 리소스를 일관된 방식으로 지칭할 수 있으며, 대부분의 URL은 “스킴://서버위치/경로“ 구조로 이루어져있다.

2.2 URL 문법

대부분의 URL은 일반 URL 문법을 따르며, 서로 다른 URL 스킴도 형태와 문법 면에서 매우 유사하다.

스킴의 문법은 일반적으로 9개로 나뉜다.

<스킴>://<사용자 이름>:<비밀번호>@<호스트>:<포트>/<경로>;<파라미터>?<질의>#<프래그먼트>

2.2.1 스킴: 사용할 프로토콜

스킴은 주어진 리소스에 어떻게 접근하는지 알려주는 중요한 정보로, 어떤 프로토콜을 사용하여 리소스를 요청해야하는지 알려준다.

2.2.2 호스트와 포트

URL의 호스트와 포트 컴포넌트가 존재한다.

  • 호스트 컴포넌트: 접근하려고 하는 리소스를 가지고 있는 인터넷상의 호스트 장비를 가리킨다.
  • 포트 컴포넌트: 서버가 열어놓은 네트워크 포트를 가리킨다.

2.2.3 사용자 이름과 비밀번호

많은 서버가 자신이 가지고 있는 데이터를 제공하기 전에 사용자 이름과 비밀번호를 요구한다.

ftp://ftp.prep.ai.mit.edu/pub/gnu

→ 표준 스킴, 호스트, 경로만 존재한다.

ftp://anonymous@ftp.prep.ai.mit.edu/pub/gnu

→ 기본 사용자 이름 값은 ‘anonymous’, 비밀번호는 브라우저마다 가지고 있는 기본값을 사용한다.

ftp://anonymous:my_passwd@ftp.prep.ai.mit.edu/pub/gnu

→ 사용자 이름 ‘anonymous’ 비밀본호 ‘my_passwd’를 ‘:’문자로 구분하여 사용한다.

‘@’는 URL에서 사용자 이름과 비밀번호 컴포넌트를 분리한다.

2.2.4 경로

URL의 경로 컴포넌트는 리소스가 서버의 어디에 있는지 알려준다.

http://www.joes-hardware.com:80/seasonal/index-fall.html

/‘ 문자를 기준으로 경로조각으로 나뉘며, 각각의 경로조각은 자체만의 파라미터 컴포넌트를 가질 수 있다.

2.2.5 파라미터

애플리케이션이 서버에 정확한 요청을 하기 위해 필요한 입력 파라미터를 받는데 사용한다.

URL의 파라미터 컴포넌트는 이름=값 쌍의 리스트로 URL 나머지로 부터 ‘;’ 문자로 구분하여 URL에 기술한다.

리소스에 접근하는데 필요한 어떤 추가 정보든 전달할 수 있다.

ftp://prep.ai.mit.edu/pub/gnu;type=d

이름은 ‘type’이고, 값은 ‘d’인 type=d라는 단 한 개의 파라미터를 전달한다.

2.2.6 질의 문자열

데이터베이스 같은 서비스들은 요청받을 리소스 형식의 범위를 좁히기 위해서 질문이나 질의를 받을 수 있다.

http://www.joes-hardware.com/inventory-check.cgi?item=12731

위 URL은 아이템 번호가 ‘12731’의 재고가 있는지 확인하기 위해서 사용된다.

‘?’ 문자에 이어서 오는 값을 질의 컴포넌트라고 한다.

‘&’문자로 나뉜 ‘이름=값‘ 쌍 형식의 질의 문자열을 많이 사용한다.

2.2.7 프래그먼트

리소스의 특정 부분을 가리킬 수 있도록, URL은 리소스 내의 조각을 가리킬 수 있는 프래그먼트 컴포넌트를 제공한다. 프래그먼트는 URL의 오른쪽에 # 문자에 이어서 온다.

http://www.joes-hardware.com/tools.html#drills

drills라는 프래그먼트는 /tools.html 웹페이지의 일부를 가리킨다.

HTTP서버는 객체 일부가 아닌 전체만 다루기 때문에, 클라이언트는 서버에 프래그먼트를 보내지 않는다.

브라우저가 서버로부터 리소스를 내려받은 후에 프래그먼트를 사용해서 보고자 하는 리소스의 화면을 보여준다.

2.3 단축 URL

웹 클라이언트는 몇몇 단축 URL을 인식하고 사용한다.

상대 URL은 리소스 안에 있는 리소스를 간결하게 기술하는데 사용할 수 있다.

2.3.1. 상대 URL

URL은 상대 URL과 절대 URL 두가지로 나뉜다.

상대 URL

  • 리소스에 접근하는데 필요한 모든 정보를 가지고 있지 않다.
  • URL을 짥게 표시하는 방식이다.
  • HTML 작성자는 URL에 스킴과 호스트 그리고 다른 컴포넌트들을 모두 입력하지 않아도 된다.

절대 URL

  • 리소스에 접근하는데 필요한 모든 정보를 가지고 있다.

URL 확장

사용자가 URL을 입력한 다음이나 입력하고 있는 동안에 자동으로 URL을 확장한다.

  • 호스트 명 확장

    ‘yahoo’를 주소창에 입력한다면, 브라우저는 호스트 명에 자동으로 ‘www.’과 ‘.com’을 붙여서 ‘www.yahoo.com'을 만든다.

  • 히스토리 확장

    URL 입력하는 시간을 줄이고자, 과거에 사용자가 방문했던 URL의 기록을 저장해 놓는 것이다.

    URL의 시작부분을 입력하면 자동으로 전체 URL을 보여준다.

2.4 안전하지 않은 문자

  • 프로토콜이 데이터를 전송하기 위해서 서로 다른 장치를 가지고 있기 때문에, 어떤 인터넷 프로토콜을 통해서든 안전하게 전송될 수 있도록 URL을 설계하는 것이 중요하다.
  • 안전한 전송이란, 정보가 유실될 위험 없이 URL을 전송할 수 있다는 것을 의미한다.
  • 이스케이프라는 기능을 추가하여, URL에 있는 안전하지 않는 문자들을 표현할 수 있도록 인코딩 방식을 사용하여 이동성과 완성도를 높였다.

HTTP 완벽가이드 1장

1장 HTTP개관

1.1 HTTP: 인터넷의 멀티미디어 배달부

HTTP는 신뢰성 있는 데이터 전송 프로토콜을 사용하기 때문에, 데이터가 지구 반대편에서 오더라도 전송 중 손상되거나 꼬이지 않음을 보장한다.

1.2 웹 클라이언트와 서버

웹 서버는 HTTP 프로토콜로 의사소통하기 때문에 HTTP서버라고 불린다. 웹 서버는 인터넷의 데이터를 저장하고, HTTP 클라이언트가 요청한 데이터를 제공한다 .

1.3 리소스

웹 서버는 웹 리소스를 관리하고 제공한다. 웹 리소스는 텍스트, 이미지 파일 등과 같은 정적 파일과 리소스는 웹에 콘텐츠를 제공하는 어떤 종류든 해당한다.

1.3.1 미디어 타입

HTTP는 웹에서 전송되는 객체 각각에 MIME라는 타입의 라벨을 붙인다. 웹브라우저는 서버로부터 객체를 돌려 받을 때, 다룰 수 있는 객체인지 MIME를 통해서 확인한다.

주 타입/부 타입으로 이루어진 문자열 라벨이다.

  • text/html → HTML로 작성된 텍스트 문서
  • text/plain → plain ASCII 텍스트 문서
  • image/jpeg →JPEG 이미지

등 수백 가지가 존재한다.

1.3.2 URI

통합 자원 식별자(Uniform Resource Identifier)

웹 서버 리소스는 각자 이름을 갖고 있기 때문에 정보 리소스를 고유하게 식별하고 위치를 지정할 수 있다.

URI에는 URL과 URN 두가지가 존재한다.

1.3.3 URL

통합 자원 지시자(Uniform Resource Locator)는 리소스 식별자의 가장 흔한 형태로, 특정 서버의 한 리소스에 대해 구체적인 위치를 서술한다.

대부분의 URL은 세부분으로 이루어진 표준 포맷을 따른다.

  • 첫번째 부분은 스킴(scheme)으로 리소스에 접근하기 위한 프로토콜을 서술한다. HTTP 프로토콜(http://)이 이에 해당한다.
  • 두번째 부분은 서버의 인터넷 주소를 제공한다. (www.joes-hardware.com)
  • 세번째 부분은 웹 서버의 리소스를 가리킨다.(/image.gif)

오늘날 대부분의 URI는 URL이다.

1.3.4 URN

유니폼 리소스 이름(Uniform Resource Name)

리소스의 위치에 영향을 받지 않으며, 리소스가 그 이름을 변하지 않게 유지하는 한, 여러종류의 네트워크 접속 프로토콜로 접근해도 문제가 되지 않는다.

1.4. 트랜잭션

요청명령(클라이언트 → 서버)과 응답결과(서버 → 클라이언트)로 구성되어있다.

1.4.1 메서드

HTTP는 여러가지 종류의 요청 명령을 지원한다.

HTTP요청 메시지는 한 개의 메서드를 갖으며, 서버에게 어떤 동작을 해야하는지 알려준다.

GET : 서버에서 클라이언트로 지정한 리소스로 보내라.

PUT : 클라이언트에서 서버로 보낸 데이터를 지정한 이름의 리소스로 저장하라.

DELETE : 저장한 리소스를 서버에서 삭제하라.

POST : 클라이언트 데이터를 서버 게이트웨이 애플리케이션으로 보내라.

HEAD : 지정한 리소스에 대한 응답에서 HTTP헤더 부분만 보내라.

1.4.2 상태코드

모든 응답 메시지는 상태 코드와 함께 반환된다.

숫자 코드 + 사유구절(reason phrase)로 함께 보낸다.

ex) 200 OK , 404 Request Error….

1.5 메시지

시작줄(Start Line)

메시지의 첫 줄로, 요청이라면 무엇을 해야 하는지 응답이라면 무슨 일이 일어났는지 나타낸다.

헤더(Header)

0개 이상의 헤더 필드가 나타난다. [이름] : [값] 형태로 구성된다.

헤더에 필드를 추가하기 위해서는 한 줄만 추가하면 된다.

본문(Body)

요청 본문은 웹 서버로 데이터를 포함해서 보내며, 응답 본문은 클라이언트로 데이터를 반환한다.

본문은 이진 데이터를 포함할 수 있다.(이미지, 비디오, 오디오, 등)

1.6 TCP 커넥션

메시지가 어떻게 TCP 커넥션을 통하는지 알아본다.

1.6.1 TCP/IP

HTTP는 애플리케이션 계층 프로토콜이다. HTTP는 네트워크 통신의 핵심적인 세부사항에 대해서는 신경쓰지 않지만 대중적이고 신뢰적인 인터넷 전송 프로토콜인 TCP/IP에게 맡긴다.

TCP특징

  • 오류 없는 데이터 전송
  • 순서에 맞는 전달(데이터는 언제나 보낸 순서대로 도착한다)
  • 조각나지 않는 데이터 스트림(언제든 어떤 크기로든 보낼 수 있다)

TCP/IP는 패킷 교환 네트워크 프로토콜의 집합이다.

어떤 종류의 컴퓨터나 네트워크든 서로 신뢰성 있는 의사소통을 하게 해준다.

TCP커넥션이 맺어지면, 클라이언트와 서버간에 교환되는 메시지가 없어지거나, 손상되거나, 순서가 뒤바뀌어 수신되는 일은 없다.

1.6.2 접속, IP주소 그리고 포트번호

HTTP 클라이언트가 서버에 메시지를 전송하기 전에 인터넷 프로토콜 주소포트번호를 사용해 클라이언트와 서버사이에 TCP 커넥션을 맺어야한다.

서버에서 클라이언트에게 HTML리소스를 보여주는 과정은 다음과 같다.

  1. 웹브라우저는 서버의 URL에서 호스트 명을 추출한다.
  2. 웹브라우저는 서버의 호스트 명을 IP로 변환한다.
  3. 웹브라우저는 URL에서 포트번호를 추출한다.
  4. 웹브라우저는 웹 서버와 TCP 커넥션을 맺는다.
  5. 웹브라우저는 서버에 HTTP 요청을 보낸다.
  6. 서버는 웹브라우저에 HTTP 응답을 돌려준다.
  7. 커넥션이 닫히면, 웹브라우저는 문서를 보여준다.

1.7 웹의 구성요소

1.7.1 프락시(Proxy)

웹 보안, 애플리케이션 통합, 성능 최적화를 위한 중요한 구성 요소로서, 프락시는 클라이언트와 서버 사이에 위치하여, 클라이언트의 모든 HTTP요청을 받아 서버에 전달한다.

주로 보안을 위해서 많이 사용된다. 모든 웹 트래픽 흐름 속에서 신뢰할 만한 중개자 역할을 한다.

1.7.2 캐시(Cache)

웹 캐시와 캐시 프락시는 자신을 거쳐 가는 문서들 중 자주 찾는 것의 사본을 저장해 둔다.

클라이언트는 멀리 떨어진 웹 서버보다 근처의 캐시에서 문서를 빠르게 다운 받을 수 있다.

1.7.3 게이트웨이(Gateway)

다른 서버들의 중개자로 동작하는 특별한 서버로서, HTTP 트래픽을 다른 프로토콜로 변환하기 위해 사용된다.

스스로가 리소스를 갖고 있는 진짜 서버인 것처럼 요청을 다룬다. 클라이언트는 자신이 게이트웨이와 통신하고 있음을 알아채지 못한다.

1.7.4 터널

두 커넥션 사이에서 raw데이터를 열어보지 않고 그대로 전달해주는 HTTP 애플리케이션이다.

터널은 주로 비 HTTP 데이터를 하나 이상의 HTTP 연결을 통해 그대로 전송해주기 위해 사용된다.

1.7.5 에이전트

사용자를 위해 HTTP 요청을 만들어주는 클라이언트 프로그램이다.

Your browser is out-of-date!

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

×