#ifndef WEBSERV_HPP # define WEBSERV_HPP # include # include # include // exception, what # include // runtime_error, invalid_argument # include // epoll # include // fcntl # include // waitpid # include // signal # include // ifstream # include // stringstream # include // errno # include // close, access # include // cout, cin # include // memset # include // socket, accept, listen, send, recv, bind, connect, setsockopt, getsockname # include // htonl, htons, ntohl, ntohs, inet_addr, inet_ntoa # include // sockaddr_in, struct in_addr // # include // usefull for what ? -> 'man (7) ip' says it's a superset of 'netinet/in.h' # include // find # include // string # include // perror, remove # include // strtol, strtoul # include // opendir() # include // isalpha, local # include "Client.hpp" # include "ServerConfig.hpp" # include "utils.hpp" # include "http_status.hpp" # include "autoindex.hpp" # include "colors.h" extern bool g_run; extern int g_last_signal; void signal_handler(int signum); // these might only be TMP # define FAILURE -1 # define SUCCESS 1 # define MIME_TYPE_DEFAULT "application/octet-stream" class Webserv { public: // base.cpp Webserv(); // Webserv(Webserv const &src); // what should it take as arg, *, &, ? // Webserv(std::vector& servers); ~Webserv(); // Webserv &operator=(Webserv const &rhs); // init.cpp void init_virtual_servers(std::vector* servers); // run_loop.cpp void run(); private: int _epfd; std::vector _listen_sockets; std::vector _servers; std::vector _clients; std::map _http_status; std::map _mime_types; // accept.cpp void _accept_connection(listen_socket &lsocket); std::map _extract_infos(struct sockaddr_in addr); // request.cpp void _request(Client *client); int _read_request(Client *client); // response.cpp void _response(Client *client); int _send_response(Client *client); void _append_base_headers(Client *client); void _construct_response(Client *client); void _process_method(Client *client, std::string &path); std::string _replace_url_root(Client *client, std::string path); void _insert_status_line(Client *client); void _error_html_response(Client *client); void _append_body(Client *client, const std::string &body, const std::string &file_extension = ""); // method_get.cpp void _get(Client *client, std::string &path); void _get_file(Client *client, const std::string &path); void _autoindex(Client *client, const std::string &path); std::string _determine_file_extension(const std::string &path) const; // method_post.cpp void _post(Client *client, const std::string &path); void _upload_files(Client *client); // method_delete.cpp void _delete(Client *client, const std::string &path); void _delete_file(Client *client, const std::string &path); // epoll_update.cpp int _epoll_update(int fd, uint32_t events, int op); int _epoll_update(int fd, uint32_t events, int op, void *ptr); // signal.cpp void _handle_last_signal(); // close.cpp void _close_client(int fd); void _close_all_clients(); void _close_all_clients_fd(); void _close_all_clients_cgi_fd(); void _close_cgi_pipe_rfd(int fd); void _close_all_cgi_pipe_rfd(); void _close_all_listen_sockets(); void _reopen_lsocket(std::vector::iterator it); void _handle_epoll_error_lsocket(uint32_t events, std::vector::iterator it); void _handle_epoll_error_client(uint32_t events, int fd); // init.cpp void _bind(int socket_fd, in_port_t port, std::string host); void _listen(int socket_fd, unsigned int max_connections); void _init_http_status_map(); void _init_mime_types_map(); // timeout.cpp void _timeout(); // cgi.cpp bool _is_cgi(Client *client, std::string path); size_t _cgi_pos(Client *client, std::string &path, size_t pos); void _exec_cgi(Client *client); void _set_env_vector(Client *client, std::vector &env_vector); void _set_env_cstr(char *env_cstr[], std::vector &env_vector); std::string _dup_env(std::string var, std::string val); std::string _dup_env(std::string var, int i); void _exec_script(Client *client, char *env[]); void _check_script_output(Client *client, std::string & output); void _check_script_status(Client *client, std::string & output); size_t _check_script_fields(const std::string & output, size_t status); void _check_fields_duplicates(Client *client, std::string & output); void _add_script_body_length_header(std::string & output); void _remove_body_leading_empty_lines(std::string & output); Client *_find_cgi_fd(int cgi_fd); void _read_cgi_output(Client *client); void _handle_epoll_error_cgi_fd(uint32_t events, Client *client); void _cgi_epollhup(uint32_t events, Client *client); /////////////////////// class ExecFail : public std::exception { public : virtual const char* what() const throw() { return ("Exec CGI fail"); }; }; }; #endif /* HTTP Semantics: https://www.rfc-editor.org/rfc/rfc9110.html https://www.bortzmeyer.org/9110.html https://www.bortzmeyer.org/cours-http-cnam.html HTTP/1.1: https://www.rfc-editor.org/rfc/rfc9112.html https://www.bortzmeyer.org/9112.html CGI: https://www.rfc-editor.org/rfc/rfc3875.html */