Browse Source

save 220-11-4-3

test
nicolas-arnaud 2 years ago
parent
commit
b1f83df83a
  1. 4
      default.json
  2. 9
      srcs/load/Env.hpp
  3. 127
      srcs/load/Server.hpp
  4. 135
      srcs/load/Socket.hpp
  5. 6
      srcs/tools.cpp
  6. 7
      srcs/webserv.hpp

4
default.json

@ -4,12 +4,12 @@
"servers": [ "servers": [
{ {
"server_name": "localhost", "server_name": "localhost",
"listens": ["15000", "[::]:88"], "listens": ["80", "localhost:80", "localhost", "[::]:443"],
"return": "301 https://$host$uri" "return": "301 https://$host$uri"
}, },
{ {
"server_name": "localhost", "server_name": "localhost",
"listens": ["150005", "[::]:88"], "listens": ["8080"],
"root": "./public", "root": "./public",
"index": ["index.html"], "index": ["index.html"],
"locations": "locations":

9
srcs/load/Env.hpp

@ -3,7 +3,7 @@
class Env { class Env {
//int _max_clients; //int _max_clients;
std::vector<Server *> _servers; std::vector<Server> _servers;
public: public:
Env(JSONNode *conf) { Env(JSONNode *conf) {
JSONList servers = conf->obj()["servers"]->lst(); JSONList servers = conf->obj()["servers"]->lst();
@ -11,17 +11,16 @@ class Env {
string th[8]= {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eigth"}; string th[8]= {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eigth"};
for (std::vector<JSONNode *>::iterator it = servers.begin(); for (std::vector<JSONNode *>::iterator it = servers.begin();
it < servers.end(); it++) { it < servers.end(); it++) {
Server *server = new Server(*it); Server server(*it);
server->launch();
_servers.push_back(server); _servers.push_back(server);
//delete *it; //delete *it;
cout << th[i] << " server launched.\n"; cout << th[i] << " server launched.\n";
i++; i++;
} }
while(1) { while(1) {
for (std::vector<Server *>::iterator it = _servers.begin(); for (std::vector<Server>::iterator it = _servers.begin();
it < _servers.end(); it++) { it < _servers.end(); it++) {
(*it)->check(); (*it).check();
} }
} }
//delete conf; //delete conf;

127
srcs/load/Server.hpp

@ -1,138 +1,33 @@
#include "../webserv.hpp" #include "../webserv.hpp"
#include "Route.hpp" #include "Route.hpp"
#include "Socket.hpp"
class Server { class Server {
string _name; string _name;
std::vector<string> _listens; std::vector<Socket> _sockets;
int _port;
std::map<string, Route *> _routes; std::map<string, Route *> _routes;
int _master_socket;
struct sockaddr_in _address;
public: public:
Server(JSONNode *server) { Server(JSONNode *server) {
_port = 80;
JSONObject datas = server->obj(); JSONObject datas = server->obj();
if (datas["server_name"]) if (datas["server_name"])
_name = datas["server_name"]->str(); _name = datas["server_name"]->str();
if (datas["listens"]) { if (datas["listens"]) {
JSONList listens = datas["listens"]->lst(); JSONList listens = datas["listens"]->lst();
for (JSONList::iterator i = listens.begin(); i < listens.end(); i++) for (JSONList::iterator i = listens.begin(); i < listens.end(); i++) {
_listens.push_back((*i)->str()); //_listens.push_back((*i)->str());
_port = std::atoi(_listens.front().c_str()); Socket sock((*i)->str());
} _sockets.push_back(sock);
//_routes["default"] = new Route(datas["root"], datas["return"], datas["index"], datas["autoindex"]);
}
void launch() {
int opt = 1;
_master_socket = socket(AF_INET, SOCK_STREAM, 0);
if (_master_socket == 0) {
cout << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
if (setsockopt(_master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
sizeof(opt)) < 0) {
cout << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
_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) {
cout << strerror(errno) << "\n";
exit(EXIT_FAILURE);
} }
cout << "Listener on port " << _port << "\n"; //_port = std::atoi(_listens.front().c_str());
if (listen(_master_socket, 3) < 0) {
cout << strerror(errno) << "\n";
exit(EXIT_FAILURE);
} }
//_routes["default"] = new Route(datas["root"], datas["return"], datas["index"], datas["autoindex"]);
cout << "Waiting for connections ..." << "\n";
} }
void check() { void check() {
int new_socket, activity, i, valread, sd; for (std::vector<Socket>::iterator it = _sockets.begin(); it < _sockets.end(); it++){
char buffer[30000]; (*it).check();
char _404[72] =
"HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!";
int max_clients = 30;
int client_socket[30];
fd_set readfds;
int max_sd = _master_socket;
int addrlen = sizeof(_address);
for (i = 0; i < max_clients; i++)
client_socket[i] = 0;
FD_ZERO(&readfds);
FD_SET(_master_socket, &readfds);
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;
}
activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);
if ((activity < 0) && (errno != EINTR))
cout << strerror(errno) << "\n";
if (FD_ISSET(_master_socket, &readfds)) {
if ((new_socket = accept(_master_socket, (struct sockaddr *)&_address,
(socklen_t *)&addrlen)) < 0) {
cout << 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";
for (i = 0; i < max_clients; i++) {
if (client_socket[i] == 0) {
client_socket[i] = new_socket;
cout << "Adding to list of sockets as " << i
<< "\n";
break;
} }
} }
}
for (i = 0; i < max_clients; i++) {
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);
cout << "Host disconnected, ip "
<< inet_ntoa(_address.sin_addr) << ", port "
<< ntohs(_address.sin_port) << "\n";
close(sd);
client_socket[i] = 0;
} else
#ifdef __linux__
send(sd, _404, strlen(_404), MSG_NOSIGNAL);
#elif __APPLE__
send(sd, _404, strlen(_404), 0);
#endif
}
}
}
}; };

135
srcs/load/Socket.hpp

@ -0,0 +1,135 @@
#include "../webserv.hpp"
class Socket {
string _ip;
int _port;
int _master_socket;
struct sockaddr_in _address;
int _max_clients;
int _client_socket[30];
public:
Socket(string def) {
size_t split = def.rfind(':');
string tmp = def.substr(0, split - 1);
_ip = isInt(tmp) ? "localhost" : tmp;
tmp = def.substr(split + 1, def.length() - split - 1).c_str();
_port = !isInt(tmp) ? 80 : std::atoi(tmp.c_str());
_max_clients = 30;
int opt = 1;
_master_socket = socket(AF_INET, SOCK_STREAM, 0);
if (_master_socket == 0) {
cout << "Socket creation: " << strerror(errno) << "\n";
exit(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";
exit(EXIT_FAILURE);
}
_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) {
cout << "Bind: " << strerror(errno) << "\n";
cout << "Socket destroyed!\n";
return ;
exit(EXIT_FAILURE);
}
cout << "Listener on port " << _port << "\n";
if (listen(_master_socket, 3) < 0) {
cout << "Listen: " << strerror(errno) << "\n";
exit(EXIT_FAILURE);
}
for (int i = 0; i < _max_clients; i++)
_client_socket[i] = 0;
}
void check() {
int new_socket, activity, i, valread, sd;
char buffer[1024];
char r404[72] = "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!";
fd_set readfds;
int max_sd = _master_socket;
int addrlen = sizeof(_address);
FD_ZERO(&readfds);
FD_SET(_master_socket, &readfds);
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;
}
activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);
if ((activity < 0) && (errno != EINTR))
cout << "Select: " << strerror(errno) << "\n";
if (FD_ISSET(_master_socket, &readfds)) {
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";
for (i = 0; i < _max_clients; i++) {
if (_client_socket[i] == 0) {
_client_socket[i] = new_socket;
cout << "Adding to list of sockets as " << i << "\n";
break;
}
}
}
cout << "Socket: " << _ip << ":" << _port << "\n";
for (i = 0; i < _max_clients; i++) {
sd = _client_socket[i];
if (FD_ISSET(sd, &readfds)) {
cout << "Client " << i << ": set\n";
valread = read(sd, buffer, 1024);
if (valread == 0) {
getpeername(sd, (struct sockaddr *)&_address,
(socklen_t *)&addrlen);
cout << "Host disconnected, ip "
<< inet_ntoa(_address.sin_addr) << ", port "
<< ntohs(_address.sin_port) << "\n";
close(sd);
_client_socket[i] = 0;
} else {
cout << buffer << "\n";
#ifdef __linux__
send(sd, r404, strlen(r404), MSG_NOSIGNAL);
#elif __APPLE__
send(sd, r404, strlen(r404), 0);
#endif
}
}
}
}
/*
Socket& operator=(Socket &src) {
_ip = src._ip;
_port = src._port;
_master_socket = src._master_socket;
_address = src._address;
return src;
}
*/
};

6
srcs/tools.cpp

@ -10,3 +10,9 @@ void *ft_memset(void *b, int c, size_t len) {
*(unsigned char *)(b_cpy + i++) = (unsigned char)c; *(unsigned char *)(b_cpy + i++) = (unsigned char)c;
return ((void *)b); return ((void *)b);
} }
bool isInt(string str) {
for (string::iterator it = str.begin(); it < str.end(); it++)
if (*it < '0' || *it > '9') return false;
return true;
}

7
srcs/webserv.hpp

@ -7,6 +7,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <cctype>
#include <cerrno> #include <cerrno>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
@ -16,11 +17,13 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
#include "json/Parser.hpp"
#include "load/Env.hpp"
using std::string; using std::string;
using std::cout; using std::cout;
using std::strerror; using std::strerror;
void *ft_memset(void *b, int c, size_t len); void *ft_memset(void *b, int c, size_t len);
bool isInt(string str);
#include "json/Parser.hpp"
#include "load/Env.hpp"

Loading…
Cancel
Save