이전 글에 이어.
[42Seoul] Webserv - 00
길고 길었던 웹서브 과제가 끝남에 따라, 그 동안 했던것들을 정리해보고자 한다. 웹서버와 HTTP 웹서브 서브젝트를 보면 이런 글귀가 있다. This is when you finally understand why a URL starts with HTTP URL이 H
woongtech.tistory.com
HTTP에 대한 개념이나 웹서브라는 과제가 어떤것을 해야하는지 살펴보았다면, 과제를 어떻게 진행할 것인가에 대해서 한번 고민해보는것도 좋다.
나는 웹서브를 진행하면서 팀원들과의 협업을 효율적으로 수행하기 위해 깃을 통해 소스코드 관리를 했고, 깃허브에서 이슈트래킹을 통해 서로의 진행 사항을 공유했다.
이런식으로 기능 구현이나 고치는 작업들을 이슈로 작성하고, 이슈마다 브랜치를 생성해서 팀원들과 최대한 작업 내용이 겹치지 않도록 관리해주었다.
Configuration file
웹서브에서는 프로그램의 인자로 configuration file을 받아야 한다고 명시하고 있다. 만약 인자가 존재하지 않다면 기본 configuration file을 사용하게 된다.
여기서 configuration file이란 구성 파일이라는 의미로 소프트웨어나 시스템의 동작 및 설정을 정의하는 데 사용되는 파일이다. 일반적으로 구성 파일은 텍스트 파일 형식으로 작성되며, 주로 설정 값, 옵션, 매개변수 등을 포함한다. 소프트웨어나 시스템은 구성 파일을 읽어 해당 설정을 적용하고 동작하게 된다.
우리는 nginx의 구성 파일을 참고하며 과제를 진행했다.
Full Example Configuration | NGINX
Full Example Configuration nginx.conf user www www; ## Default: nobody worker_processes 5; ## Default: 1 error_log logs/error.log; pid logs/nginx.pid; worker_rlimit_nofile 8192; events { worker_connections 4096; ## Default: 1024 } http { include conf/mime.
www.nginx.com
nginx 구성 파일을 포함, 구성 파일은 일반적으로 다음과 같은 특징을 가지고 있다.
- 텍스트 기반 형식: 구성 파일은 텍스트 파일로 작성되며, 사람이 읽고 이해하기 쉽다. 일반적으로 키-값 쌍(key-value pair)이나 섹션(section)으로 구성된다.
- 설정 값 설정: 구성 파일은 설정 값을 포함하며, 해당 소프트웨어나 시스템이 동작하는 데 필요한 매개변수, 옵션, 속성 등을 정의한다. 웹 서버의 구성 파일에서는 포트 번호, 호스트 이름, 디렉토리 경로, 액세스 권한 등을 설정할 수 있다.
- 주석: 주석은 구성 파일에서 설명이나 메모를 추가하는 데 사용된다. 일반적으로 주석은 특정 기호나 키워드로 시작하며, 해석되지 않고 무시된다. 주석을 사용하여 구성 파일의 이해도를 높일 수 있다.
- 상속 및 재사용: 일부 구성 파일 형식은 상속이나 재사용을 지원한다. 이를 통해 하위 구성 파일에서 상위 구성 파일의 설정을 상속하거나, 공통 구성 파일을 사용하여 여러 시스템 또는 애플리케이션에 대한 구성을 일괄적으로 관리할 수 있다.
구성 파일은 시스템 관리자나 사용자가 소프트웨어 또는 시스템의 동작을 변경하고 제어하는 데 중요한 역할을 한다. 따라서 구성 파일을 올바르게 작성하고 유지 관리하는 것은 원활한 운영과 성능 향상에 중요한 요소이다.
세부 내용
nginx의 구성 파일을 살펴보면 여러가지 값들이 설정되어 있는것을 확인할 수 있다. 이 값들을 올바르고 정확하게 사용하기 위해서는 효율적인 파싱 구조를 생각해보는것도 중요하다.
http {
include conf/mime.types;
include /etc/nginx/fastcgi.conf;
index index.html index.htm index.php;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
tcp_nopush on;
server_names_hash_bucket_size 128; # this seems to be required for some vhosts
server { # php/fastcgi
listen 80;
server_name domain1.com www.domain1.com;
access_log logs/domain1.access.log main;
root html;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:1025;
}
}
server { # simple reverse-proxy
listen 80;
server_name domain2.com www.domain2.com;
access_log logs/domain2.access.log main;
# serve static files
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
root /var/www/virtual/big.server.com/htdocs;
expires 30d;
}
# pass requests for dynamic content to rails/turbogears/zope, et al
location / {
proxy_pass http://127.0.0.1:8080;
}
}
upstream big_server_com {
server 127.0.0.3:8000 weight=5;
server 127.0.0.3:8001 weight=5;
server 192.168.0.1:8000;
server 192.168.0.1:8001;
}
server { # simple load balancing
listen 80;
server_name big.server.com;
access_log logs/big.server.access.log main;
location / {
proxy_pass http://big_server_com;
}
}
}
구성파일은 이와 같이 되어있다. 파일을 살펴보면, 키(key)는 어디에나 존재하지만, 값(value)는 있기도 하고 중괄호가 대신 들어가기도 하고, 둘 다 존재하기도 하다.
이 구성파일에서는 키를 지시자(direction)이라고 한다.
이 지시자들 중에서 가장 먼저 파악해야하는 부분은 include 지시자이다. 이 지시자는 기본 구성 파일에 또 다른 구성 파일을 불러올 수 있다. 헤더와 비슷한 개념으로 생각했다.
그렇다면, include conf/mime.types;
와 같은 지시자는 어떻게 처리되어야 할까?
nginx에서는, 구성파일을 먼저 불러온 뒤, include가 있을 때, include에 해당하는 값인 conf/mime.types
라는 경로에 위치한 또 다른 파일을 기본 구성파일 아래에 붙여주는 형식으로 처리를 해준다.
그렇다면, 위의 구성파일에 include가 적용된다면 아래와 같은 형식을 받아주어야 한다.
http {
include conf/mime.types;
include /etc/nginx/proxy.conf;
include /etc/nginx/fastcgi.conf;
index index.html index.htm index.php;
// ...
server { # php/fastcgi
listen 80;
server_name domain1.com www.domain1.com;
access_log logs/domain1.access.log main;
root html;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:1025;
}
}
server {
// ...
}
}
// mime.types
types {
text/html html htm shtml;
text/css css;
text/xml xml rss;
image/gif gif;
// ...
}
// fastcgi.conf
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
// proxy.conf
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
이런식으로 기존 구성파일의 아래에 include 지시자들에 대한 정보가 담기게 된다.
우리는 이 구성파일을 참고해 아래의 구조체에 저장하는것을 목표로 파싱을 진행했다.
struct Directive
{
std::string name;
std::string value;
std::string pre_name;
std::vector<Directive> block;
};
이 구조체에서 지시자는 name에, 값은 value에 들어가게 되고, 혹시 값이 존재하지 않다면 NULL로 처리해주었다. 또, 지시자마다 중괄호로 자식 블록을 가질 수 있기 때문에, 이 부분은 재귀로 블록의 끝 깊이까지 탐색할 수 있도록 해주고, 주소값을 block에 담아주었다.
또, 블록 내부에 같은 깊이에 존재하는 지시자들은 vector 자료구조를 사용해 접근과 사용이 편리하도록 파싱해주었다.
예시를 보면,
Directive server; // server라는 구조체가 있다면
// server.name = "server", server.value = NULL, server.block = Directive (자식 블록 구조체)
server {
// server.block[0].name = "listen", server.block[0].value = 80, server.block[0].block = NULL
listen 80;
// server.block[1].name = "server_name", server.block[1].value = "domain1.com www.domain1.com", server.block[1].block = NULL
server_name domain1.com www.domain1.com;
// server.block[2].name = "access_log", server.block[2].value = "logs/domain1.access.log main", server.block[2].block = NULL
access_log logs/domain1.access.log main;
// server.block[3].name = "root", server.block[3].value = "html", server.block[3].block = NULL;
root html;
// server.block[4].name = "location", server.block[4].value = "~ \.php$", server.block[4].block = Directive (자식 블록 구조체)
location ~ \.php$ {
// server.block[4].block[0].name = "fastcgi_pass", server.block[4].block[0].value = "127.0.0.1:1025", server.block[4].block[0].block = NULL
fastcgi_pass 127.0.0.1:1025;
}
}
이런 형식으로 데이터가 저장된다.
파싱에 완벽한 정답이 없다고 생각하지만, 적재적소 필요한 요소들을 정확하게 찾고, 적절하게 사용할 수 있도록 준비하는 작업은 정말 중요하다고 생각된다. 구조를 참고해보고 더 효율적인 구조를 생각해보기를 바란다.
'42SEOUL > Circle5' 카테고리의 다른 글
[42Seoul] webserv - 02 (0) | 2023.06.30 |
---|---|
[42Seoul] Webserv - 00 (0) | 2023.06.14 |
[42SEOUL] CPP Module 09 (0) | 2023.04.11 |
[42SEOUL] CPP Module 08 (0) | 2023.02.18 |
[42SEOUL] CPP Module 07 (0) | 2023.02.18 |