Browse Source

save 22-11-8-1

master
nicolas-arnaud 2 years ago
parent
commit
230de364a6
  1. 2
      Makefile
  2. 15
      includes/Socket.hpp
  3. 109
      srcs/load/Socket.cpp

2
Makefile

@ -10,7 +10,7 @@ CXXFLAGS= -g -I includes -Werror -Wextra -Wall -std=c++98
all : $(NAME)
$(NAME): $(OBJS)
$(CXX) -g $(OBJS) -o $(NAME)
$(CXX) -g $(OBJS) -o $(NAME)
clean:
rm -rf $(OBJS)

15
includes/Socket.hpp

@ -2,10 +2,11 @@
#include "webserv.hpp"
class Socket {
int _master_socket;
int _clients_amount;
std::vector<int> _clients;
int _fd;
//int _clients_amount;
Socket *_parent;
std::vector<Socket *> _childs;
string _request;
public:
struct sockaddr_in _address;
listen_t _listen;
@ -14,10 +15,12 @@ class Socket {
static int _min_fd;
static int _amount;
Socket(listen_t listen);
Socket(int fd, Socket *parent);
~Socket(void);
int launch(void);
void set_fds(void);
void refresh(Env *env);
int answer(Env *env, int fd, string request);
void send_answer(int fd, string msg);
bool isRequestValid(string request);
int answer(Env *env, string request);
void send_answer(string msg);
};

109
srcs/load/Socket.cpp

@ -1,9 +1,10 @@
#include "webserv.hpp"
Socket::Socket(listen_t listen) : _listen(listen) { _clients_amount = 0; }
Socket::Socket(listen_t listen) : _listen(listen) {}
Socket::Socket(int fd, Socket *parent) : _fd(fd),_parent(parent) {}
Socket::~Socket(void) {
close(_master_socket);
close(_fd);
cout << "Socket destroyed!\n";
}
@ -12,12 +13,12 @@ int Socket::launch(void) {
string ip = _listen.ip;
int port = _listen.port;
_master_socket = socket(AF_INET, SOCK_STREAM, 0);
if (_master_socket == 0) {
_fd = socket(AF_INET, SOCK_STREAM, 0);
if (_fd == 0) {
cout << "Socket creation: " << strerror(errno) << "\n";
return (EXIT_FAILURE);
}
int opt_ret = setsockopt(_master_socket, SOL_SOCKET, SO_REUSEADDR,
int opt_ret = setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR,
(char *)&opt, sizeof(opt));
if (opt_ret < 0) {
cout << "Sockopt: " << strerror(errno) << "\n";
@ -28,92 +29,111 @@ int Socket::launch(void) {
_address.sin_addr.s_addr = inet_addr(ip.c_str());
_address.sin_port = htons(port);
if (bind(_master_socket, (struct sockaddr *)&_address, sizeof(_address)) <
if (bind(_fd, (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) {
if (listen(_fd, 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;
cout << "Master: " << _fd << "\n";
if (_fd < _min_fd)
_min_fd = _fd;
_amount++;
return (EXIT_SUCCESS);
}
void Socket::set_fds(void) {
FD_SET(_master_socket, &_readfds);
for (std::vector<int>::iterator it = _clients.begin(); it < _clients.end();
int child_fd;
FD_SET(_fd, &_readfds);
for (std::vector<Socket *>::iterator it = _childs.begin(); it < _childs.end();
it++) {
FD_SET(*it, &_readfds);
if (*it > _max_fd)
_max_fd = *it;
child_fd = (*it)->_fd;
FD_SET(child_fd, &_readfds);
if (child_fd > _max_fd)
_max_fd = child_fd;
}
}
void Socket::refresh(Env *env) {
std::vector<int>::iterator it;
int valread;
int addrlen = sizeof(_address);
char buffer[10000];
if (FD_ISSET(_master_socket, &_readfds)) {
int new_socket = accept(_master_socket, (struct sockaddr *)&_address,
if (FD_ISSET(_fd, &_readfds)) {
int new_socket = accept(_fd, (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);
//fcntl(new_socket, F_GETNOSIGPIPE);
fcntl(new_socket, F_SETFL, O_NONBLOCK);
#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);
_childs.push_back(new Socket(new_socket, this));
}
for (it = _clients.begin(); it < _clients.end(); it++) {
if (FD_ISSET(*it, &_readfds)) {
valread = read(*it, buffer, 10000);
int child_fd;
for (std::vector<Socket *>::iterator it = _childs.begin(); it < _childs.end(); it++) {
child_fd = (*it)->_fd;
if (FD_ISSET(child_fd, &_readfds)) {
valread = read(child_fd, buffer, 10000);
if (valread == 0) {
getpeername(*it, (struct sockaddr *)&_address,
getpeername(child_fd, (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);
delete (*it);
_childs.erase(it);
} else {
buffer[valread] = '\0';
if (answer(env, *it, buffer) == EXIT_FAILURE) {
_clients.erase(it);
close(*it);
}
(*it)->answer(env, buffer);
}
}
}
}
int Socket::answer(Env *env, int fd, string request) {
cout << "|===|Request|===|\n"<< request << "\n|===|===|===|\n";
std::vector<string> lines = split(request, '\n');
bool Socket::isRequestValid(string request) {
_request += request;
if (_request.length() < 1)
return false;
std::vector<string> lines = split(_request, '\n');
bool is_valid = false;
for (std::vector<string>::iterator it = lines.begin();
it < lines.end(); it++) {
if (*it == "\r" || *it == "") is_valid = true;
}
if (!is_valid || lines.at(0) == "")
return false;
std::vector<string> head = split(lines.at(0), ' ');
string uri;
if (head.size() < 2)
if ((head.at(0) != "GET" && head.at(0) != "POST" && head.at(0) != "DELETE")
|| head.size() < 2)
return false;
return true;
}
int Socket::answer(Env *env, string request) {
cout << "|===|Request|===|\n"<< request << "\n|===|===|===|\n";
if (!isRequestValid(request)) {
cout << "Bad request recieved\n";
send_answer("HTTP/1.1 400 Bad Request\n\n");
return EXIT_FAILURE;
uri = head.at(1);
}
std::vector<string> lines = split(_request, '\n');
std::vector<string> head = split(lines.at(0), ' ');
string uri = head.at(1);
cout << uri << "\n";
string ret;
std::stringstream answer;
answer << "HTTP/1.1";
Server *server = env->choose_server(this, split(lines.at(1), ' ').at(1));
Server *server = env->choose_server(_parent, split(lines.at(1), ' ').at(1));
Route *route = server->get_route(uri);
string path = route->correctUri(uri);
cout << "Path: " << path << "\n";
@ -124,14 +144,15 @@ int Socket::answer(Env *env, int fd, string request) {
}
answer << (ret == "" ? " 404 Not Found\nContent-length: 0\n\n" : " 200 OK\n") << ret;
cout << "|===|Answer|===|\n" << answer.str() << "\n|===|===|===|\n";
send_answer(fd, answer.str());
send_answer(answer.str());
_request = "";
return EXIT_SUCCESS;
}
void Socket::send_answer(int fd, string msg) {
void Socket::send_answer(string msg) {
#ifdef __linux__
send(fd, msg.c_str(), msg.length(), MSG_NOSIGNAL);
send(_fd, msg.c_str(), msg.length(), MSG_NOSIGNAL);
#elif __APPLE__
send(fd, msg.c_str(), msg.length(), 0);
send(_fd, msg.c_str(), msg.length(), 0);
#endif
}

Loading…
Cancel
Save