server search for client completed with host:port
This commit is contained in:
@@ -32,6 +32,7 @@ class Client
|
||||
static char buf[MAX_FILESIZE+1];
|
||||
size_t body_size;
|
||||
unsigned int status;
|
||||
listen_socket *lsocket;
|
||||
|
||||
// const functions ?
|
||||
http_method get_method();
|
||||
|
||||
@@ -99,3 +99,9 @@ void replace_all_substr(std::string &str, const std::string &ori_substr, const s
|
||||
pos += new_substr.size();
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const listen_socket& lhs, int fd)
|
||||
{ return lhs.fd == fd; }
|
||||
|
||||
bool operator==(int fd, const listen_socket& rhs)
|
||||
{ return fd == rhs.fd; }
|
||||
|
||||
@@ -29,6 +29,15 @@ enum http_method
|
||||
ANY_METHODS = 0b11111111,
|
||||
};
|
||||
|
||||
struct listen_socket
|
||||
{
|
||||
int fd;
|
||||
std::string host;
|
||||
std::string port;
|
||||
};
|
||||
bool operator==(const listen_socket& lhs, int fd);
|
||||
bool operator==(int fd, const listen_socket& rhs);
|
||||
|
||||
std::vector<std::string> split(std::string input, char delimiter);
|
||||
bool isNumeric(std::string str);
|
||||
bool isNumeric_btw(int low, int high, std::string str);
|
||||
|
||||
@@ -58,14 +58,14 @@ class Webserv
|
||||
|
||||
private:
|
||||
int _epfd;
|
||||
std::vector<int> _listen_sockets;
|
||||
std::vector<listen_socket> _listen_sockets;
|
||||
std::vector<ServerConfig> _servers;
|
||||
std::vector<Client> _clients;
|
||||
std::map<int, std::string> _http_status;
|
||||
std::map<std::string, std::string> _mime_types;
|
||||
|
||||
// accept.cpp
|
||||
void _accept_connection(int fd);
|
||||
void _accept_connection(listen_socket &lsocket);
|
||||
// request.cpp
|
||||
void _request(Client *client);
|
||||
void _read_request(Client *client);
|
||||
@@ -106,6 +106,7 @@ class Webserv
|
||||
// close.cpp
|
||||
void _close_client(int fd);
|
||||
void _close_all_clients();
|
||||
void _close_all_listen_sockets();
|
||||
// init.cpp
|
||||
void _bind(int socket_fd, in_port_t port, std::string host);
|
||||
void _listen(int socket_fd, unsigned int max_connections);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
#include "Webserv.hpp"
|
||||
|
||||
void Webserv::_accept_connection(int fd)
|
||||
void Webserv::_accept_connection(listen_socket &lsocket)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addr_len;
|
||||
@@ -9,7 +9,7 @@ void Webserv::_accept_connection(int fd)
|
||||
|
||||
std::cerr << "accept()\n";
|
||||
addr_len = sizeof addr;
|
||||
accepted_fd = ::accept(fd, (sockaddr*)&addr, &addr_len);
|
||||
accepted_fd = ::accept(lsocket.fd, (sockaddr*)&addr, &addr_len);
|
||||
if (accepted_fd == -1)
|
||||
{
|
||||
std::perror("err accept()");
|
||||
@@ -21,6 +21,7 @@ void Webserv::_accept_connection(int fd)
|
||||
|
||||
_clients.push_back(Client());
|
||||
_clients.back().fd = accepted_fd;
|
||||
_clients.back().lsocket = &lsocket;
|
||||
|
||||
_epoll_update(accepted_fd, EPOLLIN, EPOLL_CTL_ADD);
|
||||
}
|
||||
|
||||
@@ -45,10 +45,9 @@ Webserv::Webserv(std::vector<ServerConfig>* servers)
|
||||
|
||||
Webserv::~Webserv()
|
||||
{
|
||||
//close(_socket_fd);
|
||||
// TODO : CLOSE ALL _listen_sockets
|
||||
close(_epfd);
|
||||
_close_all_clients();
|
||||
_close_all_listen_sockets();
|
||||
std::cerr << "Server destroyed\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -32,3 +32,16 @@ void Webserv::_close_all_clients()
|
||||
_clients.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void Webserv::_close_all_listen_sockets()
|
||||
{
|
||||
while (!_listen_sockets.empty())
|
||||
{
|
||||
// _epoll_update(_listen_sockets.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG
|
||||
if (::close(_listen_sockets.back().fd) == -1)
|
||||
std::perror("err close()");
|
||||
else
|
||||
std::cerr << "close fd " << _listen_sockets.back().fd << "\n";
|
||||
_listen_sockets.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
void Webserv::init_virtual_servers(std::vector<ServerConfig>* servers)
|
||||
{
|
||||
int ret;
|
||||
std::vector<int> _open_ports;
|
||||
std::vector<std::string> open_sockets;
|
||||
struct listen_socket new_socket;
|
||||
std::string host_port;
|
||||
|
||||
_servers = *servers;
|
||||
_listen_sockets.clear();
|
||||
@@ -12,7 +14,11 @@ void Webserv::init_virtual_servers(std::vector<ServerConfig>* servers)
|
||||
|
||||
while (it != _servers.end())
|
||||
{
|
||||
if ( std::find(_open_ports.begin(), _open_ports.end(), std::atoi(it->port.data()) ) != _open_ports.end() )
|
||||
host_port.clear();
|
||||
host_port.append(it->host);
|
||||
host_port.append(":");
|
||||
host_port.append(it->port);
|
||||
if ( std::find(open_sockets.begin(), open_sockets.end(), host_port) != open_sockets.end() )
|
||||
{
|
||||
++it;
|
||||
continue;
|
||||
@@ -24,27 +30,31 @@ void Webserv::init_virtual_servers(std::vector<ServerConfig>* servers)
|
||||
std::perror("err socket()");
|
||||
throw std::runtime_error("Socket init");
|
||||
}
|
||||
new_socket.fd = ret;
|
||||
new_socket.host = it->host;
|
||||
new_socket.port = it->port;
|
||||
_listen_sockets.push_back(new_socket);
|
||||
|
||||
// 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)
|
||||
if (setsockopt(new_socket.fd, SOL_SOCKET, SO_REUSEADDR, &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
|
||||
_bind(new_socket.fd, std::atoi(it->port.c_str()), it->host);
|
||||
_listen(new_socket.fd, 512); // 512 arbitrary
|
||||
|
||||
if (_epoll_update(_listen_sockets.back(), EPOLLIN, EPOLL_CTL_ADD) == -1)
|
||||
if (_epoll_update(new_socket.fd, EPOLLIN, EPOLL_CTL_ADD) == -1)
|
||||
throw std::runtime_error("Socket init");
|
||||
|
||||
_open_ports.push_back(std::atoi(it->port.data()));
|
||||
open_sockets.push_back(host_port);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,24 +356,31 @@ void Webserv::_delete_file(Client *client, const std::string &path)
|
||||
ServerConfig &Webserv::_determine_process_server(Client *client)
|
||||
{
|
||||
/*
|
||||
TODO : determine virtual server based on ip_address::port and server_name
|
||||
Ior now its just based on server_name.
|
||||
(maybe with a map< string, std::vector<ServerConfig> > where the string is "ip_adress::port")
|
||||
http://nginx.org/en/docs/http/request_processing.html
|
||||
_determine_process_server() should be complete.
|
||||
TODO : test it
|
||||
*/
|
||||
|
||||
std::string &server_name = client->get_headers("Host");
|
||||
std::vector<ServerConfig>::iterator it = _servers.begin();
|
||||
std::vector<ServerConfig>::iterator default_server = _servers.end();
|
||||
|
||||
while (it != _servers.end())
|
||||
{
|
||||
if ( std::find(it->server_name.begin(), it->server_name.end(), server_name) != it->server_name.end() )
|
||||
break;
|
||||
if (it->host == client->lsocket->host
|
||||
&& it->port == client->lsocket->port)
|
||||
{
|
||||
if ( std::find(it->server_name.begin(), it->server_name.end(), server_name) != it->server_name.end() )
|
||||
break;
|
||||
else if (default_server == _servers.end())
|
||||
default_server = it;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
if (it != _servers.end())
|
||||
return (*it);
|
||||
else
|
||||
return (_servers.front());
|
||||
return (*default_server);
|
||||
}
|
||||
|
||||
LocationConfig &Webserv::_determine_location(ServerConfig &server, std::string &path)
|
||||
|
||||
@@ -11,6 +11,7 @@ void Webserv::run()
|
||||
int nfds;
|
||||
int i;
|
||||
int count_loop = 0;
|
||||
std::vector<listen_socket>::iterator it_socket;
|
||||
|
||||
g_run = true;
|
||||
while (g_run)
|
||||
@@ -34,9 +35,9 @@ void Webserv::run()
|
||||
while (i < nfds)
|
||||
{
|
||||
// TODO : handle EPOLLERR and EPOLLHUP
|
||||
if ((std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd) != _listen_sockets.end())
|
||||
&& (events[i].events & EPOLLIN))
|
||||
_accept_connection(events[i].data.fd);
|
||||
it_socket = std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd);
|
||||
if (it_socket != _listen_sockets.end() && events[i].events & EPOLLIN)
|
||||
_accept_connection(*it_socket);
|
||||
else if (events[i].events & EPOLLIN)
|
||||
_request( &(*std::find(_clients.begin(), _clients.end(), events[i].data.fd)) );
|
||||
else if (events[i].events & EPOLLOUT)
|
||||
|
||||
Reference in New Issue
Block a user