1
0
forked from cat/WebBase

Compare commits

..

7 Commits

Author SHA1 Message Date
cat
7d6163b3dd removed cache 2025-07-02 19:12:17 +03:00
cat
336b8311cd Fixed README.md 2025-07-02 19:11:47 +03:00
cat
b07711341f Resolving conflict 2025-07-02 19:11:06 +03:00
cat
64bc7d0fb7 Cmake is changed to reflect restructure 2025-07-02 18:59:26 +03:00
cat
0b483c69cb HTTP bodies should work nicely, files are reorganised, www is reverted 2025-07-02 18:58:40 +03:00
cat
14394f1c9f Start of the body processing 2025-07-02 15:14:16 +03:00
309ba08e34 Breaking it off from File Hosting 2025-07-01 19:05:20 +02:00
8 changed files with 103 additions and 94 deletions

View File

@@ -7,8 +7,11 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BUILD_TYPE Debug) set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "-Wall -g -fsanitize=address") set(CMAKE_CXX_FLAGS "-Wall -g -fsanitize=address")
add_executable(Webserver "src/Entry.cpp" "src/Webserver.cpp" "src/HTTP.cpp" add_executable(
"libs/QuickDigest5/quickdigest5.cpp" "src/Helpers.cpp") Webserver
"src/Entry.cpp" "src/Webserver.cpp" "src/HTTP.cpp"
"libs/QuickDigest5/quickdigest5.cpp" "src/Helpers.cpp"
"src/HTTPRequestProcess.cpp")
add_custom_command( add_custom_command(
TARGET Webserver TARGET Webserver

View File

@@ -1,4 +1,4 @@
#include "main.hpp" #include "Main.hpp"
#include <exception> #include <exception>
#include <iostream> #include <iostream>

View File

@@ -1,94 +1,9 @@
#include "Helpers.hpp" #include "Helpers.hpp"
#include "main.hpp" #include "Main.hpp"
#include <asio/completion_condition.hpp>
#include <asio/impl/read_until.hpp>
#include <iostream>
#include <istream>
#include <ostream>
#include <sstream>
#include <string>
#include <system_error>
void HTTPrequest::start() { void HTTPrequest::start() {
// Possible Logging here // Possible Logging here
readData(); processHTTPHeader();
}
void HTTPrequest::readData() {
//
// Reading happens here
//
std::shared_ptr<HTTPrequest> self(shared_from_this());
// TODO: Read until headers, headers contains the file size then allocate that
// much memory on buffer, and THEN start reading the file
// 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::unordered_map<std::string, std::string> request;
std::unordered_map<std::string, std::string> args;
std::istream stream(&buffer);
uint64_t bitCount = 0;
// This is HTTP main request
std::string rq, key, value, type, path;
Helpers::getlineAndCount(stream, bitCount, type,
' '); // HTTP request type
Helpers::getlineAndCount(stream, bitCount, path, ' '); // HTTP path
Helpers::getlineAndCount(stream, bitCount,
rq); // Version, omitting for now
// Quick stop to process arguments
std::stringstream pathStream(path);
std::getline(pathStream, path, '?'); // Keeping the path pure
while (!pathStream.eof()) {
std::getline(pathStream, key, '=');
std::getline(pathStream, value, '&');
args.insert({key, value});
std::cout << key << " " << value << std::endl;
}
// Rest of the request vals
while (bitCount <
packageSize - 2) { // -2 is due to last two \r\n\r\n combo
Helpers::getlineAndCount(stream, bitCount, key, ':');
Helpers::getlineAndCount(
stream, bitCount, rq,
' '); // trim start some gangster shit right here
Helpers::getlineAndCount(stream, bitCount, value);
request.insert({key, value});
}
// ===================
// BODY OF THE REQUEST
// ===================
std::size_t uploadSize =
std::stoull(request.at("Content-Length")) - buffer.size();
asio::async_read(
sock, buffer.prepare(uploadSize),
asio::transfer_exactly(uploadSize),
[self, this](std::error_code error, std::size_t packageSize) {
buffer.commit(packageSize);
std::istream bodyStream(&buffer);
std::string body;
body.resize(buffer.size());
bodyStream.read(body.data(), buffer.size());
std::cout << body << "\ntest" << std::endl;
buffer.consume(buffer.size());
sock.close();
});
processRequest(type, path, request, args); // This writes data too
sock.close();
}
});
} }
void HTTPrequest::processRequest( void HTTPrequest::processRequest(

View File

@@ -0,0 +1,89 @@
#include "Helpers.hpp"
#include "Main.hpp"
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
// file type and name
// 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::unordered_map<std::string, std::string> request;
std::unordered_map<std::string, std::string> args;
std::istream stream(&buffer);
uint64_t octetCount = 0;
// This is HTTP main request
std::string rq, key, value, type, path;
Helpers::getlineAndCount(stream, octetCount, type,
' '); // HTTP request type
Helpers::getlineAndCount(stream, octetCount, path, ' '); // HTTP path
Helpers::getlineAndCount(stream, octetCount,
rq); // Version, omitting for now
// Quick stop to process arguments
if (path.find('?') != std::string::npos) {
std::stringstream pathStream(path);
std::getline(pathStream, path, '?'); // Keeping the path pure
while (!pathStream.eof()) {
std::getline(pathStream, key, '=');
std::getline(pathStream, value, '&');
args.insert({key, value});
}
}
// Rest of the request vals
while (octetCount <
packageSize - 2) { // -2 is due to last two \r\n\r\n combo
Helpers::getlineAndCount(stream, octetCount, key, ':');
Helpers::getlineAndCount(
stream, octetCount, rq,
' '); // trim start some gangster shit right here
Helpers::getlineAndCount(stream, octetCount, value);
request.insert({key, value});
}
// ===================
// BODY OF THE REQUEST
// ===================
if (request.find("Content-Length") != request.end()) {
std::size_t uploadSize = std::stoull(request.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);
std::string body;
body.resize(buffer.size());
bodyStream.read(body.data(), buffer.size());
buffer.consume(
buffer.size()); // Just so the buffer is nice and clean
}
processRequest(type, path, request, args); // This writes data too
sock.close();
}
});
}

View File

@@ -27,7 +27,8 @@ std::string Helpers::GenerateResponse(std::string statusCode,
std::string content) { std::string content) {
std::stringstream output; std::stringstream output;
output << "HTTP/1.1 " << statusCode << "\n" output << "HTTP/1.1 " << statusCode << "\n"
<< "Content-Type: " << contentType << "\nConnection: close\n\n" << "Content-Type: " << contentType
<< "\nContent-Length: " << content.size() << "\nConnection: close\n\n"
<< content; << content;
return output.str(); return output.str();
} }

View File

@@ -30,7 +30,7 @@ public:
private: private:
HTTPrequest(asio::io_context &context); HTTPrequest(asio::io_context &context);
void readData(); void processHTTPHeader();
void processRequest(std::string requestType, std::string requestPath, void processRequest(std::string requestType, std::string requestPath,
std::unordered_map<std::string, std::string> request, std::unordered_map<std::string, std::string> request,
std::unordered_map<std::string, std::string> args); std::unordered_map<std::string, std::string> args);

View File

@@ -1,4 +1,4 @@
#include "main.hpp" #include "Main.hpp"
#include <iostream> #include <iostream>
// Webserver is defined at main.hpp, you probably do not want to code here // Webserver is defined at main.hpp, you probably do not want to code here

View File

@@ -8,7 +8,8 @@
</head> </head>
<body> <body>
<h1>Test</h1> <h1>Welcome</h1>
<h1>POST test</h1>
<form action="/upload" method="POST" enctype="multipart/form-data"> <form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="uploaded_file"> <input type="file" name="uploaded_file">
<input type="submit" value="Upload"> <input type="submit" value="Upload">