#include "Client.hpp" /********************************************* * COPLIENS *********************************************/ Client::Client() : status(0), header_complete(false), read_body_size(0), assigned_server(NULL), assigned_location(NULL), _fd(0), _port(""), _ip(""), _lsocket(NULL) { return; } Client::Client(int afd, listen_socket *lsocket, std::string aport, std::string aip) : status(0), header_complete(false), read_body_size(0), assigned_server(NULL), assigned_location(NULL), _fd(afd), _port(aport), _ip(aip), _lsocket(lsocket) { return; } Client::~Client() { return; } // WIP not sure fo what is more logic here Client::Client( Client const & src ) : status ( src.status ), header_complete ( src.header_complete ), read_body_size ( src.read_body_size ), assigned_server ( src.assigned_server ), assigned_location ( src.assigned_location ), _fd ( src._fd ), _port ( src._port ), _ip ( src._ip ), _lsocket ( src._lsocket ) { raw_request = src.raw_request; response = src.response; // buf = strdup(src.buf); // TODO: this doesn't work return; } // WIP placeholder because of const values Client & Client::operator=( Client const & rhs ) { if ( this != &rhs ) { // stuff } return *this; } /********************************************* * PUBLIC MEMBER FUNCTIONS *********************************************/ // http headers : // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers // https://www.ibm.com/docs/en/cics-ts/5.3?topic=protocol-http-requests // https://www.tutorialspoint.com/http/http_requests.htm void Client::parse_request() { std::map headers; std::string body; // DEBUG std::cout << "\nREQUEST ____________\n" << raw_request << "\n_____________\n"; _parse_request_line(); _parse_request_headers(); _parse_request_body(); _parse_port_hostname(this->get_rq_headers("Host")); raw_request.clear(); } bool Client::fill_script_path(std::string script) { size_t pos; int len = script.size(); std::string path = this->get_rq_abs_path(); std::string tmp; pos = path.find(script); if (pos == 0) { tmp = path.substr(0, pos + len); _request.script.path = "./srcs" + tmp; // TODO: root path ? _request.script.info = path.substr(pos + len); return true; } return false; } void Client::clear() { clear_request(); header_complete = false; read_body_size = 0; assigned_server = NULL; assigned_location = NULL; raw_request.clear(); response.clear(); status = 0; } void Client::clear_request() { clear_script(); _request.method = UNKNOWN; _request.uri.clear(); _request.version.clear(); _request.headers.clear(); _request.body.clear(); _request.abs_path.clear(); _request.query.clear(); _request.port.clear(); _request.hostname.clear(); } void Client::clear_script() { _request.script.path.clear(); _request.script.info.clear(); } /********************************************* * GETTERS *********************************************/ // client side int Client::get_cl_fd() const { return _fd; } const std::string & Client::get_cl_ip() const { return _ip; } const std::string & Client::get_cl_port() const { return _port; } const listen_socket * Client::get_cl_lsocket() const { return _lsocket; } // requette http_method Client::get_rq_method() const { return _request.method; } std::string Client::get_rq_method_str() const { return ::http_methods_to_str(_request.method); } std::string Client::get_rq_uri() const { return _request.uri; } std::string Client::get_rq_abs_path() const { return _request.abs_path; } std::string Client::get_rq_query() const { return _request.query; } std::string Client::get_rq_version() const { return _request.version; } std::string Client::get_rq_body() const { return _request.body; } std::string Client::get_rq_port() const { return _request.port; } std::string Client::get_rq_hostname() const { return _request.hostname; } std::string Client::get_rq_script_path()const { return _request.script.path; } std::string Client::get_rq_script_info()const { return _request.script.info; } std::string Client::get_rq_headers(const std::string & key) const { std::map::const_iterator it; it = _request.headers.find(::str_tolower(key)); if (it == _request.headers.end()) return ""; return it->second; } /********************************************* * PRIVATE MEMBER FUNCTIONS *********************************************/ void Client::_parse_request_line() { std::vector line; int ret; ret = ::parse_http_first_line(raw_request, line); if (ret != 3) { std::cerr << "err _parse_first_line(): wrong number of elements (" << ret << " instead of 3)\n"; status = 400; // "bad request" } else { _request.method = str_to_http_method(line[0]); _request.uri = line[1]; _parse_request_uri(line[1]); _request.version = line[2]; } } void Client::_parse_request_uri( std::string uri ) { size_t pos; pos = uri.find("?"); if (pos != std::string::npos) _request.query = uri.substr(pos + 1); else _request.query = ""; _request.abs_path = uri.substr(0, pos); } void Client::_parse_request_headers() { // TODO: check error and adjust status _request.headers = ::parse_http_headers(raw_request); } void Client::_parse_request_body() { // TODO: check error and adjust status _request.body = ::parse_http_body(raw_request); } void Client::_parse_port_hostname(std::string host) { size_t pos; if (host == "") std::cerr << "no host\n"; pos = host.find(':'); // port : if (pos == std::string::npos) _request.port = "4040"; // TODO: make equal to default port in config else _request.port = host.substr(pos); if (_request.port == ":") _request.port = ""; // hostname : _request.hostname = host.substr(0, pos); } /********************************************* * OVERLOAD *********************************************/ bool operator==(const Client& lhs, const Client& rhs) { return lhs.get_cl_fd() == rhs.get_cl_fd(); } bool operator==(const Client& lhs, int fd) { return lhs.get_cl_fd() == fd; } bool operator==(int fd, const Client& rhs) { return fd == rhs.get_cl_fd(); }