이 프로젝트는 42 코어 커리큘럼의 일부로 완료되었습니다. Alouane04로 수행되었습니다
이 프로젝트의 목표는 C ++ 98 호환 HTTP 웹 서버를 처음부터 구축하는 것입니다. 웹 서버는 HTTP Get, Head, Post, Put 및 Delete 요청을 처리 할 수 있으며 CGI를 사용하여 지정된 루트 디렉토리 또는 동적 컨텐츠에서 정적 파일을 제공 할 수 있습니다. 또한 select ()의 도움으로 여러 클라이언트 연결을 동시에 처리 할 수 있습니다.
용법
소개
웹 서버의 일부
make
./webserv [Config File] # # leave empty to use the default configuration.HTTP (HyperText Transfer Protocol)는 인터넷을 통해 정보를 보내고받는 프로토콜입니다. 월드 와이드 웹의 기초이며 웹 브라우저와 웹 서버에서 서로 통신하기 위해 사용됩니다.
HTTP 웹 서버는 클라이언트 (예 : 웹 브라우저)의 HTTP 요청을 듣고 응답하는 소프트웨어 응용 프로그램입니다. 웹 서버의 주요 목적은 웹 컨텐츠를 호스팅하여 인터넷을 통해 사용자가 사용할 수 있도록하는 것입니다.
HTTP는 요청 및 응답으로 구성됩니다. 클라이언트 (예 : 웹 브라우저)가 서버에서 웹 페이지를 검색하려는 경우 서버에 HTTP 요청을 보냅니다. 그런 다음 서버는 요청을 처리하고 HTTP 응답을 다시 보냅니다.
HTTP 메시지 형식
start-line CRLF
Headers CRLF
CRLF(end of headers)
[message-body]
CRLF are Carriage Return and Line Feed (rn), which is just a new line.
HTTP 메시지는 요청 또는 응답 일 수 있습니다.
HTTP 요청
HTTP 요청은 요청 행, 헤더 및 선택적 메시지 본문으로 구성됩니다. 다음은 HTTP 요청의 예입니다.
GET /index.html HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
요청 행은 메소드, 경로 및 HTTP 버전의 세 부분으로 구성됩니다. 이 메소드는 클라이언트가 수행하려는 조치 (리소스 검색) 또는 게시물 (서버에 데이터 제출)과 같이 수행하려는 작업을 지정합니다. 경로 또는 URI는 서버의 리소스 위치를 지정합니다. HTTP 버전은 사용중인 HTTP 프로토콜의 버전을 나타냅니다.
헤더에는 서버의 호스트 이름 및 사용중인 브라우저 유형과 같은 요청에 대한 추가 정보가 포함되어 있습니다.
위의 예에는 Get 메소드에 일반적으로 신체가 포함되지 않기 때문에 메시지 본문이 없었습니다.
HTTP 응답
HTTP 응답은 또한 상태 라인, 헤더 및 선택적 메시지 본문으로 구성됩니다. 다음은 HTTP 응답의 예입니다.
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234
<Message Body>
상태 라인은 HTTP 버전, 상태 코드 및 이유 문구의 세 부분으로 구성됩니다. 상태 코드는 200 OK (성공) 또는 404를 찾을 수 없음 (찾을 수없는 리소스)과 같은 요청의 결과를 나타냅니다. 그 이유는 상태 코드에 대한 간단한 설명입니다. 다음은 상태 코드가 무엇을 나타내는 지에 대한 간단한 요약입니다.
1xx 정보 메시지 만 나타냅니다
2xx 어떤 종류의 성공을 나타냅니다
3xx 클라이언트를 다른 URL로 리디렉션합니다
4xx 클라이언트 측면의 오류를 나타냅니다
5xx 서버 부분의 오류를 나타냅니다
헤더에는 반환되는 컨텐츠의 유형 및 크기와 같은 응답에 대한 추가 정보가 포함되어 있습니다. 메시지 본문에는 웹 페이지의 HTML 코드와 같은 응답의 실제 내용이 포함되어 있습니다.
HTTP 방법
| 방법 | 설명 | 가능한 몸 |
|---|---|---|
GET | 특정 리소스 또는 리소스 모음을 검색하면 데이터/리소스에 영향을 미치지 않아야합니다. | 아니요 |
POST | 요청 컨텐츠에서 리소스 별 처리를 수행하십시오 | 예 |
DELETE | URI가 제공하는 대상 리소스를 제거합니다 | 예 |
PUT | 메시지 본문의 데이터로 새로운 리소스를 작성합니다. 자원이 이미 존재하는 경우 본문의 데이터로 업데이트하십시오. | 예 |
HEAD | get과 동일하지만 응답 내용을 전송하지 마십시오. | 아니요 |
얻다
HTTP get 메소드는 리소스의 표현을 읽거나 검색하는 데 사용됩니다. 성공 (또는 비 방향)의 경우, GET GET는 응답 본문에서 리소스의 표현을 반환하고 200 (OK)의 HTTP 응답 상태 코드를 반환합니다. 오류 경우에는 대부분 404 (찾을 수 없음) 또는 400 (불량 요청)을 반환합니다.
우편
HTTP Post 방법은 가장 자주 새로운 리소스를 만드는 데 사용됩니다. 성공적인 생성시 HTTP Response Code 201 (생성)가 반환됩니다.
삭제
HTTP Delete는 Stright Forword입니다. URI에 지정된 리소스를 삭제합니다. 성공적인 삭제에서는 HTTP 응답 상태 코드 204 (콘텐츠 없음)를 반환합니다.
HTTP 방법에 대해 자세히 알아보십시오. RFC9110#9.1
기본 HTTP 웹 서버는 클라이언트로부터 HTTP 요청을 받고 처리하고 응답을 보내기 위해 함께 작동하는 여러 구성 요소로 구성됩니다. 아래는 웹 서버의 주요 부분입니다.
TCP 연결을 처리하고 들어오는 요청 듣기 및 응답 보내기 등의 작업을 수행하는 웹 서버의 네트워킹 부분. 소켓 생성 및 관리, 입력 및 출력 스트림 처리, 서버 및 클라이언트 간 데이터 흐름 관리와 같은 웹 서버의 저수준 네트워킹 작업을 담당합니다.
웹 서버를 작성하기 전에 C/C ++에서 TCP가 어떻게 작동하는지 잘 이해하는 데 도움이되는 C에서 간단한 TCP 클라이언트/서버를 구축하는 것에 대한이 멋진 안내서를 읽는 것이 좋습니다. 또한 I/O 곱셈을 이해해야합니다.이 비디오는 select ()의 주요 아이디어를 파악하는 데 도움이됩니다.
웹 서버의 I/O 멀티플렉싱 프로세스는 아래 흐름도에 요약되어 있습니다. (CGI는 흐름도에 포함되어 있지 않지만 향후 추가 될 수 있습니다)
웹 서버의 구문 분석 부분은 HTTP 요청에서 정보를 해석하고 추출하는 프로세스를 나타냅니다. 이 웹 서버에서 요청의 구문 분석은 httprequest 클래스에서 수행됩니다. Httprequest 객체는 들어오는 요청을 받고,이를 구문 분석하고, 방법, 경로, 헤더 및 메시지 본문과 같은 관련 정보를 추출합니다 (현재). 구문 분석 중 요청에서 구문 오류가 발견되면 오류 플래그가 설정되고 구문 분석 중지가 중지됩니다. 요청은 메소드 피드 ()를 완전히 또는 부분적으로 통해 객체에 공급할 수 있으므로, 파서가 한 번에 요청 바이트를 스캔하고 필요할 때마다 구문 분석 상태를 업데이트하기 때문에 가능합니다. Nginx와 Nodejs 요청 파서에서 동일한 구문 분석을 사용합니다.
아래는 파서의 작동 방식에 대한 개요입니다.
응답 빌더는 요청에 응답하여 클라이언트에게 다시 전송되는 HTTP 응답을 구성하고 서식하는 일을 담당합니다. 이 웹 서버에서 응답 클래스는 상태 라인, 헤더 및 메시지 본문을 포함하여 HTTP 응답을 구축하고 저장하는 일을 담당합니다. 응답 빌더는 요청의 결과를 기반으로 적절한 상태 코드 및 이유 문구를 설정하고 응답에 헤더를 추가하여 컨텐츠 또는 서버에 대한 추가 정보를 제공하고 컨텐츠 유형 및 응답의 인코딩에 따라 메시지 본문을 형식화하는 것과 같은 작업을 수행 할 수도 있습니다. 예를 들어, 서버가 클라이언트로부터 웹 페이지 요청을 수신하는 경우 서버는 요청을 구문 분석하고 웹 페이지의 내용을 가져오고 메시지 본문의 HTML 컨텐츠와 컨텐츠 유형 및 콘텐츠 길이 헤더와 같은 적절한 헤더로 HTTP 응답을 구성하는 응답 객체로 전달합니다.
구성 파일은 웹 서버 작동 방식을 지시하는 다양한 설정 및 지시문이 포함 된 텍스트 파일입니다. 이러한 설정에는 웹 서버가 듣는 포트 번호, 웹 서버 루트 디렉토리의 위치 및 기타 여러 설정이 포함될 수 있습니다.
다음은 구성 파일 형식 및 지원되는 지침을 보여주는 예제입니다.
server {
listen 8001 ; # listening port, mandatory parameter
host 127.0.0.1; # host or 127.0.0.1 by default
server_name test; # specify server_name, need to be added into /etc/hosts to work
error_page 404 /error/404.html; # default error page
client_max_body_size 1024 ; # max request body size in bytes
root docs/fusion_web/; # root folder of site directory, full or relative path, mandatory parameter
index index.html; # default page when requesting a directory, index.html by default
location /tours {
root docs/fusion_web; # root folder of the location, if not specified, taken from the server.
# EX: - URI /tours --> docs/fusion_web/tours
# - URI /tours/page.html --> docs/fusion_web/tours/page.html
autoindex on ; # turn on/off directory listing
allow_methods POST GET; # allowed methods in location, GET only by default
index index.html; # default page when requesting a directory, copies root index by default
return abc/index1.html; # redirection
alias docs/fusion_web; # replaces location part of URI.
# EX: - URI /tours --> docs/fusion_web
# - URI /tours/page.html --> docs/fusion_web/page.html
}
location cgi-bin {
root ./; # cgi-bin location, mandatory parameter
cgi_path /usr/bin/python3 /bin/bash; # location of interpreters installed on the current system, mandatory parameter
cgi_ext .py .sh; # extensions for executable files, mandatory parameter
}
}CGI는 웹 서버에서 외부 프로그램을 실행하는 표준입니다. 사용자가 CGI 프로그램에서 처리 해야하는 웹 페이지를 요청하면 웹 서버가 프로그램을 실행하고 출력을 사용자의 웹 브라우저로 반환합니다.
CGI 프로그램은 Perl, Python 또는 Bash와 같은 모든 프로그래밍 언어로 작성할 수있는 스크립트이며 일반적으로 웹 브라우저를 통해 사용자가 제출 한 데이터를 처리하거나 웹 페이지에서 동적 콘텐츠를 생성하는 데 사용됩니다.