You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.3 KiB

#include "webserv.hpp"
2 years ago
#define PORT 80
int main(int ac, char **av) {
Env env;
2 years ago
int opt = 1;
int master_socket, addrlen, new_socket, client_socket[30],
max_clients = 30, activity, i, valread, sd;
int max_sd;
2 years ago
struct sockaddr_in address;
2 years ago
char buffer[30000];
2 years ago
fd_set readfds;
char _404[72] =
"HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!";
if (ac > 1) {
cout << "Parsing configuration file...\n";
JSONParser parser(av[1]);
JSONNode *conf = parser.parse();
cout << "Configuration parsed.\n";
cout << "Setting environment...\n";
env.max_clients = conf->obj()["max_clients"]->nbr();
JSONList servers = conf->obj()["servers"]->lst();
for (std::vector<JSONNode *>::iterator i = servers.begin();
i < servers.end(); i++) {
JSONObject datas = (*i)->obj();
Server *server =
new Server(datas["server_name"]->str(), datas["root"]->str(),
datas["return"]->str(), datas["listen"],
datas["index"], datas["location"]);
delete *i;
}
delete conf;
cout << "Environment setup.\n";
}
for (i = 0; i < max_clients; i++)
client_socket[i] = 0;
if ((master_socket = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
std::cout << std::strerror(errno) << std::endl;
2 years ago
exit(EXIT_FAILURE);
}
if (setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
sizeof(opt)) < 0) {
std::cout << std::strerror(errno) << std::endl;
2 years ago
exit(EXIT_FAILURE);
}
2 years ago
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(master_socket, (struct sockaddr *)&address, sizeof(address)) < 0) {
std::cout << std::strerror(errno) << std::endl;
2 years ago
exit(EXIT_FAILURE);
}
std::cout << "Listener on port " << PORT << std::endl;
if (listen(master_socket, 3) < 0) {
std::cout << std::strerror(errno) << std::endl;
2 years ago
exit(EXIT_FAILURE);
}
2 years ago
addrlen = sizeof(address);
std::cout << "Waiting for connections ..." << std::endl;
while (1) {
2 years ago
FD_ZERO(&readfds);
FD_SET(master_socket, &readfds);
max_sd = master_socket;
for (i = 0; i < max_clients; i++) {
sd = client_socket[i];
if (sd > 0)
FD_SET(sd, &readfds);
if (sd > max_sd)
max_sd = sd;
2 years ago
}
activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);
if ((activity < 0) && (errno != EINTR))
2 years ago
std::cout << std::strerror(errno) << std::endl;
if (FD_ISSET(master_socket, &readfds)) {
if ((new_socket = accept(master_socket, (struct sockaddr *)&address,
(socklen_t *)&addrlen)) < 0) {
std::cout << std::strerror(errno) << std::endl;
2 years ago
exit(EXIT_FAILURE);
}
#ifdef __APPLE__
fcntl(new_socket, F_GETNOSIGPIPE);
#endif
std::cout << "New connection, socket fd is " << new_socket
<< ", ip is : " << inet_ntoa(address.sin_addr)
<< ", port : " << ntohs(address.sin_port) << std::endl;
for (i = 0; i < max_clients; i++) {
if (client_socket[i] == 0) {
2 years ago
client_socket[i] = new_socket;
std::cout << "Adding to list of sockets as " << i
<< std::endl;
break;
2 years ago
}
}
}
for (i = 0; i < max_clients; i++) {
2 years ago
sd = client_socket[i];
if (FD_ISSET(sd, &readfds)) {
valread = read(sd, buffer, 30000);
if (valread == 0) {
getpeername(sd, (struct sockaddr *)&address,
(socklen_t *)&addrlen);
std::cout << "Host disconnected, ip "
<< inet_ntoa(address.sin_addr) << ", port "
<< ntohs(address.sin_port) << std::endl;
close(sd);
2 years ago
client_socket[i] = 0;
} else
send(sd, _404, strlen(_404), MSG_NOSIGNAL);
2 years ago
}
}
}
return (0);
}