책 “HTTP 완벽 가이드”를 읽고 정리한 글입니다.
웹 서버란?
웹 서버는 HTTP(또는 HTTPS)를 사용하여 웹 페이지(또는 파일)를 웹 브라우저에 전달하는 소프트웨어 프로그램이다.
하드웨어적인 측면에서 웹 서버는 파일을 저장하고 소프트웨어를 동작시키는 컴퓨터를 일컫기도 한다.
웹 서버의 형태
웹 서버는 다음의 형태로 사용할 수 있다.
- 범용 소프트웨어 웹 서버 (general-purpose software web servers)
- 웹 서버 어플라이언스 (web server appliance)
- 임베디드 웹 서버 (embedded web servers)
범용 소프트웨어 웹 서버
- 개념
- 네트워크가 가능한 컴퓨터에서 일반적으로 구동하는 방식이다.
- 사용하는 소프트웨어의 종류
- 오픈 소스 소프트웨어 - Apache, W3C의 Jigsaw 등
- 상업용 소프트웨어 - Microosft나 iPlanet의 웹 서버
순위 웹 서버 비율 1 nginx 26.11% 2 Apache 20.63% 3 Cloudflare 9.91% 4 OpenResty 8.15%
웹 서버 어플라이언스
- 개념
- 사전에 구성된 상태의 소프트웨어/하드웨어 솔루션
- 판매자가 선택한 컴퓨터 플랫폼과 설정에 소프트웨어 서버를 설치해두고 판매하는 방식
- 사전에 구성된 상태의 소프트웨어/하드웨어 솔루션
- 장점
- 사용자가 직접 소프트웨어를 설치하고 설정을 하는 등의 번거로움을 줄여준다.
- 단점
- 유연성이 떨어지고 기능이 풍부하지 않은 편이다.
- 하드웨어의 용도를 변경하거나 업그레이드하기가 어렵다.
- 예시
임베디드 웹 서버
- 개념
- 소비자 상품에 내장되도록 만든 웹 서버
- 장점
- 웹 브라우저 인터페이스를 사용하여 쉽게 소비자의 기기를 관리할 수 있다.
- 예시
- IPic의 초소형 웹 서버
- NetMedia SitePlayer SP1 이더넷 웹 서버
웹 서버 구현
다음의 펄(Perl) 스크립트를 사용하면 간단한 웹 서버를 만들 수 있다. 단순화 된 이 웹 서버는 HTTP/1.1이 지원하는 다양한 기능을 사용할 수는 없다. 이 서버는 주로 클라이언트와 프록시 간의 상호작용을 테스트하는 용도로 사용된다. perl type-o-serve.pl
로 프로그램을 실행하고 브라우저로 127.0.0.1:8080
에 접근하면, 다음과 같은 HTTP 요청 메시지를 받을 수 있다.
이 상태에서 다음과 같이 HTTP 응답 메시지를 전송하면,
브라우저에서 아래와 같은 메시지를 받을 수 있다.
웹 서버의 역할
웹 서버는 다음의 역할을 수행한다.
- 클라이언트 커넥션 수락
- 요청 메시지 수신
- 요청 처리
- 리소스 매핑과 접근
- 응답 생성
- 응답 전송
- 트랜잭션 로그 기록
클라이언트 커넥션 수락
기존에 클라이언트와의 커넥션이 존재한다면 해당 커넥션을 사용하고, 존재하지 않는다면 새로운 커넥션을 생성해야한다.
웹 서버는 클라이언트(IP 주소/호스트명)가 인가되었는지를 확인한 후 커넥션을 생성한다.
생성 과정에서 역방향 DNS(reverse DNS)를 사용하여 클라이언트의 IP 주소를 호스트명으로 변환한다. 이 정보는 추후에 접근 제어와 로깅에 사용될 수 있다.
요청 메시지 수신
웹 서버는 수신한 데이터로 요청 메시지를 구성한다.
- 메시지 구성 과정
- 요청줄을 파싱하여 요청 메서드, URI, 버전 정보를 알아낸다.
- 메시지 헤더를 읽는다.
- 헤더의 마지막 줄(CRLF로 끝나는 빈 줄)을 찾을 때까지 읽는다.
- 요청 본문을 읽는다.(존재하는 경우에만)
메시지의 저장
이러한 데이터 수신 과정에서 서버는 메시지를 메모리에 임시적으로 저장해두며 읽어간다.
일부 웹 서버는 요청 메시지를 내부 자료구조에 저장하기도 한다.
요청 처리
웹 서버는 요청에서 메서드, 리소스, 헤더, 본문을 파싱하여 처리한다.
리소스의 매핑과 접근
클라이언트에게 콘텐츠를 제공하기 위해, 웹 서버는 요청 메시지의 URI에 해당하는 콘텐츠를 찾아내야 한다.
이 과정에서 사용하는 방법이 리소스 매핑이다.
- 리소스 매핑(Resource mapping) : 웹에서 URI를 사용해 리소스를 식별하고 위치시키는 것
Docroot (Document root)
가장 단순한 리소스 매핑 방식으로, 요청 URI를 웹 서버의 파일 이름으로 사용하는 것이다.
가령 다음과 같은 요청 메시지가 들어왔다고 하자.
1
2
GET /specials/saw-blade.gif HTTP/1.0
Host: www.joes-hardware.com
웹 서버의 docroot이 /usr/local/httpd/files
라고 할 때, 서버는 클라이언트에게 /usr/local/httpd/files/specials/saw-blade.gif
를 반환하게 된다.
경로가 디렉터리인 경우
경로가 파일이 아닌 디렉터리로 들어온 경우, 웹 서버는 다음의 동작 중 하나를 취한다.
- 에러 반환
- 색인 파일(index.html)을 반환
- 디렉터리 목록을 담은 HTML 페이지 반환
응답 생성
웹 서버는 요청 메서드에 해당하는 동작을 한 뒤에 응답 메시지를 반환한다.
응답 메시지는 다음을 포함한다.
- 응답 메시지
- 응답 상태 코드
- 응답 헤더
- 응답 본문
MIME 타입 결정
웹 서버는 응답 본문의 MIME 타입을 명시해야 하는데, 이 과정에서 다음과 같은 방법을 사용한다.
- mime.types
- 파일의 확장자를 보고 타입을 알아내는 방식
- 매직 타이핑(magic typing)
- 파일 내용을 검사해서 타입을 알아내는 방식
- 파일 내용의 패턴을 매직 파일(테이블)과 비교해서 찾는다.
- 유형 명시(explicit typing)
- 파일과 무관하게 웹 서버 자체적으로 타입을 설정하는 방식
- 유형 협상(type negotiation)
- 한 리소스에 대해 여러 형식을 설정한 뒤, 사용자와 협상을 통해 타입을 결정하는 방식
리다이렉션(redirection)
- 요청을 수행하기 위해 브라우저를 다른 곳으로 보내는 것
- 300번대의 상태 코드를 사용한다.
- Location 응답 헤더에 콘텐츠의 위치(URI)를 반환한다.
응답 전송
응답을 클라이언트에게 보낼 때는 클라이언트의 상태에 유의해야 한다.
또한 커넥션의 상태를 파악해야 하는데, 이 부분은 커넥션의 지속 여부에 따라 달라진다.
- 비지속적인 경우
- 서버가 모든 메시지를 전송한 뒤에 자신의 커넥션을 닫는다.
- 이 과정에서 서버는 클라이언트에게
Connection: close
헤더를 포함하여 전송한다.
- 지속적인 경우
- 서버가 응답을 보낸 후에도 커넥션은 계속해서 열려있다.
- 서버는 클라이언트에게
Connection: keep-alive
헤더를 포함하여 보낸다.
로깅
서버는 트랜잭션 완료 후, 해당 트랜잭션이 어떻게 이루어졌는지에 대한 로그 파일을 기록한다.