Compare commits
3 Commits
0d87542196
...
809c833259
Author | SHA1 | Date | |
---|---|---|---|
809c833259 | |||
fb3f1e7c37 | |||
cc3eb54b3b |
51
src/HTTP.cpp
51
src/HTTP.cpp
@@ -1,6 +1,17 @@
|
|||||||
#include "Helpers.hpp"
|
#include "Helpers.hpp"
|
||||||
#include "Main.hpp"
|
#include "Main.hpp"
|
||||||
#include <exception>
|
#include <asio/buffer.hpp>
|
||||||
|
#include <asio/completion_condition.hpp>
|
||||||
|
#include <asio/impl/write.hpp>
|
||||||
|
#include <asio/registered_buffer.hpp>
|
||||||
|
#include <asio/socket_base.hpp>
|
||||||
|
#include <asio/streambuf.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <ostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
void HTTPrequest::start() {
|
void HTTPrequest::start() {
|
||||||
// Possible Logging here
|
// Possible Logging here
|
||||||
@@ -9,19 +20,43 @@ void HTTPrequest::start() {
|
|||||||
|
|
||||||
void HTTPrequest::processRequest() {
|
void HTTPrequest::processRequest() {
|
||||||
try {
|
try {
|
||||||
Webserver::responseMethods[requestType].at(requestPath)(*this);
|
Webserver::responseMethods[requestType].at(requestPath)(this);
|
||||||
} catch (std::exception e) {
|
} catch (std::out_of_range &e) {
|
||||||
writeData(Helpers::GenerateResponse("404 Not Found", "text/html",
|
sendResponse("404 Not Found", "text/html",
|
||||||
Helpers::ReadFile("www/error.html")));
|
Helpers::ReadFile("www/error.html"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPrequest::writeData(std::string data) {
|
void HTTPrequest::sendResponse(std::string status, std::string mime,
|
||||||
|
std::string data) {
|
||||||
// Logging here perhaps
|
// Logging here perhaps
|
||||||
asio::async_write(sock, asio::buffer(data),
|
std::stringstream output;
|
||||||
[](std::error_code, std::size_t) {});
|
output << "HTTP/1.1 " << status << "\r\n"
|
||||||
|
<< "Content-Type: " << mime << "\r\nContent-Length: " << data.size()
|
||||||
|
<< "\r\nConnection: close\r\n\r\n"
|
||||||
|
<< data;
|
||||||
|
|
||||||
|
responseText = output.str();
|
||||||
|
asio::async_write(
|
||||||
|
sock, asio::buffer(responseText),
|
||||||
|
[this, self = shared_from_this()](std::error_code, std::size_t) {
|
||||||
|
sock.shutdown(asio::ip::tcp::socket::shutdown_send);
|
||||||
|
waitForClientClose();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// I'm not happy with this
|
||||||
|
void HTTPrequest::waitForClientClose() {
|
||||||
|
auto buf = std::array<char, 1>();
|
||||||
|
sock.async_read_some(asio::buffer(buf),
|
||||||
|
[this, self = shared_from_this()](
|
||||||
|
const std::error_code &error, std::size_t) {
|
||||||
|
if (error) {
|
||||||
|
sock.close();
|
||||||
|
}
|
||||||
|
waitForClientClose();
|
||||||
|
});
|
||||||
|
}
|
||||||
// ================= CLASS HANDLING SPECIFIC =================
|
// ================= CLASS HANDLING SPECIFIC =================
|
||||||
|
|
||||||
HTTPrequest::HTTPrequest(asio::io_context &context) : sock(context) {}
|
HTTPrequest::HTTPrequest(asio::io_context &context) : sock(context) {}
|
||||||
|
@@ -8,12 +8,16 @@
|
|||||||
// So just add your logic here and relax ;)
|
// So just add your logic here and relax ;)
|
||||||
std::unordered_map<
|
std::unordered_map<
|
||||||
std::string,
|
std::string,
|
||||||
std::unordered_map<std::string, std::function<void(HTTPrequest &self)>>>
|
std::unordered_map<std::string, std::function<void(HTTPrequest *self)>>>
|
||||||
Webserver::responseMethods;
|
Webserver::responseMethods;
|
||||||
|
|
||||||
void Webserver::initResponses() {
|
void Webserver::initResponses() {
|
||||||
responseMethods["GET"]["/"] = [](HTTPrequest &self) {
|
responseMethods["GET"]["/"] = [](HTTPrequest *self) {
|
||||||
self.writeData(Helpers::GenerateResponse(
|
self->sendResponse("200 OK", "text/html",
|
||||||
"200 OK", "text/html", Helpers::ReadFile("www/index.html")));
|
Helpers::ReadFile("www/index.html"));
|
||||||
|
};
|
||||||
|
|
||||||
|
responseMethods["POST"]["/upload"] = [](HTTPrequest *self) {
|
||||||
|
self->sendResponse("200 OK", "text/text", self->bodyContent);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
#include "Helpers.hpp"
|
#include "Helpers.hpp"
|
||||||
#include "Main.hpp"
|
#include "Main.hpp"
|
||||||
|
#include <asio/socket_base.hpp>
|
||||||
|
#include <iostream>
|
||||||
#include <istream>
|
#include <istream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
// 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
|
||||||
@@ -31,8 +34,8 @@ void HTTPrequest::processHTTPHeader() {
|
|||||||
processHeaderValues(stream, octetCount, packageSize);
|
processHeaderValues(stream, octetCount, packageSize);
|
||||||
processBody();
|
processBody();
|
||||||
|
|
||||||
processRequest(); // This writes data too
|
// RESPOND
|
||||||
sock.close();
|
processRequest();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -22,13 +22,3 @@ void Helpers::getlineAndCount(std::basic_istream<char> &stream, uint64_t &count,
|
|||||||
count += string.size() + 1; // Delimiter
|
count += string.size() + 1; // Delimiter
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string Helpers::GenerateResponse(std::string statusCode,
|
|
||||||
std::string contentType,
|
|
||||||
std::string content) {
|
|
||||||
std::stringstream output;
|
|
||||||
output << "HTTP/1.1 " << statusCode << "\n"
|
|
||||||
<< "Content-Type: " << contentType
|
|
||||||
<< "\nContent-Length: " << content.size() << "\nConnection: close\n\n"
|
|
||||||
<< content;
|
|
||||||
return output.str();
|
|
||||||
}
|
|
||||||
|
@@ -5,6 +5,4 @@ namespace Helpers {
|
|||||||
std::string ReadFile(std::string Path);
|
std::string ReadFile(std::string Path);
|
||||||
void getlineAndCount(std::basic_istream<char> &stream, uint64_t &count,
|
void getlineAndCount(std::basic_istream<char> &stream, uint64_t &count,
|
||||||
std::string &string, char delimit = '\0');
|
std::string &string, char delimit = '\0');
|
||||||
std::string GenerateResponse(std::string statusCode, std::string contentType,
|
|
||||||
std::string content);
|
|
||||||
} // namespace Helpers
|
} // namespace Helpers
|
||||||
|
@@ -28,16 +28,17 @@ public:
|
|||||||
static HTTPrequest_ptr create(asio::io_context &context);
|
static HTTPrequest_ptr create(asio::io_context &context);
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void writeData(std::string data);
|
void sendResponse(std::string status, std::string mime, std::string data);
|
||||||
|
|
||||||
// Request itself
|
// Request itself
|
||||||
std::string requestType, requestPath;
|
std::string requestType, requestPath, responseText;
|
||||||
std::unordered_map<std::string, std::string> headers, args;
|
std::unordered_map<std::string, std::string> headers, args;
|
||||||
std::string bodyContent;
|
std::string bodyContent;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HTTPrequest(asio::io_context &context);
|
HTTPrequest(asio::io_context &context);
|
||||||
void processRequest();
|
void processRequest();
|
||||||
|
void waitForClientClose();
|
||||||
|
|
||||||
// Breaking Header to in lines
|
// Breaking Header to in lines
|
||||||
void processHTTPHeader();
|
void processHTTPHeader();
|
||||||
@@ -60,7 +61,7 @@ public:
|
|||||||
// Responses
|
// Responses
|
||||||
static std::unordered_map<
|
static std::unordered_map<
|
||||||
std::string,
|
std::string,
|
||||||
std::unordered_map<std::string, std::function<void(HTTPrequest &self)>>>
|
std::unordered_map<std::string, std::function<void(HTTPrequest *self)>>>
|
||||||
responseMethods;
|
responseMethods;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Reference in New Issue
Block a user