5.3 진짜 웹 서버가 하는 일

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

5.4 단계 1. 클라이언트 커넥션 수락

  • 새 커넥션 다루기
    • 클라이언트가 웹 서버에 TCP 커넥션을 요청하면, 웹 서버는 커넥션을 맺고 TCP 커넥션에서 IP 주소를 추출하여 커넥션 맞은편에 어떤 클라이언트가 있는지 확인
    • 서버는 새 커넥션을 커넥션 목록에 추가하고, 커넥션에서 오고 가는 데이터를 지켜보기 위한 준비를 한다.
    • 웹 서버는 인가되지 않은 클라이언트나 악의적인 경우 커넥션을 닫을 수 있다.
  • 클라이언트 호스트명 식별
    • 역방향 DNS를 사용하여 클라이언트의 IP 주소를 클라이언트의 호스트 명으로 변환하도록 설정
    • 웹 서버는 클라이언트 호스트 명을 구체적인 접근 제어와 로깅을 위해 사용할 수 있다.
    • 호스트 명 룩업(hostname lookup)은 꽤 시간이 많이 걸릴 수 있어서 웹 트랜잭션을 느려지게 할 수 있다.
      HostnameLookups off
      <Files ~ "\.(html|htm|cgi)$">
          HostnameLookups on
      </Files>
      
  • ident를 통해 클라이언트 사용자 알아내기
    • IETF ident 프로토콜을 지원
    • ident 프로토콜은 서버에게 어떤 사용자 이름이 HTTP 커넥션을 초기화했는지 알 수 있게 해준다.
    • ident 프로토콜 과정
      • 메리는 새 HTTP 커넥션을 맺는다.
      • 서버는 ident 커넥션을 맺는다
      • 서버는 요청을 보낸다 (TCP 113포트 listen)
      • 클라이언트는 ident 응답을 반환한다 (4236,80:USERID:UNIX:MARY)

5.5 단계 2. 요청 메시지 수신

  • 커넥션에 데이터가 도착하면, 웹 서버는 네트워크 커넥션에서 그 데이터를 읽어 파싱하고 요청 메시지를 구성한다.
  • 요청 메시지 파싱
    • 요청줄을 파싱하여 요청 메서드, URI, HTTP 버전을 찾는다. 각 값은 스페이스 한개로 분리되어 있으며, 요청줄은 캐리지 리턴 줄바꿈(CRLF) 문자열로 끝난다.
    • 메시지 헤더들을 읽는다. 각 메시지 헤더는 CRLF로 끝난다.
    • 헤더의 끝을 의미하는 CRLF로 끝나는 빈 줄을 찾아낸다.
    • 요청 본문이 있다면 읽어 들인다.(길이는 Content-Length 헤더로 정의)
  • 메시지의 내부 표현
    • 자료구조의 저장
    • 예를 들어, 자료구조는 요청 메시지의 각 조각에 대한 포인터와 길이를 담을 수 있을 것이고, 헤더는 속도가 빠른 룩업 테이블에 저장
  • 커넥션 입/출력 처리 아키텍처
    • 고성능 웹 서버는 수천 개의 커넥션을 동시에 열 수 있도록 지원한다.
    • 이 커넥션들은 웹 서버가 전 세계의 클라이언트들과 각각 한 개 이상의 커넥션을 통해 통신할 수 있게 해준다.
    • 웹 서버 아키텍처의 종류(아키텍처마다 요청을 처리하는 방식도 다르다)
      • 단일 스레드 웹 서버
      • 멀티프로세스와 멀티스레드 웹 서버
      • 다중 I/O 서버
      • 다중 멀티스레드 웹 서버

5.6 단계 3. 요청 처리

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

5.7 단계 4. 리소스의 매핑과 접근

  • Docroot
    • 요청 URI를 웹 서버의 파일 시스템 안에 있는 파일 이름으로 사용하는 것이다.
    • 일반적으로 웹 서버 파일 시스템의 특별한 폴더를 웹 콘텐츠를 위해 예약해 둔다. 이른 docroot라 부른다.
    • 웹 서버는 URI를 가져와서 문서 루트 뒤에 붙인다.
    • 아파치 웹 서버의 문서 루트 설정
      DocumentRoot /usr/local/httpd/files
      
  • 가상 호스팅된 docroot
    • 가상 호스팅 웹 서버는 각 사이트에 그들만의 분리된 문서 루트를 주는 방법으로 한 웹서버에서 여러 개의 웹 사이트를 호스팅한다.
    • 아파치 웹 서버 가상 호스트 docroot 설정
      <VirtualHost www.joes-hardware.com>
        ServerName www.joes-hardware.com
        DocumentRoot /docs/joe
        TransferLog /logs/joe.access_log
        ErrorLog /logs/joe.error_log
      </VirtualHost>
      <VirtualHost www.marys-antiques.com>
        ServerName www.marys-antiques.com
        DocumentRoot /docs/mary
        TransferLog /logs/mary.access_log
        ErrorLog /logs/mary.error_log
      </VirtualHost>
      
      • 요청 메시지 A: /docs/joe/index.html 파일을 가져온다.
        GET /index.html HTTP/1.0
        Host: www.joes-hardware.com
        
      • 요청 메시지 B: /docs/mary/index.html 파일을 가져온다.
        GET /index.html HTTP/1.0
        Host: www.marys-antiques.com
        
  • 사용자 홈 디렉터리 docroots
    • docroot의 또 다른 대표적인 활용은, 사용자들이 한 대의 웹 서버에 여러 웹 사이트를 만들수 있도록 해준다.
    • 보통 빗금(/)과 물결표(~) 다음에 사용자 이름이 오는 것으로 시작하는 URI는 그 사용자의 개인 문서 루트를 가리킨다.
  • 디렉터리 목록
    • 웹 서버는 경로가 파일이 아닌 디렉터리를 가리키는 디렉터리 URL에 대한 요청을 받을 수 있다.
    • 해당 요청에 대해 다음과 같은 행동을 취하도록 설정할 수 있다.
      • 에러 반환
      • 디렉터리 대신 특별한 ‘색인 파일(index.html)’ 반환
      • 디렉터리를 탐색해서 그 내용을 담은 HTML 페이지 반환
    • 아파치 웹 서버에서 DirectoryIndex 설정 지시자를 사용해서 파일 이름의 집합을 설정할 수 있다.
      DirectoryIndex index.html index.htmhome.html home.htm index.cgi
      
    • 아파치 지시자로 디렉터리 색인 파일 자동 생성을 끌 수 있다.
      Options -Indexes
      
  • 동적 콘텐츠 리소스 매핑
    • 웹 서버는 URI를 동적 리소스에 매핑할 수 있다.
    • 어떤 리소스가 동적 리소스라면, WAS는 그에 대한 동적 콘텐츠 생성 프로그램이 어디에 있는지, 그리고 어떻게 그 프로그램을 실행하는 지 알려줄 수 있어야 한다.
    • URI의 경로가 /cgi-bin/ 으로 시작한다면, /usr/local/etc/httpd/cgi-programs/에서 프로그램을 찾아 실행하라는 의미
      ScriptAlias /cgi-bin/ /usr/local/etc/httpd/cgi-programs/\
      
    • .cgi로 끝나는 모든 웹 리소스는 실행되어야 함을 명시
      AddHandler cgi-script .cgi
      
  • 서버사이드 인클로두(Server-Side Includes, SSI)

  • 접근 제어

5.8 단계 5. 응답 만들기

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

  • 응답 엔터티
    • 응답 본문의 MIME 타입을 서술하는 Content-Type 헤더
    • 응답 본문의 길이를 서술하는 Content-Length 헤더
    • 실제 응답 본문의 내용
  • MIME 타입 결정
    • mime.types
      • 웹 서버는 MIME 타입을 나타내기 위해 파일 이름의 확장자를 사용할 수 있다.
    • 매직 타이핑
      • 아파치는 각 파일의 MIME 타입을 알아내기 위해 파일의 내용을 검사해서 알려진 패턴에 대한 테이블에 핻ㅇ하는 패턴이 있는지 찾는다.
      • 느리지만 파일이 표준 확장자 없이 이름 지어진 경우에 편리하다.
    • 유형 명시
      • 특정 파일이나 디렉터리 안의 파일들이 파일 확장자나 내용에 상관없이 어떤 MIME 타입을 갖도록 웹 서버를 설정할 수 있다.
    • 유형 협상
      • 한 리소스가 여러 종류의 문서 형식에 속하도록 설정할 수 있다.
      • 웹 서버가 사용자와의 협상 과정을 통해 사용하기 가장 좋은 형식을 판별할 것인지의 여부도 설정할 수 있다.
  • 리다이렉션
    • 웹 서버는 요청을 수행하기 위해 브라우저가 다른 곳으로 가도록 리다이렉트 할 수 있다.
    • 리다이렉션 응답은 3xx 상태코드로 지칭된다.
    • Location 응답 헤더는 콘텐츠의 새로운 혹은 선호하는 위치에 대한 URI를 포함한다.

    • 영구히 리소스가 옮겨진 경우
      • 클라이언트에게 리소스의 이름이 바뀌었으므로, 클라이어느는 북마크를 갱신할 수 있다고 말해줄 수 있다.
      • 301 Moved Permanently 상태 코드를 사용한다.
    • 임시로 리소스가 옮겨진 경우
      • 위치가 옮겨졌거나 이름이 임시로 변경된 경우 서버는 클라이언트를 새 위치로 리다이렉트하길 원할 것이다.
      • 303 See Other와 307 Temporary Redirect 상태 코드를 사용한다.
    • URL 증강
      • 문맥 정보를 포함하기 위해 재 작성된 URL로 리다이렉트를 한다.
      • 요청이 도착하면 서버는 상태 정보를 내포한 새 URL을 생성하고 사용자를 이 새 URL로 리다이렉트한다.
      • 클라이언트는 상태 정보가 포함된 완전한 URL을 포함한 요청을 다시 한다.
      • 303 See Other와 307 Temporary Redirect 상태 코드를 사용한다.
    • 부하 균형
      • 과부하된 서버가 요청을 받으면, 서버는 클라이언트에를 좀 덜 부하가 걸린 서버로 리다이렉트 할 수 있다.
      • 303 See Other와 307 Temporary Redirect 상태 코드를 사용한다.
    • 친밀한 다른 서버가 있을 때
      • 웹 서버는 어떤 사용자에 대한 정보를 가질 수 있고, 서버는 클라이언트를
      • 그 클라이언트에 대한 정보를 갖고 있는 다른 서버로 리다이렉트 할 수 있다.
      • 303 See Other와 307 Temporary Redirect 상태 코드를 사용한다.
    • 디렉터리 이름 정규화
      • 클라이언트가 디렉터리 이름에 대한 URI 요청을 하는데 빗금(/) 을 빠트렸다면, 웹 서버는 이것이 잘 작동하도록 추가한 URI로 리다이렉트 한다.

5.9 단계6. 응답 보내기

  • 웹 서버는 요청들 받을 때와 마찬가지로 커넥션 너머로 데이터를 보낼 때도 비슷한 이슈에 직면한다.
  • 서버는 커넥션 상태를 추적해야 하며 지속적인 커넥션은 특별히 주의해서 다뤄야한다.
  • 비지속적인 커넥션이라면, 서버는 모든 메시지를 전송하고 자신의 커넥션을 닫는다.
  • 지속적인 커넥션이라면, 서버가 Content-Length 헤더를 바르게 계산하기 위해 특별한 주의를 필요로 하는 경우나, 클라이언트가 응답이 언제 끝나는지 알 수 없는 경우에 커넥션은 열린 상태를 유지할 것이다.

5.10 단계7. 로깅

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

** 참고 서적: HTTP 완벽 가이드