Browse Source

save 22-11-3

master
nicolas-arnaud 2 years ago
parent
commit
8489ab2506
  1. 2
      includes/Socket.hpp
  2. 151
      srcs/load/Route.cpp
  3. 271
      srcs/load/Socket.cpp
  4. 6
      srcs/tools.cpp

2
includes/Socket.hpp

@ -7,7 +7,7 @@ class Socket {
Socket *_parent; Socket *_parent;
std::vector<Socket *> _childs; std::vector<Socket *> _childs;
struct sockaddr_in _address; struct sockaddr_in _address;
string tmp; string _tmp;
string _header; string _header;
string _content; string _content;

151
srcs/load/Route.cpp

@ -1,26 +1,27 @@
#include "webserv.hpp" #include "webserv.hpp"
Route::Route(Server *server, string location, JSONNode *datas) : _server(server), _location(location){ Route::Route(Server *server, string location, JSONNode *datas)
JSONObject object = datas->obj(); : _server(server), _location(location) {
JSONNode *tmp; JSONObject object = datas->obj();
if ((tmp = object["root"])) JSONNode *tmp;
_root = tmp->str(); if ((tmp = object["root"]))
if ((tmp = object["return"])) _root = tmp->str();
_ret = tmp->str(); if ((tmp = object["return"]))
if ((tmp = object["autoindex"])) _ret = tmp->str();
_autoindex = tmp->boo(); if ((tmp = object["autoindex"]))
if ((tmp = object["indexs"])) { _autoindex = tmp->boo();
JSONList indexs = tmp->lst(); if ((tmp = object["indexs"])) {
for (JSONList::iterator it = indexs.begin(); it < indexs.end(); it++) { JSONList indexs = tmp->lst();
_indexs.push_back((*it)->str()); for (JSONList::iterator it = indexs.begin(); it < indexs.end(); it++) {
} _indexs.push_back((*it)->str());
} }
if ((tmp = object["add_header"])) { }
JSONList headers = tmp->lst(); if ((tmp = object["add_header"])) {
for (JSONList::iterator it = headers.begin(); it < headers.end(); it++) { JSONList headers = tmp->lst();
_headers.push_back((*it)->str()); for (JSONList::iterator it = headers.begin(); it < headers.end(); it++) {
} _headers.push_back((*it)->str());
} }
}
} }
Route::~Route(void) {} Route::~Route(void) {}
@ -32,63 +33,65 @@ std::vector<string> Route::getIndexsLst(void) { return _indexs; }
std::vector<string> Route::getHeadersLst(void) { return _headers; } std::vector<string> Route::getHeadersLst(void) { return _headers; }
string Route::getIndex(string uri, string path) { string Route::getIndex(string uri, string path) {
std::stringstream content; std::stringstream content;
std::stringstream ret; std::stringstream ret;
DIR *dir; DIR *dir;
struct dirent *entry; struct dirent *entry;
struct stat info; struct stat info;
std::vector<string> indexs = getIndexsLst(); std::vector<string> indexs = getIndexsLst();
std::vector<string>::iterator it; std::vector<string>::iterator it;
if ((dir = opendir(path.c_str())) == NULL) if ((dir = opendir(path.c_str())) == NULL)
return ""; return "";
else { else {
content << "<h3 style=\"text-align: center;\">" << path << " files :</h3>\n<ul>\n"; content << "<h3 style=\"text-align: center;\">" << path
while ((entry = readdir(dir)) != NULL) { << " files :</h3>\n<ul>\n";
if (entry->d_name[0] == '.') while ((entry = readdir(dir)) != NULL) {
continue; if (entry->d_name[0] == '.')
for (it = indexs.begin(); it < indexs.end(); it++) { continue;
if (entry->d_name == *it) for (it = indexs.begin(); it < indexs.end(); it++) {
return (read_file(path + "/" + *it)); if (entry->d_name == *it)
} return (read_file(path + "/" + *it));
content << "<li><a href=\"" << uri + "/" + entry->d_name << "\">"<< entry->d_name << "</a></li>\n"; }
if (stat(path.c_str(), &info) != 0) content << "<li><a href=\"" << uri + "/" + entry->d_name << "\">"
std::cerr << "stat() error on " << path << ": " << entry->d_name << "</a></li>\n";
<< strerror(errno) << "\n"; if (stat(path.c_str(), &info) != 0)
} std::cerr << "stat() error on " << path << ": " << strerror(errno)
content << "<ul>"; << "\n";
closedir(dir); }
} content << "<ul>";
if (!_autoindex) closedir(dir);
return ""; }
ret << "Content-type: text/html \n"; if (!_autoindex)
ret << "Content-length: "<< content.str().length(); return "";
ret << "\n\n" << content.str(); ret << "Content-type: text/html \r\n";
return ret.str(); ret << "Content-length: " << content.str().length() << "\r\n";
ret << "\r\n" << content.str();
return ret.str();
} }
string Route::correctUri(string uri) { string Route::correctUri(string uri) {
std::stringstream ret; std::stringstream ret;
std::vector<string>::iterator it; std::vector<string>::iterator it;
std::vector<string>::iterator it2; std::vector<string>::iterator it2;
//cout << "Correcting request: " << uri << " with root: " << _root << "\n"; // cout << "Correcting request: " << uri << " with root: " << _root << "\n";
ret << _root; ret << _root;
std::vector<string> loc_split = split(_location, '/'); std::vector<string> loc_split = split(_location, '/');
std::vector<string> uri_split = split(uri, '/'); std::vector<string> uri_split = split(uri, '/');
it2 = uri_split.begin(); it2 = uri_split.begin();
for (it = loc_split.begin(); it < loc_split.end(); it++) { for (it = loc_split.begin(); it < loc_split.end(); it++) {
while (*it2 == "") while (*it2 == "")
it2++; it2++;
while (*it == "") while (*it == "")
it++; it++;
if (it != loc_split.end()) if (it != loc_split.end())
it2++; it2++;
} }
while (it2 < uri_split.end()) { while (it2 < uri_split.end()) {
ret << "/" << *(it2++); ret << "/" << *(it2++);
} }
//cout << "resutlt: " << ret.str() << "\n"; // cout << "resutlt: " << ret.str() << "\n";
return ret.str(); return ret.str();
} }

271
srcs/load/Socket.cpp

@ -1,169 +1,170 @@
#include "webserv.hpp" #include "webserv.hpp"
Socket::Socket(listen_t listen) : _listen(listen) {} Socket::Socket(listen_t listen) : _listen(listen) {}
Socket::Socket(int fd, Socket *parent) : _fd(fd),_parent(parent) {} Socket::Socket(int fd, Socket *parent) : _fd(fd), _parent(parent) {}
Socket::~Socket(void) { Socket::~Socket(void) {
close(_fd); close(_fd);
cout << "Socket destroyed!\n"; cout << "Socket destroyed!\n";
} }
int Socket::launch(void) { int Socket::launch(void) {
int opt = 1; int opt = 1;
string ip = _listen.ip; string ip = _listen.ip;
int port = _listen.port; int port = _listen.port;
_fd = socket(AF_INET, SOCK_STREAM, 0); _fd = socket(AF_INET, SOCK_STREAM, 0);
if (_fd == 0) { if (_fd == 0) {
cout << "Socket creation: " << strerror(errno) << "\n"; cout << "Socket creation: " << strerror(errno) << "\n";
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
int opt_ret = setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, int opt_ret =
(char *)&opt, sizeof(opt)); setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
if (opt_ret < 0) { if (opt_ret < 0) {
cout << "Sockopt: " << strerror(errno) << "\n"; cout << "Sockopt: " << strerror(errno) << "\n";
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
_address.sin_family = AF_INET; _address.sin_family = AF_INET;
_address.sin_addr.s_addr = inet_addr(ip.c_str()); _address.sin_addr.s_addr = inet_addr(ip.c_str());
_address.sin_port = htons(port); _address.sin_port = htons(port);
if (bind(_fd, (struct sockaddr *)&_address, sizeof(_address)) < if (bind(_fd, (struct sockaddr *)&_address, sizeof(_address)) < 0) {
0) { cout << "Bind: " << strerror(errno) << "\n";
cout << "Bind: " << strerror(errno) << "\n"; return (EXIT_FAILURE);
return (EXIT_FAILURE); }
} cout << "Listener " << ip << " on port " << port << "\n";
cout << "Listener " << ip << " on port " << port << "\n";
if (listen(_fd, 3) < 0) { if (listen(_fd, 3) < 0) {
cout << "Listen: " << strerror(errno) << "\n"; cout << "Listen: " << strerror(errno) << "\n";
return (EXIT_FAILURE); return (EXIT_FAILURE);
} }
cout << "Master: " << _fd << "\n"; cout << "Master: " << _fd << "\n";
if (_fd < _min_fd) if (_fd < _min_fd)
_min_fd = _fd; _min_fd = _fd;
_amount++; _amount++;
return (EXIT_SUCCESS); return (EXIT_SUCCESS);
} }
void Socket::set_fds(void) { void Socket::set_fds(void) {
int child_fd; int child_fd;
FD_SET(_fd, &_readfds); FD_SET(_fd, &_readfds);
for (std::vector<Socket *>::iterator it = _childs.begin(); it < _childs.end(); for (std::vector<Socket *>::iterator it = _childs.begin(); it < _childs.end();
it++) { it++) {
child_fd = (*it)->_fd; child_fd = (*it)->_fd;
FD_SET(child_fd, &_readfds); FD_SET(child_fd, &_readfds);
if (child_fd > _max_fd) if (child_fd > _max_fd)
_max_fd = child_fd; _max_fd = child_fd;
} }
} }
void Socket::refresh(Env *env) { void Socket::refresh(Env *env) {
int valread; int valread;
int addrlen = sizeof(_address); int addrlen = sizeof(_address);
char buffer[10000]; char buffer[10000];
if (FD_ISSET(_fd, &_readfds)) { if (FD_ISSET(_fd, &_readfds)) {
int new_socket = accept(_fd, (struct sockaddr *)&_address, int new_socket =
(socklen_t *)&addrlen); accept(_fd, (struct sockaddr *)&_address, (socklen_t *)&addrlen);
if (new_socket < 0) { if (new_socket < 0) {
cout << "Accept: " << strerror(errno) << "\n"; cout << "Accept: " << strerror(errno) << "\n";
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#ifdef __APPLE__ #ifdef __APPLE__
//fcntl(new_socket, F_GETNOSIGPIPE); // fcntl(new_socket, F_GETNOSIGPIPE);
fcntl(new_socket, F_SETFL, O_NONBLOCK); fcntl(new_socket, F_SETFL, O_NONBLOCK);
#endif #endif
cout << "New connection, socket fd is " << new_socket cout << "New connection, socket fd is " << new_socket
<< ", ip is : " << inet_ntoa(_address.sin_addr) << ", ip is : " << inet_ntoa(_address.sin_addr)
<< ", port : " << ntohs(_address.sin_port) << "\n"; << ", port : " << ntohs(_address.sin_port) << "\n";
_childs.push_back(new Socket(new_socket, this)); _childs.push_back(new Socket(new_socket, this));
} }
int child_fd; int child_fd;
for (std::vector<Socket *>::iterator it = _childs.begin(); it < _childs.end(); it++) { for (std::vector<Socket *>::iterator it = _childs.begin(); it < _childs.end();
child_fd = (*it)->_fd; it++) {
if (FD_ISSET(child_fd, &_readfds)) { child_fd = (*it)->_fd;
valread = read(child_fd, buffer, 10000); if (FD_ISSET(child_fd, &_readfds)) {
if (valread == 0) { valread = read(child_fd, buffer, 10000);
getpeername(child_fd, (struct sockaddr *)&_address, if (valread == 0) {
(socklen_t *)&addrlen); getpeername(child_fd, (struct sockaddr *)&_address,
cout << "Host disconnected, ip " << inet_ntoa(_address.sin_addr) (socklen_t *)&addrlen);
<< ", port " << ntohs(_address.sin_port) << "\n"; cout << "Host disconnected, ip " << inet_ntoa(_address.sin_addr)
delete (*it); << ", port " << ntohs(_address.sin_port) << "\n";
_childs.erase(it); delete (*it);
} else { _childs.erase(it);
buffer[valread] = '\0'; } else {
(*it)->answer(env, buffer); buffer[valread] = '\0';
} (*it)->answer(env, buffer);
} }
} }
}
} }
bool Socket::waitHeader() { bool Socket::waitHeader() {
if (_header.length() < 1) if (_tmp.length() < 1)
return false; return false;
std::vector<string> lines = split(header, '\r\n'); std::vector<string> lines = split(_tmp, '\n');
bool is_valid = false; bool is_valid = false;
for (std::vector<string>::iterator it = lines.begin(); for (std::vector<string>::iterator it = lines.begin(); it < lines.end();
it < lines.end(); it++) { it++) {
if (*it == "") if (*it == "\r")
is_valid = true; is_valid = true;
} }
if (!is_valid || lines.at(0) == "") if (!is_valid)
return false; return false;
std::vector<string> head = split(lines.at(0), ' '); _header = _tmp;
if ((head.at(0) != "GET" && head.at(0) != "POST" && head.at(0) != "DELETE") _tmp = "";
|| head.size() < 2) return true;
return false;
return true;
} }
int Socket::answer(Env *env, string request) { int Socket::answer(Env *env, string request) {
tmp += request; _tmp += request;
cout << "|===|request|===>"<< _request << "|===||\n"; cout << "|===|request|===>" << _tmp << "|===||\n";
if (_header == "") { if (_header == "") {
waitHeader(); waitHeader();
cout << "Bad request recieved\n"; }
return EXIT_FAILURE; std::vector<string> lines = split(_header, '\n');
} std::vector<string> head = split(lines.at(0), ' ');
std::vector<string> lines = split(_request, '\n'); string uri = head.at(1);
std::vector<string> head = split(lines.at(0), ' '); cout << uri << "\n";
string uri = head.at(1); string ret;
cout << uri << "\n"; std::stringstream answer;
string ret; answer << "HTTP/1.1";
std::stringstream answer;
answer << "HTTP/1.1"; Server *server = env->choose_server(_parent, split(lines.at(1), ' ').at(1));
Route *route = server->get_route(uri);
std::vector<string> headers;
Server *server = env->choose_server(_parent, split(lines.at(1), ' ').at(1)); if ((head.at(0) != "GET" && head.at(0) != "POST" && head.at(0) != "DELETE") ||
Route *route = server->get_route(uri); head.size() < 2)
std::vector<string> headers; send_answer("HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n");
if ((headers = route->getHeadersLst()).size() > 0) { else if ((headers = route->getHeadersLst()).size() > 0) {
if (std::find(headers.begin(), headers.end(), head.at(0)) == headers.end()) if (std::find(headers.begin(), headers.end(), head.at(0)) == headers.end())
send_answer("HTTP/1.1 405 Method Not Allowed"); send_answer("HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n");
} else if ((headers = server->getHeadersLst()).size() > 0) { } else if ((headers = server->getHeadersLst()).size() > 0) {
if (std::find(headers.begin(), headers.end(), head.at(0)) == headers.end()) if (std::find(headers.begin(), headers.end(), head.at(0)) == headers.end())
send_answer("HTTP/1.1 405 Method Not Allowed"); send_answer("HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n");
} }
string path = route->correctUri(uri); string path = route->correctUri(uri);
cout << "Path: " << path << "\n"; cout << "Path: " << path << "\n";
ret = route->getIndex(uri, path); ret = route->getIndex(uri, path);
if (ret == "") { if (ret == "") {
cout << "No index: lf file\n"; cout << "No index: lf file\n";
ret = read_file(path); ret = read_file(path);
} }
answer << (ret == "" ? " 404 Not Found\nContent-length: 0\n\n" : " 200 OK\n") << ret; answer << (ret == "" ? " 404 Not Found\r\nContent-length: 0\r\n\r\n" : " 200 OK\r\n")
cout << "|===|Answer|===>" << answer.str() << "|===||\n"; << ret;
send_answer(answer.str()); cout << "|===|Answer|===>" << answer.str() << "|===||\n";
_request = ""; send_answer(answer.str());
return EXIT_SUCCESS; _content = "";
_header = "";
return EXIT_SUCCESS;
} }
void Socket::send_answer(string msg) { void Socket::send_answer(string msg) {
#ifdef __linux__ #ifdef __linux__
send(_fd, msg.c_str(), msg.length(), MSG_NOSIGNAL); send(_fd, msg.c_str(), msg.length(), MSG_NOSIGNAL);
#elif __APPLE__ #elif __APPLE__
send(_fd, msg.c_str(), msg.length(), 0); send(_fd, msg.c_str(), msg.length(), 0);
#endif #endif
} }

6
srcs/tools.cpp

@ -219,8 +219,8 @@ string read_file(string path) {
std::getline(file, str); std::getline(file, str);
content += str + "\n"; content += str + "\n";
} }
ret << "Content-type: " << getMime(path) << "\n"; ret << "Content-type: " << getMime(path) << "\r\n";
ret << "Content-length: " << content.length(); ret << "Content-length: " << content.length() << "\r\n";
ret << "\n\n" << content; ret << "\r\n" << content;
return (ret.str()); return (ret.str());
} }

Loading…
Cancel
Save