Template
1
0

Compare commits

..

2 Commits

3 changed files with 88 additions and 80 deletions

View File

@@ -6,13 +6,7 @@ void HTTPrequest::start() {
processHTTPHeader(); processHTTPHeader();
} }
void HTTPrequest::processRequest( void HTTPrequest::processRequest() {
std::string requestType, std::string requestPath,
std::unordered_map<std::string, std::string> request,
std::unordered_map<std::string, std::string> args) {
//
// This is where we will process requests
//
uint64_t pathHash = Helpers::Pathhash(requestPath); uint64_t pathHash = Helpers::Pathhash(requestPath);
// This is very much temp // This is very much temp
@@ -40,9 +34,7 @@ void HTTPrequest::processRequest(
} }
void HTTPrequest::writeData(std::string data) { void HTTPrequest::writeData(std::string data) {
// // Logging here perhaps
// Response here
//
asio::async_write(sock, asio::buffer(data), asio::async_write(sock, asio::buffer(data),
[](std::error_code, std::size_t) {}); [](std::error_code, std::size_t) {});
} }

View File

@@ -1,44 +1,51 @@
#include "Helpers.hpp" #include "Helpers.hpp"
#include "Main.hpp" #include "Main.hpp"
#include <istream>
void HTTPrequest::processHTTPHeader() {
//
// Reading happens here
//
std::shared_ptr<HTTPrequest> self(shared_from_this());
// Sadly due to the nature of how asio works this entire logic needs to be
// mostly in 1 method I do wager that I could break off the whole body
// processing into its own thing as well as a lot of inline methods
// specifically for argument and header processing
// TODO: Remove boundary from the body. Do keep other stuff like // TODO: Remove boundary from the body. Do keep other stuff like
// file type and name // file type and name
void HTTPrequest::processHTTPHeader() {
std::shared_ptr<HTTPrequest> self(shared_from_this());
// HEADER read // HEADER read
asio::async_read_until( asio::async_read_until(
sock, buffer, "\r\n\r\n", // its not the other way bud sock, buffer, "\r\n\r\n", // its not the other way bud
[this, self](std::error_code error, std::size_t packageSize) { [this, self](std::error_code error, std::size_t packageSize) {
if (!error) { if (!error) {
buffer.commit(packageSize); buffer.commit(packageSize);
std::unordered_map<std::string, std::string> request;
std::unordered_map<std::string, std::string> args;
std::istream stream(&buffer); std::istream stream(&buffer);
uint64_t octetCount = 0; std::size_t octetCount = 0;
// This is HTTP main request // This is HTTP main request
std::string rq, key, value, type, path; std::string rq;
Helpers::getlineAndCount(stream, octetCount, requestType,
Helpers::getlineAndCount(stream, octetCount, type,
' '); // HTTP request type ' '); // HTTP request type
Helpers::getlineAndCount(stream, octetCount, path, ' '); // HTTP path Helpers::getlineAndCount(stream, octetCount, requestPath,
' '); // HTTP path
Helpers::getlineAndCount(stream, octetCount, Helpers::getlineAndCount(stream, octetCount,
rq); // Version, omitting for now rq); // Version, omitting for now
// Quick stop to process arguments // Get arguments and other header stuff out of the way
if (path.find('?') != std::string::npos) { processArgs();
std::stringstream pathStream(path); processHeaderValues(stream, octetCount, packageSize);
std::getline(pathStream, path, '?'); // Keeping the path pure processBody();
processRequest(); // This writes data too
sock.close();
}
});
}
// ===================
// 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()) { while (!pathStream.eof()) {
std::getline(pathStream, key, '='); std::getline(pathStream, key, '=');
@@ -46,24 +53,29 @@ void HTTPrequest::processHTTPHeader() {
args.insert({key, value}); args.insert({key, value});
} }
} }
}
// Rest of the request vals void inline HTTPrequest::processHeaderValues(std::basic_istream<char> &stream,
while (octetCount < std::size_t &octetCount,
packageSize - 2) { // -2 is due to last two \r\n\r\n combo 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, key, ':');
Helpers::getlineAndCount( Helpers::getlineAndCount(stream, octetCount, empty,
stream, octetCount, rq,
' '); // trim start some gangster shit right here ' '); // trim start some gangster shit right here
Helpers::getlineAndCount(stream, octetCount, value); Helpers::getlineAndCount(stream, octetCount, value);
request.insert({key, value}); headers.insert({key, value});
}
} }
// =================== // ===================
// BODY OF THE REQUEST // BODY OF THE REQUEST
// =================== // ===================
if (request.find("Content-Length") != request.end()) {
std::size_t uploadSize = std::stoull(request.at("Content-Length")) - void inline HTTPrequest::processBody() {
buffer.size(), if (headers.find("Content-Length") != headers.end()) {
std::size_t uploadSize =
std::stoull(headers.at("Content-Length")) - buffer.size(),
octetCount = 0; octetCount = 0;
// This part needs to be sync since we want this specific instance // This part needs to be sync since we want this specific instance
@@ -74,16 +86,9 @@ void HTTPrequest::processHTTPHeader() {
buffer.commit(octetCount); buffer.commit(octetCount);
std::istream bodyStream(&buffer); std::istream bodyStream(&buffer);
std::string body; bodyContent.resize(buffer.size());
body.resize(buffer.size()); bodyStream.read(bodyContent.data(), buffer.size());
bodyStream.read(body.data(), buffer.size());
buffer.consume( buffer.consume(buffer.size()); // Just so the buffer is nice and clean
buffer.size()); // Just so the buffer is nice and clean
} }
processRequest(type, path, request, args); // This writes data too
sock.close();
}
});
} }

View File

@@ -18,7 +18,7 @@
using asocket = asio::ip::tcp::socket; using asocket = asio::ip::tcp::socket;
using asocket_ptr = std::shared_ptr<asocket>; using asocket_ptr = std::shared_ptr<asocket>;
// We handle HTTP requests with readData, writeData, and processRequest // We handle HTTP requests with processHTTPHeader, writeData, and processRequest
class HTTPrequest : public std::enable_shared_from_this<HTTPrequest> { class HTTPrequest : public std::enable_shared_from_this<HTTPrequest> {
public: public:
typedef std::shared_ptr<HTTPrequest> HTTPrequest_ptr; typedef std::shared_ptr<HTTPrequest> HTTPrequest_ptr;
@@ -30,12 +30,23 @@ public:
private: private:
HTTPrequest(asio::io_context &context); HTTPrequest(asio::io_context &context);
void processHTTPHeader(); void processRequest();
void processRequest(std::string requestType, std::string requestPath,
std::unordered_map<std::string, std::string> request,
std::unordered_map<std::string, std::string> args);
void writeData(std::string data); void writeData(std::string data);
// Breaking Header to in lines
void processHTTPHeader();
void inline processArgs();
void inline processHeaderValues(std::basic_istream<char> &stream,
std::size_t &octetCount,
std::size_t headerSize);
void inline processBody();
// Request itself
std::string requestType, requestPath;
std::unordered_map<std::string, std::string> headers, args;
std::string bodyContent;
// Networking
asio::ip::tcp::socket sock; asio::ip::tcp::socket sock;
asio::streambuf buffer; asio::streambuf buffer;
}; };