forked from cat/WebBase
Made args processing, header processing, and body processing inline methods. Additionally now most variables are class level instead of method level
This commit is contained in:
@@ -6,10 +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
|
// This is where we will process requests
|
||||||
//
|
//
|
||||||
|
@@ -1,44 +1,51 @@
|
|||||||
#include "Helpers.hpp"
|
#include "Helpers.hpp"
|
||||||
#include "Main.hpp"
|
#include "Main.hpp"
|
||||||
|
#include <istream>
|
||||||
|
|
||||||
|
// TODO: Remove boundary from the body. Do keep other stuff like
|
||||||
|
// file type and name
|
||||||
|
|
||||||
void HTTPrequest::processHTTPHeader() {
|
void HTTPrequest::processHTTPHeader() {
|
||||||
//
|
|
||||||
// Reading happens here
|
|
||||||
//
|
|
||||||
std::shared_ptr<HTTPrequest> self(shared_from_this());
|
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
|
|
||||||
// file type and name
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
21
src/Main.hpp
21
src/Main.hpp
@@ -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;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user