HTTP 완벽 가이드 2-5. 웹 서버


📘 HTTP 완벽 가이드 읽고 정리하기 🐿︎



웹 서버


  • 웹 서버는 HTTP 요청을 처리하고 응답을 제공

  • 웹 서버 소프트웨어와 웹페이지 제공에 특화된 장비(ex)컴퓨터) 양쪽 모두를 가리킴

  • 기능, 형태, 크기가 다양하지만, 모든 웹 서버는 리소스에 대한 HTTP 요청을 받아서 콘텐츠를 클라이언트에게 돌려줌

  • 웹 서버는 HTTP 및 그와 관련된 TCP 처리를 구현한 것

  • HTTP 프로토콜 구현, 웹 리소스 관리, 웹 서버 관리 기능 제공

  • 웹 서버는 TCP 커넥션 관리에 대한 책임을 운영체제와 나눠 가짐

    • 운영체제는 컴퓨터 시스템의 하드웨어 관리, TCP/IP 네트워크 지원, 웹 리소스를 유지하기 위한 파일 시스템 현재 연산 활동을 제어하기 위한 프로세스 관리를 제공


다목적 소프트웨어 웹 서버


  • 네트워크에 연결된 표준 컴퓨터 시스템에서 동작

  • 오픈 소스 소프트웨어(ex) 아파치, W3C의 직소)를 사용 할 수도, 상용 소프트웨어(ex) 마이크로소프트, 아이플래닛)를 사용할 수도 있음

  • 웹 서버 소프트웨어는 거의 모든 컴퓨터와 운영체제에서 동작


임베디드 웹 서버


  • 일반 소비자용 제품에 내장될 목적으로 만들어진 작은 웹 서버 (ex) 프린터, 가전제품)

  • 사용자가 그들의 일반 소비자용 기기를 간편한 웹 브라우저 인터페이스로 관리할 수 있게 해줌



웹 서버의 수행 단계


  1. 커넥션을 맺는다 : 클라이언트의 접속을 받아들이거나, 원치 않는 클라이언트라면 닫는다

  2. 요청을 받는다 : HTTP 요청 메시지를 네트워크로부터 읽어 들인다

  3. 요청을 처리한다 : 요청 메시지를 해석하고 행동을 취한다

  4. 리소스에 접근한다 : 메시지에서 지정한 리소스에 접근한다

  5. 응답을 만든다 : 올바른 헤더를 포함한 HTTP 응답 메시지를 생성한다

  6. 응답을 보낸다 : 응답을 클라이언트에게 돌려준다

  7. 트랜잭션을 로그에 남긴다 : 로그파일에 트랜잭션 완료에 대한 기록을 남긴다


👉 각 단계에 대해 자세히 알아보자 🧐


1) 클라이언트 커넥션 수락


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

  • 클라이언트가 웹 서버에 TCP 커넥션을 요청 → 웹 서버는 그 커넥션을 맺고 TCP 커넥션에서 IP 주소를 추출, 커넥션 맞은펀에 어떤 클라이언트가 있는지 확인 → 새 커넥션이 맺어지고 받아들여지면, 서버는 새 커넥션을 커넥션 목록에 추가하고 커넥션에서 오가는 데이터를 지켜보기 위한 준비를 함

  • 웹 서버는 어떤 커넥션이든 마음대로 거절하거나 즉시 닫을 수 있음 (ex) 클라이언트의 IP 주소나 호스트 명이 인가되지 않았거나 악의적이라고 알려진 것인 경우)

  • 대부분의 웹 서버는 역방향 DNS(reverse DNS)를 사용해 클라이언트의 IP 주소를 클라이언트의 호스트 명으로 변환하도록 설정되어 있음

  • 웹 서버는 클라이언트 호스트 명을 구체적인 접근 제어와 로깅을 위해 사용할 수 있음

  • 몇몇 웹 서버가 지원하는 IETF ident 프로토콜은 서버에게 어떤 사용자 이름이 HTTP 커넥션을 초기화했는지 찾아낼 수 있게 해줌

  • 클라이언트가 ident 프로토콜을 지원한다면, 클라이언트는 ident 결과를 위해 TCP 포트 113번을 listen

  • 방화벽이 ident 트래픽이 들어오는 것을 막는 경우가 많고, 가상 IP 주소를 잘 지원하지 않으며, 클라이언트 사용자 이름의 노출로 인한 프라이버시 침해의 우려 등 여러 이유로 ident는 조직 내부에서는 잘 사용할 수 있지만, 공공 인터넷에서는 잘 동작하지 않음


2) 요청 메시지 수신


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

  • 요청 메시지를 파싱할 떄, 웹 서버는 입력 데이터를 네트워크로부터 불규칙적으로 받으며, 네트워크 커넥션은 언제라도 무효화될 수 있음

  • 요청 메시지를 파싱할 때, 웹 서버는

    • 요청줄을 파싱하여 요청 메서드, 지정된 리소스의 식별자(URI), 버전 번호를 찾음, 각 값음 스페이스 한 개로 분리되어 있으며, 요청줄은 캐리지 리턴 줄바꿈(CRLF) 문자열로 끝남

    • 메시지 헤더들을 읽음, 각 메시지 헤더는 CRLF로 끝남

    • (존재한다면) 헤더의 끝을 의미하는 CRLF로 끝나는 빈 줄을 찾아냄

    • 요청 본문이 있다면, 읽어들인다 (길이는 Content-Length 헤더로 정의됨)

  • 고성능 웹 서버는 수천 개의 커넥션을 동시에 열 수 있도록 지원하며, 이 커넥션들은 웹 서버가 전 세계의 클라이언트들과 각각 한 개 이상의 커넥션을 통해 통신할 수 있게 해줌

  • 웹 서버 아키텍처의 차이에 따라 요청을 처리하는 방식도 달라짐

    • 단일 스레드 웹 서버

      • 한 번에 하나씩 요청을 처리, 트랜잭션이 완료되면 다음 커넥션이 처리됨

      • 구현하기 간단한 아키텍처이지만, 처리 도중에 모든 다른 커넥션은 무시되고, 이는 심각한 성능 문제를 만들어내기 때문에 로드가 적은 서버나 type-o-serve와 같은 진단도구에서만 적당

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

      • 여러 요청을 동시에 처리하기 위해 여러 개의 프로세스 혹은 고효율 스레드를 할당

      • 스레드/프로세스는 필요할 때마다 만들어질 수도, 미리 민들어질 수도 있음

      • 서버가 수천, 수만 개의 동시 커넥션을 처리할 때 그로 인해 만들어진 수많은 프로세스나 스레드는 너무 많은 메모리나 시스템 리소스를 소비하기 때문에, 많은 멀티스레드 웹 서비스는 스레드/프로세스의 최대 개수에 제한을 걺

    • 다중 I/O 서버

      • 대량의 커넥션을 지원하기 위해 많은 웹 서버는 다중 아키텍처를 채택

      • 커넥션의 상태가 바뀌면 그 커넥션에 대해 작은 양의 처리가 수행됨 -> 처리 완료 후, 다음번 상태 변경을 위해 열린 커넥션 목록으로 돌아감

    • 다중 멀티스레드 웹 서버

      • 자신의 컴퓨터 플랫폼에 올라와 있는 CPU 여러 개의 이점을 살리기 위해 멀티스레딩과 다중화를 결합


3) 요청 처리


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


4) 리소스의 매핑과 접근


  • 웹 서버 = 리소스 서버 : HTML 페이지나 JPEG 이미지 같은 미리 만들어진 콘텐츠를 제공, 서버 위에서 동작하는 리소스 생성 애플리케이션을 통해 만들어진 동적 콘텐츠도 제공

  • 클라이언트에 콘텐츠를 전달하기 위해서는 그 전에 요청 메시지의 URI에 대응하는 알맞은 콘텐츠나 콘텐츠 생성기를 웹 서버에서 찾아 그 콘텐츠의 원천을 식별해야 함

  • Docroot

    • docroot(문서루트) : 리소스 매핑의 가장 단순한 형태는 요청 URI를 웹 서버의 파일 시스템 안에 있는 파일 이름으로 사용하는데, 일반적으로 웹 서버 파일 시스템의 특별한 폴더를 웹 콘텐츠를 위해 예약해둠. 이 폴더를 문서루트 혹은 docroot로 부름

    • 웹 서버는 요청 메시지에서 URI를 가져와 문서 루트 뒤에 붙임

    • 가상 호스팅된 docroot : 가상 호스팅 웹 서버는 URI나 Host 헤더에서 얻은 IP 주소나 호스트 명을 이용해 올바른 문서 루트를 식별하는데, 이 방법으로 하나의 웹 서버 위에서 두 개의 사이트가 완전히 분리된 콘텐츠를 갖고 호스팅 되도록 할 수 있음

    • 사용자 홈 디렉터리 docroots : docroot의 대표적인 활용으로, 사용자들이 한 대의 웹 서버에서 각자의 개인 웹 사이트를 만들 수 있도록 해주는 것인데, 보통 빗금(/)과 물결표(~) 다음에 사용자 이름이 오는 것으로 시작하는 URI는 그 사용자의 개인 문서 루트를 가리킴

  • 디렉터리 목록

    • 웹 서버는 경로가 파일이 아닌 디렉터리를 가리키는 디렉터리 URL에 대한 요청을 받을 수 있음

    • 대부분의 웹 서버에서 클라이언트가 디렉터리 URL을 요청했을 때 취하도록 설정하는 행동

      • 에러 반환

      • 디렉터리 대신 특별한 ‘색인 파일’ 반환

      • 디렉터리를 탐색 해 그 내용을 담은 HTML 페이지 반환

  • 동적 콘텐츠 리소스 매핑

    • 웹 서버는 요청에 맞게 콘텐츠럴 생성하는 프로그램에 URI를 매핑할 수도 있음 (대부분의 웹 서버는 동적 리소스를 식별하고 매핑할 수 있는 매커니즘을 갖고 있음)

    • 아파치는 URI 경로명이 실행 가능한 프로그램이 위치한 디렉터리로 매핑되도록 설정하는 기능을 제공하며, 특정 확장자의 파일만 실행하도록 설정할 수도 있음

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

    • 만약 어떤 리소스가 서버사이드 인클루드를 포함하고 있는 것으로 설정돼 있다면, 서버는 그 리소스의 콘텐츠를 클라이언트에게 보내기 전에 처리
  • 접근제어

    • 접근 제어되는 리소스에 대한 요청이 도착하면 웹 서버는 클라이언트의 IP 주소에 근거하여 접근을 제어하거나 비밀번호를 물을 수 있음


5) 응답 만들기


  • 한번 서버가 리소스를 식별하면 서버는 요청 메서드로 서술되는 동작을 수행한 뒤 응답 메시지(상태코드 + 헤더 (+ 본문))를 반환

  • 응답 엔터티

    • 만약 트랜잭션이 응답 본문을 생성한다면 그 내용을 응답 메시지와 함꼐 돌려보내는데, 본문이 있을 경우 응답메시지가 주로 포함하는 것

      • 응답 본문의 MIME 타입을 서술하는 Content-Type 헤더

      • 응답 본문의 길이를 서술하는 Content-Length 헤더

      • 실제 응답 본문의 내용

  • MIME 타입 결정

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

    • 매직 타이핑 : 아파치 웹 서버는 각 파일의 MIME 타입을 알아내기 위해 파일의 내용을 검사, 알려진 패턴에 대한 테이블(매직 파일)에 해당하는 패턴이 있는지 찾아봄, 느리지만 파일이 표준 확장자 없이 이름지어진 경우 편리

    • 유형 명시(Explicit typing) : 특정 파일이나 디렉터리 안의 파일들이 파일 확장자나 내용에 상관없이 어떤 MIME 타입을 갖도록 웹 서버를 설정할 수 있음

    • 유형 협상(Type negotiation) : 한 리소스가 여러 종류의 문서 형식에 속하도록 설정할 수 있는데, 이 때 웹 서버가 사용자와의 협상 과정을 통해 사용하기 가장 좋은 형식을 판별할것인지 여부도 설정할 수 있음, 또한 특정 파일이 특정 MIME 타입을 갖게끔 설정할 수도 있음

  • 리다이렉션

    • 웹 서버는 종종 성공 메시지 대신 리다이렉션 응답을 반환 (3XX 상태코드)

    • 리다이렉트가 유용한 경우

      • 리소스에 새 URL이 부여되어 새로운 위치로 옮겨졌거나 이름이 바뀐 경우, 301 Moved Permanently 상태 코드

      • 리소스가 임시로 옮겨지거나 이름이 변경된 경우, 303 See Other / 307 Temporary Redirect 상태 코드

      • 문맥 정보를 포함시키기 위해 재 작성된 URL로 리다이렉트 하는 경우, 트랜잭션 간 상태를 유지하는 유용한 방법, 303 See Other / 307 Temporary Redirect 상태 코드

      • 클라이언트를 그 클라이언트에 대한 정보를 갖고 있는 다른 서버로 리다이렉트하는 경우, 303 See Other / 307 Temporary Redirect 상태 코드

      • 디렉터리 이름 정규화, 클라이언트가 디렉터리 이름에 대한 URI를 요청할 때 끝에 ‘/’를 빼먹은 경우, 웹 서버는 상대경로가 정상적으로 동작할 수 있도록 슬래시를 추가한 URI로 리다이렉트


6) 응답 보내기


  • 서버는 커넥션 상태를 추적해야 하며 지속적인 커넥션은 특별해 주의해서 다뤄야 함

  • 비지속적인 커넥션이라면 서버는 모든 메시지를 전송했을 때 자신쪽의 커넥션을 닫음


5) 로깅


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

Categories:

HTTP