#include "webserv.hpp" Socket::Socket(string def) { size_t sep_pos = def.rfind(':'); size_t ip6_endpos = def.rfind(']'); string tmp = def.substr(0, sep_pos); if (ip6_endpos > sep_pos) _ip = def; else _ip = isInt(tmp) || tmp == "localhost" ? "127.0.0.1" : tmp; tmp = def.substr(sep_pos + 1, def.length() - sep_pos - 1).c_str(); _port = !isInt(tmp) ? 80 : std::atoi(tmp.c_str()); _clients_amount = 0; } Socket::~Socket() { close(_master_socket); cout << "Socket destroyed!\n"; } int Socket::launch() { int opt = 1; _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); } _address.sin_family = AF_INET; _address.sin_addr.s_addr = inet_addr(_ip.c_str()); _address.sin_port = htons(_port); 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"; 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); } void Socket::set_fds() { FD_SET(_master_socket, &_readfds); for (std::vector::iterator it = _clients.begin(); it < _clients.end(); it++) { FD_SET(*it, &_readfds); if (*it > _max_fd) _max_fd = *it; } } void Socket::refresh() { std::vector::iterator it; int valread; int addrlen = sizeof(_address); char buffer[1024]; 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__ fcntl(new_socket, F_GETNOSIGPIPE); #endif cout << "New connection, socket fd is " << new_socket << ", ip is : " << inet_ntoa(_address.sin_addr) << ", port : " << ntohs(_address.sin_port) << "\n"; _clients.push_back(new_socket); } for (it = _clients.begin(); it < _clients.end(); it++) { if (FD_ISSET(*it, &_readfds)) { valread = read(*it, buffer, 1024); 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); _clients.erase(it); } else this->answer(*it, buffer); } } } void Socket::answer(int fd, string request) { char r404[72] = "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!"; cout << request << "\n"; #ifdef __linux__ send(fd, r404, strlen(r404), MSG_NOSIGNAL); #elif __APPLE__ send(fd, r404, strlen(r404), 0); #endif }