- HTTP 1.1 프로토콜 지원
- Nginx 설정 파일과 호환
- Kqueue를 통한 I/O Multiplexing
- 정적 파일, CGI 요청 처리
웹서버의 동작을 정의하는 Nginx 설정 파일 파싱 모듈을 담당했습니다.
server/location블록 등 중첩 구조 구문 분석include지시어를 통한 모듈화된 설정 파일 구문 분석- 파싱된 설정을 기반으로 웹서버가 동작할 수 있도록 계층적 클래스 구조 설계
- 문법 오류 탐지 및 상세 예외 메세지 처리 기능 구현
http, server, location 블록의 내부의 지시어들은 대부분 유사하지만 블록에 따라 지원하는 지시어나 문법이 달라져 세세한 부분이 달라져야만 했습니다. 이를 고려하며 코드의 재사용성과 확장성을 고려하는 것에 신경을 썼습니다.
해결 방법
- 추상클래스
AConfig를 기반으로 하는 계층적 클래스 구조를 설계했습니다. - 상속을 통해 각 블록에 맞는 공통 로직과 개별 로직을 분리하여 유지보수성을 향상시켰습니다.
classDiagram
AConfig <|-- WebservConfig
AConfig <|-- EventConfig
AConfig <|-- HttpConfig
AConfig <|-- ServerConfig
AConfig <|-- LocationConfig
AHttpConfigCore <|-- LocationConfig
AHttpConfigCore <|-- ServerConfig
AHttpConfigCore <|-- HttpConfig
%% WebservConfig o-- EventConfig : event
%% WebservConfig o-- HttpConfig : http
%% HttpConfig o-- ServerConfig : servers
%% ServerConfig o-- LocationConfig : locations
class AConfig {
<<abstract>>
+ initDirectives()
}
class AHttpConfigCore {
<<abstract>>
+ timeouts : Timeout
+ root
+ errorPages
}
class WebservConfig {
+ event : EventConfig
+ http : HttpConfig
}
class EventConfig {
+ workerConnections
}
class HttpConfig {
+ servers : ServerConfig[]
}
class ServerConfig {
+ names
+ ports
+ locations : LocationConfig[][]
}
class LocationConfig {
+ pattern
+ alias
+ proxyPass
+ cgiPath
}
관련 코드
중첩 구조와 모듈화된 설정 파일을 설정 클래스에 저장하기 위해 생성자 내부에서 다른 블록 개체를 재귀적으로 생성해야 했습니다. 이 과정에서 발생하는 문법, 구조 오류, 중복 선언 등 다양한 예외를 적절한 시점에 감지하고 명확하게 에러 메세지로 전달해 웹서버가 오작동하지 않게끔 해야 했습니다.
해결 방법
- 파싱 중 발생할 수 있는 문법 오류, 중복 선언, 허용되지 않는 지시어 등을 감지할 수 있도록 상황별 예외 처리 로직을 구축했습니다.
- 예외 발생 시 에러 발생 지점(블록명, 지시어명 등)과 함께 상세 메시지를 제공해 사용자가 원인을 쉽게 파악할 수 있도록 했습니다.
- 상위 블록까지 예외가 전달되어 전체 설정 파일의 구조 오류를 감지할 수 있도록 했습니다.
관련 코드
- Our program uses
kqueueto implement I/O Multiplexing. - Therefore, you need an OS that supports
kqueue. - Tested on macOS (Apple silicon, Intel)
- Clone this repo.
git clone https://github.com/two-three-four-five/webserv.git- Compile webserv with Makefile
make all./webserv [config_file]config_file (Optional): 설정 파일 경로 (기본값: ./conf/default.conf)
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
client_body_timeout 180;
server {
listen 8888;
server_name localhost;
client_body_timeout 10;
location ^ / {
root html;
index index.html index.htm;
}
}
}