#include "Client.hpp" /********************************************* * COPLIENS *********************************************/ Client::Client() : fd(0), lsocket(NULL), status(0), header_complete(false), read_body_size(0), assigned_server(NULL), assigned_location(NULL) { return; } Client::~Client() { return; } // copy constructor : // Client::Client( Client const & src ) {} // assignement operator : // Client & Client::operator=( Client const & rhs ) {} /********************************************* * 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::string sub; std::vector list; size_t pos; pos = (raw_request).find(CRLF CRLF); sub = (raw_request).substr(0, pos); list = split(sub, '\n'); // request_line _parse_request_line(*list.begin()); list.erase(list.begin()); // headers _parse_request_headers(list); //body- message _parse_request_body(pos + 4); // add "raw_request.clear()" after parsing ? for little less memory usage ? } 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() { _request.method = UNKNOWN; _request.path.clear(); _request.version.clear(); _request.headers.clear(); _request.body.clear(); } http_method Client::get_method() { return _request.method; } std::string &Client::get_path() { return _request.path; } std::string &Client::get_version() { return _request.version; } std::string &Client::get_body() { return _request.body; } std::string &Client::get_headers(const std::string &key) { return _request.headers[key]; } /********************************************* * PRIVATE MEMBER FUNCTIONS *********************************************/ void Client::_parse_request_line( std::string rline ) { std::vector sline; std::string tmp; sline = split(rline, ' '); if (sline.size() != 3) { std::cerr << "err _parse_request_line(): "; throw std::runtime_error("bad request-line header"); } // method tmp = ::trim(sline[0], ' '); tmp = ::trim(tmp, '\r'); _request.method = str_to_http_method(tmp); // TODO uri in request_line // https://www.rfc-editor.org/rfc/rfc7230#section-5.3 // https://stackoverflow.com/questions/40311306/when-is-absoluteuri-used-from-the-http-request-specs tmp = ::trim(sline[1], ' '); tmp = ::trim(tmp, '\r'); _request.path = tmp; // http version tmp = ::trim(sline[2], ' '); tmp = ::trim(tmp, '\r'); _request.version = tmp; } void Client::_parse_request_headers( std::vector list ) { std::string key; std::string val; std::vector::iterator it; size_t pos; for (it = list.begin(); it != list.end(); it++) { pos = (*it).find(':'); key = (*it).substr( 0, pos ); key = ::trim(key, ' '); key = ::trim(key, '\r'); val = (*it).substr( pos + 1 ); val = ::trim(val, ' '); val = ::trim(val, '\r'); _request.headers.insert( std::pair(key, val) ); } } void Client::_parse_request_body( size_t pos ) { // TODO : a revoir avec une std::string, // pour ne pas avoir le probleme d'un '0' qui marque la fin des données std::string body = &raw_request[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; }