94 lines
2.4 KiB
C++
94 lines
2.4 KiB
C++
|
|
#include "Webserv.hpp"
|
|
|
|
void Webserv::init_virtual_servers(std::vector<ServerConfig>* servers)
|
|
{
|
|
int ret;
|
|
std::vector<int> _open_ports;
|
|
|
|
_servers = *servers;
|
|
_listen_sockets.clear();
|
|
std::vector<ServerConfig>::iterator it = _servers.begin();
|
|
|
|
while (it != _servers.end())
|
|
{
|
|
if ( std::find(_open_ports.begin(), _open_ports.end(), std::atoi(it->port.data()) ) != _open_ports.end() )
|
|
{
|
|
++it;
|
|
continue;
|
|
}
|
|
|
|
ret = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); // (SOCK_CLOEXEC) for CGI fork ?
|
|
if (ret == -1)
|
|
{
|
|
std::perror("err socket()");
|
|
throw std::runtime_error("Socket init");
|
|
}
|
|
// HUGO ADD
|
|
//
|
|
// allow socket descriptor to be reuseable
|
|
// I just copied it from https://www.ibm.com/docs/en/i/7.2?topic=designs-example-nonblocking-io-select
|
|
int on = 1;
|
|
if (setsockopt(ret, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
|
|
{
|
|
::perror("err setsockopt()");
|
|
throw std::runtime_error("Socket init");
|
|
}
|
|
//
|
|
// HUGO ADD END
|
|
_listen_sockets.push_back(ret);
|
|
|
|
_bind(_listen_sockets.back(), std::atoi(it->port.data()), it->host);
|
|
_listen(_listen_sockets.back(), 512); // 512 arbitrary
|
|
|
|
if (_epoll_update(_listen_sockets.back(), EPOLLIN, EPOLL_CTL_ADD) == -1)
|
|
throw std::runtime_error("Socket init");
|
|
|
|
_open_ports.push_back(std::atoi(it->port.data()));
|
|
++it;
|
|
}
|
|
}
|
|
|
|
void Webserv::_bind(int socket_fd, in_port_t port, std::string host)
|
|
{
|
|
// cast invalid ? how to ?
|
|
// const struct sockaddr* cast_test = static_cast<const struct sockaddr*>(addr);
|
|
|
|
struct sockaddr_in addr;
|
|
std::memset(&addr, 0, sizeof addr);
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_port = ::htons(port);
|
|
addr.sin_addr.s_addr = ::htonl(::inet_addr(host.c_str()));
|
|
// addr.sin_addr.s_addr = ::htonl(INADDR_ANY); // htonl useless with 0 value (INADDR_ANY) ?
|
|
|
|
if (::bind(socket_fd, (const sockaddr*)&addr, sizeof addr) == -1)
|
|
{
|
|
std::perror("err bind()");
|
|
throw std::runtime_error("Socket bind");
|
|
}
|
|
}
|
|
|
|
void Webserv::_listen(int socket_fd, unsigned int max_connections)
|
|
{
|
|
if (::listen(socket_fd, max_connections) == -1)
|
|
{
|
|
std::perror("err listen()");
|
|
throw std::runtime_error("Socket listen");
|
|
}
|
|
}
|
|
|
|
void Webserv::_init_http_status_map()
|
|
{
|
|
_http_status[200] = S200;
|
|
_http_status[201] = S201;
|
|
_http_status[204] = S204;
|
|
|
|
_http_status[400] = S400;
|
|
_http_status[403] = S403;
|
|
_http_status[404] = S404;
|
|
_http_status[405] = S405;
|
|
_http_status[413] = S413;
|
|
|
|
_http_status[500] = S500;
|
|
}
|