diff --git a/Makefile b/Makefile index a775cd8..221d18b 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,8 @@ CXXFLAGS += -MMD -MP #header dependencie VPATH = $(SRCS_D) -HEADERS_D = srcs +HEADERS_D = srcs \ + srcs/webserv SRCS_D = srcs \ srcs/webserv diff --git a/srcs/Client.cpp b/srcs/Client.cpp index e6c6f39..db3e2c8 100644 --- a/srcs/Client.cpp +++ b/srcs/Client.cpp @@ -113,4 +113,15 @@ void Client::_parse_request_body( size_t pos ) _request.body = body; } +/********************************************* + * OVERLOAD + *********************************************/ +bool operator==(const Client& lhs, const Client& rhs) + { return lhs.fd == rhs.fd; } + +bool operator==(const Client& lhs, int fd) + { return lhs.fd == fd; } + +bool operator==(int fd, const Client& rhs) + { return fd == rhs.fd; } diff --git a/srcs/ConfigParser.cpp b/srcs/ConfigParser.cpp index ad9257b..c63326b 100644 --- a/srcs/ConfigParser.cpp +++ b/srcs/ConfigParser.cpp @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/07/13 22:11:17 by me #+# #+# */ -/* Updated: 2022/07/31 13:18:14 by simplonco ### ########.fr */ +/* Updated: 2022/08/02 14:05:03 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -262,7 +262,7 @@ void ConfigParser::_set_server_values(ServerConfig *server, \ { for (unsigned long i = 0; i != tmp_val.size(); i++) { - MethodType m = _str_to_method_type(tmp_val[i]); + http_method m = _str_to_method_type(tmp_val[i]); if (m == 3) throw std::invalid_argument("not a valid method"); server->allow_methods.push_back(m); @@ -347,7 +347,7 @@ void ConfigParser::_set_location_values(LocationConfig *location, \ { for (unsigned long i = 0; i != tmp_val.size(); i++) { - MethodType m = _str_to_method_type(tmp_val[i]); + http_method m = _str_to_method_type(tmp_val[i]); if (m == 3) throw std::invalid_argument("not a valid method"); location->allow_methods.push_back(m); diff --git a/srcs/ConfigParser.hpp b/srcs/ConfigParser.hpp index 9ae1577..119e043 100644 --- a/srcs/ConfigParser.hpp +++ b/srcs/ConfigParser.hpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* ConfigParser.hpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: me +#+ +:+ +#+ */ +/* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/07/11 23:01:41 by me #+# #+# */ -/* Updated: 2022/07/27 19:27:57 by me ### ########.fr */ +/* Updated: 2022/08/02 14:05:30 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,7 +15,6 @@ # include "ServerConfig.hpp" # include "LocationConfig.hpp" -# include "MethodType.hpp" # include "utils.hpp" # include @@ -77,7 +76,7 @@ private: // why static? it's an enum... - static MethodType _str_to_method_type(std::string str); + static http_method _str_to_method_type(std::string str); diff --git a/srcs/ConfigParserUtils.cpp b/srcs/ConfigParserUtils.cpp index 861ae83..c9e483c 100644 --- a/srcs/ConfigParserUtils.cpp +++ b/srcs/ConfigParserUtils.cpp @@ -83,7 +83,7 @@ std::string ConfigParser::_get_rest_of_line(size_t *curr) } -MethodType ConfigParser::_str_to_method_type(std::string str) +http_method ConfigParser::_str_to_method_type(std::string str) { if (str == "GET") return GET; diff --git a/srcs/LocationConfig.hpp b/srcs/LocationConfig.hpp index 2a077f6..6db5d58 100644 --- a/srcs/LocationConfig.hpp +++ b/srcs/LocationConfig.hpp @@ -3,18 +3,16 @@ /* ::: :::::::: */ /* LocationConfig.hpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: me +#+ +:+ +#+ */ +/* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/07/23 16:08:00 by me #+# #+# */ -/* Updated: 2022/07/25 20:09:48 by me ### ########.fr */ +/* Updated: 2022/08/02 14:06:07 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef LOCATIONCONFIG_HPP # define LOCATIONCONFIG_HPP -# include "MethodType.hpp" - # include # include # include @@ -31,7 +29,7 @@ public: int client_body_limit; std::string root; std::vector index; - std::vector allow_methods; + std::vector allow_methods; std::map cgi_info; // wait if i can call several times, shouldn't it be a map? diff --git a/srcs/MethodType.hpp b/srcs/MethodType.hpp deleted file mode 100644 index 9c815f5..0000000 --- a/srcs/MethodType.hpp +++ /dev/null @@ -1,15 +0,0 @@ - - -#ifndef METHODTYPE_HPP -# define METHODTYPE_HPP - -enum MethodType -{ - GET, - POST, - DELETE, - INVALID, -}; - - -#endif diff --git a/srcs/Server.hpp b/srcs/Server.hpp deleted file mode 100644 index 7fcb4d9..0000000 --- a/srcs/Server.hpp +++ /dev/null @@ -1,21 +0,0 @@ - -#ifndef SERVER_HPP -# define SERVER_HPP - -# include -# include - -class Server -{ - public: - // Server(Placeholder); - // Server(); - // Server(Server const &src); - // ~Server(); - // Server &operator=(Server const &rhs); - - private: - -}; - -#endif diff --git a/srcs/ServerConfig.hpp b/srcs/ServerConfig.hpp index ce49255..dc658da 100644 --- a/srcs/ServerConfig.hpp +++ b/srcs/ServerConfig.hpp @@ -2,7 +2,7 @@ #ifndef SERVERCONFIG_HPP # define SERVERCONFIG_HPP -# include "MethodType.hpp" +# include "utils.hpp" # include "LocationConfig.hpp" # include @@ -42,7 +42,7 @@ public: // i'm tempted to do something diff for storing method types... // fuck it, you can only call allow_methods once in Server // once more in each location. - std::vector allow_methods; + std::vector allow_methods; std::vector locations; diff --git a/srcs/Webserv_hugo.cpp b/srcs/Webserv_hugo.cpp deleted file mode 100644 index e373ffa..0000000 --- a/srcs/Webserv_hugo.cpp +++ /dev/null @@ -1,447 +0,0 @@ - -#include "Webserv.hpp" - -int g_last_signal; -bool g_run; -void signal_handler(int signum) -{ - g_last_signal = signum; -} - -Webserv::Webserv() -{ - std::cerr << "Server init\n"; - - _epfd = ::epoll_create1(0); // (EPOLL_CLOEXEC) for CGI fork ? - if (_epfd == -1) - { - std::perror("err epoll_create1()"); - throw std::runtime_error("Epoll init"); - } - - std::signal(SIGPIPE, signal_handler); - std::signal(SIGINT, signal_handler); -} - -/* Webserv::Webserv(Webserv const &src) -{ - -} */ - -Webserv::~Webserv() -{ - close(_socket_fd); - close(_epfd); - _close_all_clients(); - std::cerr << "Server destroyed\n"; -} - -/* Webserv & Webserv::operator=(Webserv const &rhs) -{ - -} */ - - /////////////// - // Functions // - -void Webserv::init_virtual_servers() // ADD config param -{ - _socket_fd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); // (SOCK_CLOEXEC) for CGI fork ? - if (_socket_fd == -1) - { - std::perror("err socket()"); - throw std::runtime_error("Socket init"); - } - // HUGO ADD - // allow socket descriptor to be reuseable - int on = 1; - if (setsockopt(_socket_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) - { - ::perror("setsockopt() failed"); - throw std::runtime_error("Socket init"); - } - // HUGO ADD END - - _bind(_socket_fd, 4040); - _listen(_socket_fd, 512); // 512 arbitrary - - if (_epoll_update(_socket_fd, EPOLLIN, EPOLL_CTL_ADD) == -1) - throw std::runtime_error("Socket init"); -} - -void Webserv::start() -{ - std::cerr << "Server started\n"; - struct epoll_event events[MAX_EVENTS]; - int nfds; - int i; - int count_loop = 0; - - g_run = true; - while (g_run) - { - std::cerr << ++count_loop << "----loop epoll()\n"; - nfds = ::epoll_wait(_epfd, events, MAX_EVENTS, TIMEOUT); - if (nfds == -1) - { - std::perror("err epoll_wait(): "); - throw std::runtime_error("Epoll wait"); - } - else if (nfds == 0) - { - if (!_clients.empty()) - { - std::cerr << "Timeout " << TIMEOUT << "ms\n"; - _close_all_clients(); - } - } - i = 0; - while (i < nfds) - { - // if ((events[i].data.u32 == SERVER_FD) && (events[i].events & EPOLLIN)) // Dont work, see "SERVER_FD" define - if ((events[i].data.fd == _socket_fd) && (events[i].events & EPOLLIN)) - _accept_connection(events[i].data.fd); - else if (events[i].events & EPOLLIN) - _read_request(static_cast(events[i].data.ptr)); - else if (events[i].events & EPOLLOUT) - _send_response(static_cast(events[i].data.ptr)); - ++i; - _actual_client = NULL; - } - } -} - - - /////////////////////// - // Private Functions // - -void Webserv::_accept_connection(int fd) -{ - struct sockaddr_in addr; - socklen_t addr_len; - int accepted_fd; - - std::cerr << "accept()\n"; - addr_len = sizeof addr; - accepted_fd = ::accept(fd, (sockaddr*)&addr, &addr_len); - if (accepted_fd == -1) - { - std::perror("err accept(): "); - return ; - } - ::fcntl(accepted_fd, F_SETFL, O_NONBLOCK); - - _clients.push_back(Client()); - _clients.back().fd = accepted_fd; - - _epoll_update(accepted_fd, EPOLLIN, EPOLL_CTL_ADD, &_clients.back()); -} - - ////////// - // READ // -void Webserv::_read_request(Client *client) -{ - char buf[BUFSIZE+1]; - ssize_t ret; - _actual_client = client; - - std::cerr << "recv()\n"; - ret = ::recv(client->fd, buf, BUFSIZE, 0); - if (ret == -1) - { - std::perror("err recv(): "); - // if (g_last_signal) - // _handle_last_signal(); - // else - // _close_client(client->fd); - - std::cerr << "client ptr =" << client << "\n"; // DEBUG - std::cerr << "client.fd =" << client->fd << "\n"; // DEBUG - return ; - } - /* - if (ret == BUFSIZE) - // send error like "request too long" to client - */ - - buf[ret] = '\0'; - client->raw_request.append(buf); - - // HUGO TMP - // - _parse_request(client); - // - // HUGO TMP END - - _epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD, client); -} - - /////////// - // WRITE // -void Webserv::_send_response(Client *client) -{ - ssize_t ret; - _actual_client = client; - - std::cerr << "send()\n"; - std::cerr << "RAW_REQUEST\n|\n" << client->raw_request << "|\n"; - - - // TMP HUGO test cgi - // - // if "POST" found in _buf, execve a cgi - if (client->raw_request.find("POST") != std::string::npos) - _exec_cgi_script(client); - // if "index.html" found in _buf, send the page - if (client->raw_request.find("index.html") != std::string::npos) - _serve_file(client, "index.html"); - // - // TMP HUGO end test cgi - - - ret = ::send(client->fd, MSG_TEST, sizeof MSG_TEST - 1, 0); - if (ret == -1) - { - std::perror("err send(): "); - if (g_last_signal) - _handle_last_signal(); - // else - // _close_client(client->fd); - return ; - } - - _close_client(client->fd); - // if (client->raw_request.find("Connection: keep-alive") == std::string::npos) - // _close_client(client->fd); - // else - // _epoll_update(client->fd, EPOLLIN, EPOLL_CTL_MOD, client); - - client->raw_request.clear(); -} - - - //////////////////// - // Misc functions // - -int Webserv::_epoll_update(int fd, uint32_t events, int op) -{ - struct epoll_event ev; - std::memset(&ev, 0, sizeof ev); - ev.events = events; - ev.data.fd = fd; - if (::epoll_ctl(_epfd, op, fd, &ev) == -1) - { - std::perror("err _epoll_update(): "); - return (-1); - } - return (0); -} - -// TMP HUGO -// -void _parse_request(Client *client) -{ - std::string request = client->raw_request; - std::map field = client->request; -// size_t size = request.size(); - size_t begin = 0; - size_t end; - size_t len; - -// std::string str ("test un: deux\ntest deux: trois quatre\ntest :trois quatre cinq"); -// std::string sub; - - std::cout << str << "\n\n"; - - int i = 0; - while (end != std::string::npos) - { - // find first portion, before ':' - end = str.find(':', begin); - len = end - begin; - if (end == std::string::npos) - len = end; - sub = str.substr(begin, len); - std::cout << i << "|" << sub << "\n"; - // std::cout << "[begin:" << begin << " - end:" << end << " - len:" << len << "] " << sub << "\n"; - begin = end + 1; - - // find second portion, until '\n' - end = str.find('\n', begin); - len = end - begin; - if (end == std::string::npos) - len = end; - sub = str.substr(begin, len); - std::cout << i << "|" << sub << "\n"; - begin = end + 1; - i++; - } - -// for (size_t i = 0; i < size; i++) -// { -// field.insert(request); -// } - -// GET /home.html HTTP/1.1 -// Host: developer.mozilla.org -// User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0 -// Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 -// Accept-Language: en-US,en;q=0.5 -// Accept-Encoding: gzip, deflate, br -// Referer: https://developer.mozilla.org/testpage.html -// Connection: keep-alive -// Upgrade-Insecure-Requests: 1 -// If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT -// If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a" -// Cache-Control: max-age=0 - -} -void Webserv::_serve_file(Client *client, std::string page) -{ - int page_fd; - std::string to_send; - std::string end_header = "\r\n\r\n"; - std::string body; - std::stringstream strs; - char buffer[1]; - - to_send = "HTTP/1.1 200 OK\n"; - to_send += "Content-Type: text/html;\n"; - to_send += "Content-Length: "; - page_fd = open(page.c_str(), O_RDONLY); - for (int ret = 1; ret > 0;) - { - ret = read(page_fd, buffer, 1); - body += buffer; - } - strs << body.size(); - to_send += strs.str(); - to_send += end_header; - to_send += body; - if (::send(client->fd, to_send.c_str(), to_send.size(), 0) == -1) - std::perror("err send()"); -} -void Webserv::_exec_cgi_script(Client *client) -{ - int save_stdout; - char** env = new char*[5]; - char * const * nll = NULL; - - // set env - env[0] = strdup("PATH_INFO=/no"); - env[1] = strdup("REQUEST_METHOD=POST"); - env[2] = strdup("SERVER_PROTOCOL=HTTP/1.1"); - env[3] = strdup("CONTENT_LENGTH=665"); - env[4] = NULL; - // save STDOUT - save_stdout = dup(STDOUT_FILENO); - // inside child process - if (fork() == 0) - { - dup2(client->fd, STDOUT_FILENO); -// execve("./srcs/cgi-bin/cgi_cpp.cgi", nll, env); - execve("./srcs/cgi-bin/php-cgi", nll, env); - } - // inside parent process - else - waitpid(-1, NULL, 0); - // restore stdout - dup2(save_stdout, STDOUT_FILENO); -} -// -// END TMP HUGO - -int Webserv::_epoll_update(int fd, uint32_t events, int op, void *ptr) -{ - struct epoll_event ev; - std::memset(&ev, 0, sizeof ev); - ev.events = events; - ev.data.ptr = ptr; - if (::epoll_ctl(_epfd, op, fd, &ev) == -1) - { - std::perror("err _epoll_update(): "); - return (-1); - } - return (0); -} - -void Webserv::_handle_last_signal() -{ - if (g_last_signal == SIGPIPE) - { - std::cerr << "SIGPIPE\n"; - if (_actual_client) - { - _close_client(_actual_client->fd); - _actual_client = NULL; - } - } - else if (g_last_signal == SIGINT) - { - g_run = false; - } - g_last_signal = 0; -} - -void Webserv::_close_client(int fd) -{ - std::vector::iterator it = _clients.begin(); - while (it != _clients.end()) - { - if (it->fd == fd) - { - // _epoll_update(fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG - if (::close(fd) == -1) - std::perror("err close(): "); - else - std::cerr << "close fd " << fd << "\n"; - _clients.erase(it); - break; - } - ++it; - } -} - -void Webserv::_close_all_clients() -{ - while (!_clients.empty()) - { - // _epoll_update(_clients.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG - if (::close(_clients.back().fd) == -1) - std::perror("err close(): "); - else - std::cerr << "close fd " << _clients.back().fd << "\n"; - _clients.pop_back(); - } -} - - - //////////////////// - // Init functions // - -void Webserv::_bind(int socket_fd, in_port_t port) -{ - // cast invalid ? how to ? - // const struct sockaddr* cast_test = static_cast(addr); - - struct sockaddr_in addr; - std::memset(&addr, 0, sizeof addr); - addr.sin_family = AF_INET; - addr.sin_port = ::htons(port); - addr.sin_addr.s_addr = ::htonl(INADDR_ANY); // htonl useless with 0 value (INADDR_ANY) ? - - if (::bind(socket_fd, (const sockaddr*)&addr, sizeof addr) == -1) - { - std::perror("err bind(): "); - throw std::runtime_error("Socket bind"); - } -} - -void Webserv::_listen(int socket_fd, unsigned int max_connections) -{ - if (::listen(socket_fd, max_connections) == -1) - { - std::perror("err listen(): "); - throw std::runtime_error("Socket listen"); - } -} diff --git a/srcs/ft_itoa.cpp b/srcs/ft_itoa.cpp deleted file mode 100644 index 90f6ff7..0000000 --- a/srcs/ft_itoa.cpp +++ /dev/null @@ -1,13 +0,0 @@ - -# include -# include - -char* itoa(int n) -{ - std::stringstream strs; - char * str; - - strs << n; - str = (char*)(strs.str().c_str()); - return (str); -} diff --git a/srcs/utils.hpp b/srcs/utils.hpp index a2e2409..70b16c5 100644 --- a/srcs/utils.hpp +++ b/srcs/utils.hpp @@ -7,6 +7,14 @@ # include # include // atoi +enum http_method +{ + GET = 1, + POST, + DELETE, + INVALID, +}; + std::vector split(std::string input, char delimiter); bool isNumeric(std::string str); bool isNumeric_btw(int low, int high, std::string str); diff --git a/srcs/Webserv.hpp b/srcs/webserv/Webserv.hpp similarity index 91% rename from srcs/Webserv.hpp rename to srcs/webserv/Webserv.hpp index 6b858a4..193b57d 100644 --- a/srcs/Webserv.hpp +++ b/srcs/webserv/Webserv.hpp @@ -29,30 +29,10 @@ # include "ServerConfig.hpp" # include "utils.hpp" -// TODO: A virer -//# include "ConfigParser.hpp" -//# include "LocationConfig.hpp" -//# include "MethodType.hpp" -//# include "utils.hpp" -// TODO: A virer - extern bool g_run; extern int g_last_signal; void signal_handler(int signum); -/* enum // WIP test -{ - SERVER_FD = 1, - CLIENT_FD -}; - -struct s // WIP test -{ - int fd; - Client *ptr; -}; - */ - // these might only be TMP # define FAILURE -1 # define SUCCESS 1 diff --git a/srcs/webserv/response.cpp b/srcs/webserv/response.cpp index da818e7..0e97c6c 100644 --- a/srcs/webserv/response.cpp +++ b/srcs/webserv/response.cpp @@ -84,7 +84,7 @@ void Webserv::_insert_status_line(Client *client) client->response.insert(0, status_line); } -#define ROOT "website" +#define ROOT "www" #define INDEX "index.html" #define MAX_FILESIZE 1000000 // (1Mo) void Webserv::_get_ressource(Client *client) diff --git a/srcs/webserv/run_loop.cpp b/srcs/webserv/run_loop.cpp index 215e4f9..7f93043 100644 --- a/srcs/webserv/run_loop.cpp +++ b/srcs/webserv/run_loop.cpp @@ -4,14 +4,6 @@ #define MAX_EVENTS 42 // arbitrary #define TIMEOUT 3000 -// Temp. To move in other file -bool operator==(const Client& lhs, const Client& rhs) - { return lhs.fd == rhs.fd; } -bool operator==(const Client& lhs, int fd) - { return lhs.fd == fd; } -bool operator==(int fd, const Client& rhs) - { return fd == rhs.fd; } - void Webserv::run() { std::cerr << "Server started\n"; diff --git a/website/index.html b/website/index.html deleted file mode 100644 index bc65643..0000000 --- a/website/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - Le Webserv - - -

Le index (˘ ͜ʖ˘)

-
-

(˚3˚)

- - \ No newline at end of file diff --git a/www/index.html b/www/index.html index 7de0cd1..bc65643 100644 --- a/www/index.html +++ b/www/index.html @@ -1,16 +1,11 @@ - - - + Le Webserv - -

My First Heading

-

My first paragraph.

- +

Le index (˘ ͜ʖ˘)

+
+

(˚3˚)

- - - + \ No newline at end of file diff --git a/website/rfc2119_sigabrt.html b/www/rfc2119.html similarity index 100% rename from website/rfc2119_sigabrt.html rename to www/rfc2119.html diff --git a/website/rfc2119_no_link.html b/www/rfc2119_no_link.html similarity index 100% rename from website/rfc2119_no_link.html rename to www/rfc2119_no_link.html