#include "Webserv.hpp" #define BUFSIZE 8192 void Webserv::_request(Client *client) { _read_request(client); if (g_last_signal) _handle_last_signal(); } void Webserv::_read_request(Client *client) { char buf[BUFSIZE+1]; ssize_t ret; std::cerr << "recv()\n"; ret = ::recv(client->fd, buf, BUFSIZE, 0); if (ret == -1) { std::perror("err recv()"); std::cerr << "client ptr =" << client << "\n"; // DEBUG std::cerr << "client.fd =" << client->fd << "\n"; // DEBUG _close_client(client->fd); return ; } /* if (ret == BUFSIZE) // send error like "request too long" to client */ buf[ret] = '\0'; client->raw_request.append(buf); _parse_request(client); _epoll_update(client->fd, EPOLLOUT, EPOLL_CTL_MOD, client); } // 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 Webserv::_parse_request(Client *client) { std::string sub; std::vector list; size_t pos; pos = (client->raw_request).find("\r\n\r\n"); sub = (client->raw_request).substr(0, pos); list = split(sub, '\n'); // request_line _parse_request_line(client, *list.begin()); list.erase(list.begin()); // headers _parse_request_headers(client, list); // message-body client->request.insert( std::pair("Body-Message", &client->raw_request[pos + 4]) ); // TMP DEBUG // std::map::iterator itm; // std::map::iterator itm_end; // std::cout << "\n====== REQUEST HEADERS\n"; // for (itm = client->request.begin(), itm_end = client->request.end(); itm != itm_end; itm++) // std::cout << "[" << itm->first << "] [" << itm->second << "]\n"; // std::cout << "\n====== END\n"; } void Webserv::_parse_request_line(Client *client, 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'); client->request.insert( std::pair("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'); client->request.insert( std::pair("Request-URI", tmp) ); // http version tmp = ::trim(sline[2], ' '); tmp = ::trim(tmp, '\r'); client->request.insert( std::pair("HTTP-Version", tmp) ); } void Webserv::_parse_request_headers ( Client *client , 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'); client->request.insert( std::pair(key, val) ); } }