forked from cat/WebBase
98 lines
3.1 KiB
C++
98 lines
3.1 KiB
C++
#include "Helpers.hpp"
|
|
#include "Main.hpp"
|
|
#include <asio/socket_base.hpp>
|
|
#include <iostream>
|
|
#include <istream>
|
|
#include <string>
|
|
|
|
// TODO: Remove boundary from the body. Do keep other stuff like
|
|
// file type and name
|
|
|
|
void HTTPrequest::processHTTPHeader() {
|
|
std::shared_ptr<HTTPrequest> 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<char> &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
|
|
}
|
|
}
|