서버 매니저는 configuration file을 의미 있는 단위(block)로 나누고, 각 블록에 대해 유효성을 검증한 뒤 문제가 없다면 서버 생성자의 인자로 넘겨 서버를 생성합니다. 서버는 여러 개가 만들어질 수 있기 때문에 서버 매니저의 벡터 멤버 변수로 관리합니다.
void
ServerManager::createServer(const std::string& configuration_file_path, char **env)
{
std::string config_string = ft::getStringFromFile(configuration_file_path);
std::string config_block;
std::vector<std::string> server_strings;
if (!splitConfigString(config_string, config_block, server_strings))
throw (std::invalid_argument("Failed to split configuration string"));
if (!isValidConfigBlock(config_block))
throw (std::invalid_argument("Config block is not valid."));
m_config = Config(config_block, env);
for (size_t i = 0; i < server_strings.size(); ++i)
{
std::string server_block;
std::vector<std::string> location_blocks;
if (!splitServerString(server_strings[i], server_block, location_blocks))
throw (std::invalid_argument("Failed to split Sever string(" + ft::to_string(i) + ")"));
if (!isValidServerBlock(server_block))
throw (std::invalid_argument("Server block(" + ft::to_string(i) + ") is not valid."));
for (size_t j = 0; j < location_blocks.size(); ++j) {
if (!isValidLocationBlock(location_blocks[j]))
throw (std::invalid_argument("Location block(" + ft::to_string(i) \
+ "-" + ft::to_string(j) + ") is not valid."));
}
m_servers.push_back(Server(this, server_block, location_blocks, &this->m_config));
m_server_fdset.insert(m_servers.back().get_m_fd());
}
writeCreateServerLog();
}
Server 생성자
이미 유효성 검사가 끝난 safety block들이 인자로 들어오기 때문에, Server 생성자에서 해야 하는 작업은 많지 않습니다. server_block을 파싱하여 Server 인스턴스의 멤버 변수에 값을 저장하고, location block들은 그대로 Location 생성자에 넘겨 Server 인스턴스의 벡터 멤버 변수에 저장합니다. 그 외에는 일반적인 서버 프로그램과 같습니다.