#include "Helpers.hpp" #include "Main.hpp" #include #include #include #include // TODO: Remove boundary from the body. Do keep other stuff like // file type and name void HTTPrequest::processHTTPHeader() { std::shared_ptr self(shared_from_this()); // HEADER read asio::async_read_until( sock, buffer, "\r\n\r\n", // its not the other way bud [this, self](std::error_code error, std::size_t packageSize) { if (!error) { buffer.commit(packageSize); std::istream stream(&buffer); std::size_t octetCount = 0; // This is HTTP main request std::string rq; Helpers::getlineAndCount(stream, octetCount, requestType, ' '); // HTTP request type Helpers::getlineAndCount(stream, octetCount, requestPath, ' '); // HTTP path Helpers::getlineAndCount(stream, octetCount, rq); // Version, omitting for now // Get arguments and other header stuff out of the way processArgs(); processHeaderValues(stream, octetCount, packageSize); processBody(); // RESPOND processRequest(); } }); } // =================== // Inline Helpers // =================== void inline HTTPrequest::processArgs() { std::string key, value; if (requestPath.find('?') != std::string::npos) { std::stringstream pathStream(requestPath); std::getline(pathStream, requestPath, '?'); // Keeping the path pure while (!pathStream.eof()) { std::getline(pathStream, key, '='); std::getline(pathStream, value, '&'); args.insert({key, value}); } } } void inline HTTPrequest::processHeaderValues(std::basic_istream &stream, std::size_t &octetCount, std::size_t headerSize) { std::string key, value, empty; while (octetCount < headerSize - 2) { // -2 is due to last two \r\n\r\n combo Helpers::getlineAndCount(stream, octetCount, key, ':'); Helpers::getlineAndCount(stream, octetCount, empty, ' '); // trim start some gangster shit right here Helpers::getlineAndCount(stream, octetCount, value); headers.insert({key, value}); } } // =================== // BODY OF THE REQUEST // =================== void inline HTTPrequest::processBody() { if (headers.find("Content-Length") != headers.end()) { std::size_t uploadSize = std::stoull(headers.at("Content-Length")) - buffer.size(), octetCount = 0; // This part needs to be sync since we want this specific instance // execution to pause while (octetCount < uploadSize) { octetCount += asio::read(sock, buffer.prepare(uploadSize)); } buffer.commit(octetCount); std::istream bodyStream(&buffer); bodyContent.resize(buffer.size()); bodyStream.read(bodyContent.data(), buffer.size()); buffer.consume(buffer.size()); // Just so the buffer is nice and clean } }