Files
42_INT_12_webserv/srcs/webserv/Webserv.hpp

174 lines
5.8 KiB
C++

#ifndef WEBSERV_HPP
# define WEBSERV_HPP
# include <map>
# include <vector>
# include <exception> // exception, what
# include <stdexcept> // runtime_error, invalid_argument
# include <sys/epoll.h> // epoll
# include <fcntl.h> // fcntl
# include <sys/wait.h> // waitpid
# include <csignal> // signal
# include <fstream> // ifstream
# include <sstream> // stringstream
# include <cerrno> // errno
# include <unistd.h> // close, access
# include <iostream> // cout, cin
# include <cstring> // memset
# include <sys/socket.h> // socket, accept, listen, send, recv, bind, connect, setsockopt, getsockname
# include <arpa/inet.h> // htonl, htons, ntohl, ntohs, inet_addr, inet_ntoa
# include <netinet/in.h> // sockaddr_in, struct in_addr
// # include <netinet/ip.h> // usefull for what ? -> 'man (7) ip' says it's a superset of 'netinet/in.h'
# include <algorithm> // find
# include <string> // string
# include <cstdio> // perror, remove
# include <cstdlib> // strtol, strtoul
# include <dirent.h> // opendir()
# include <locale> // 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<ServerConfig>& servers);
~Webserv();
// Webserv &operator=(Webserv const &rhs);
// init.cpp
void init_virtual_servers(std::vector<ServerConfig>* servers);
// run_loop.cpp
void run();
private:
int _epfd;
std::vector<listen_socket> _listen_sockets;
std::vector<ServerConfig> _servers;
std::vector<Client> _clients;
std::map<int, std::string> _http_status;
std::map<std::string, std::string> _mime_types;
// accept.cpp
void _accept_connection(listen_socket &lsocket);
std::map<std::string, std::string>
_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_client_cgi_pipes(Client *client);
void _close_all_clients();
void _close_all_clients_fd();
void _close_all_clients_cgi_pipes();
void _close_all_listen_sockets();
void _reopen_lsocket(std::vector<listen_socket>::iterator it);
void _handle_epoll_error_lsocket(uint32_t events, std::vector<listen_socket>::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 _cgi_open_pipes(Client *client);
void _exec_cgi(Client *client);
void _set_env_vector(Client *client, std::vector<std::string> &env_vector);
void _set_env_cstr(char *env_cstr[], std::vector<std::string> &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);
unsigned int
_check_script_fields(const std::string & output, unsigned int 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);
// cgi_epoll.cpp
void _read_cgi_output(Client *client);
void _handle_epollerr_cgi_output(uint32_t events, Client *client);
void _handle_epollhup_cgi_output(uint32_t events, Client *client);
void _cgi_input_ready(Client *client);
void _handle_epollerr_cgi_input(uint32_t events, Client *client);
Client *_find_cgi_output_fd(int fd);
Client *_find_cgi_input_fd(int fd);
///////////////////////
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
*/