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.

125 lines
3.3 KiB

#include "webserv.hpp"
Socket::Socket(string def) {
_listen = get_listen_t(def);
2 years ago
_clients_amount = 0;
}
Socket::~Socket() {
2 years ago
close(_master_socket);
cout << "Socket destroyed!\n";
}
int Socket::launch() {
2 years ago
int opt = 1;
string ip = _listen.ip;
int port = _listen.port;
2 years ago
_master_socket = socket(AF_INET, SOCK_STREAM, 0);
if (_master_socket == 0) {
cout << "Socket creation: " << strerror(errno) << "\n";
return (EXIT_FAILURE);
}
int opt_ret = setsockopt(_master_socket, SOL_SOCKET, SO_REUSEADDR,
(char *)&opt, sizeof(opt));
if (opt_ret < 0) {
cout << "Sockopt: " << strerror(errno) << "\n";
return (EXIT_FAILURE);
}
if (ip.at(0) == '[')
_address.sin_family = AF_INET6;
else
_address.sin_family = AF_INET;
_address.sin_addr.s_addr = inet_addr(ip.c_str());
_address.sin_port = htons(port);
2 years ago
if (bind(_master_socket, (struct sockaddr *)&_address, sizeof(_address)) <
0) {
cout << "Bind: " << strerror(errno) << "\n";
return (EXIT_FAILURE);
}
cout << "Listener " << ip << " on port " << port << "\n";
2 years ago
if (listen(_master_socket, 3) < 0) {
cout << "Listen: " << strerror(errno) << "\n";
return (EXIT_FAILURE);
}
cout << "Socket::_master_socket: " << _master_socket << "\n";
if (_master_socket < _min_fd)
_min_fd = _master_socket;
_amount++;
return (EXIT_SUCCESS);
}
2 years ago
void Socket::set_fds() {
2 years ago
FD_SET(_master_socket, &_readfds);
2 years ago
for (std::vector<int>::iterator it = _clients.begin(); it < _clients.end();
it++) {
FD_SET(*it, &_readfds);
if (*it > _max_fd)
_max_fd = *it;
}
}
void Socket::refresh(Env *env) {
2 years ago
std::vector<int>::iterator it;
2 years ago
int valread;
int addrlen = sizeof(_address);
char buffer[10000];
if (FD_ISSET(_master_socket, &_readfds)) {
int new_socket = accept(_master_socket, (struct sockaddr *)&_address,
(socklen_t *)&addrlen);
if (new_socket < 0) {
cout << "Accept: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
#ifdef __APPLE__
2 years ago
fcntl(new_socket, F_GETNOSIGPIPE);
#endif
2 years ago
cout << "New connection, socket fd is " << new_socket
<< ", ip is : " << inet_ntoa(_address.sin_addr)
<< ", port : " << ntohs(_address.sin_port) << "\n";
2 years ago
_clients.push_back(new_socket);
2 years ago
}
for (it = _clients.begin(); it < _clients.end(); it++) {
if (FD_ISSET(*it, &_readfds)) {
valread = read(*it, buffer, 10000);
if (valread == 0) {
getpeername(*it, (struct sockaddr *)&_address,
(socklen_t *)&addrlen);
cout << "Host disconnected, ip " << inet_ntoa(_address.sin_addr)
<< ", port " << ntohs(_address.sin_port) << "\n";
close(*it);
2 years ago
_clients.erase(it);
2 years ago
} else {
buffer[valread] = '\0';
answer(env, *it, buffer);
2 years ago
}
}
}
2 years ago
}
void Socket::answer(Env *env, int fd, string request) {
std::vector<string> lines = split(request, '\n');
string uri = split(lines.at(0), ' ').at(1);
cout << uri << "\n";
2 years ago
cout << request << "\n|===|===|===|\n";
std::stringstream answer;
answer << "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: ";
Server *server = env->choose_server(this, split(lines.at(1), ' ').at(1));
Route *route = server->get_route(uri);
answer << route->getAutoindex(uri);
cout << answer.str() << "\n|===|===|===|\n";
send_answer(fd, answer.str());
}
void Socket::send_answer(int fd, string msg) {
#ifdef __linux__
send(fd, msg.c_str(), msg.length(), MSG_NOSIGNAL);
#elif __APPLE__
send(fd, msg.c_str(), msg.length(), 0);
#endif
}