|
@ -18,6 +18,9 @@ |
|
|
|
|
|
|
|
|
#include <ctime> |
|
|
#include <ctime> |
|
|
#include <chrono> |
|
|
#include <chrono> |
|
|
|
|
|
#include <numeric> |
|
|
|
|
|
#include "jessilib/split.hpp" |
|
|
|
|
|
#include "jessilib/unicode.hpp" |
|
|
#include "String.hpp" |
|
|
#include "String.hpp" |
|
|
#include "Reference_String.h" |
|
|
#include "Reference_String.h" |
|
|
#include "TCPSocket.h" |
|
|
#include "TCPSocket.h" |
|
@ -25,8 +28,25 @@ |
|
|
#include "HTTP_Server.h" |
|
|
#include "HTTP_Server.h" |
|
|
|
|
|
|
|
|
using namespace Jupiter::literals; |
|
|
using namespace Jupiter::literals; |
|
|
|
|
|
using namespace std::literals; |
|
|
|
|
|
|
|
|
static const Jupiter::ReferenceString HTTP_REQUEST_ENDING = "\r\n\r\n"_jrs; |
|
|
static const std::string_view HTTP_REQUEST_ENDING = "\r\n\r\n"sv; |
|
|
|
|
|
|
|
|
|
|
|
template<typename ResultT = unsigned int, typename InT> |
|
|
|
|
|
ResultT calc_checksum(const InT& in_container) { |
|
|
|
|
|
ResultT result{}; |
|
|
|
|
|
result = std::accumulate(in_container.begin(), in_container.end(), result); |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template<typename ResultT = unsigned int, typename InT> |
|
|
|
|
|
ResultT calc_checksumi(const InT& in_container) { |
|
|
|
|
|
ResultT result{}; |
|
|
|
|
|
result = std::accumulate(in_container.begin(), in_container.end(), result, [](ResultT current_sum, typename InT::value_type current_element) { |
|
|
|
|
|
return current_sum + jessilib::fold(current_element); |
|
|
|
|
|
}); |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// HTTPCommand
|
|
|
// HTTPCommand
|
|
|
|
|
|
|
|
@ -49,19 +69,21 @@ enum HTTPVersion |
|
|
|
|
|
|
|
|
// HTTP::Server::Content
|
|
|
// HTTP::Server::Content
|
|
|
|
|
|
|
|
|
Jupiter::HTTP::Server::Content::Content(const Jupiter::ReadableString &in_name, Jupiter::HTTP::Server::HTTPFunction in_function) : name(in_name) { |
|
|
Jupiter::HTTP::Server::Content::Content(std::string in_name, Jupiter::HTTP::Server::HTTPFunction in_function) |
|
|
|
|
|
: name(std::move(in_name)) { |
|
|
Jupiter::HTTP::Server::Content::function = in_function; |
|
|
Jupiter::HTTP::Server::Content::function = in_function; |
|
|
Jupiter::HTTP::Server::Content::name_checksum = Jupiter::HTTP::Server::Content::name.calcChecksum(); // switch to calcChecksumi to make case-insensitive
|
|
|
Jupiter::HTTP::Server::Content::name_checksum = calc_checksum(name); // switch to calcChecksumi to make case-insensitive
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::ReadableString *Jupiter::HTTP::Server::Content::execute(const Jupiter::ReadableString &query_string) { |
|
|
Jupiter::ReadableString *Jupiter::HTTP::Server::Content::execute(std::string_view query_string) { |
|
|
return Jupiter::HTTP::Server::Content::function(query_string); |
|
|
return Jupiter::HTTP::Server::Content::function(query_string); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// HTTP::Server::Directory
|
|
|
// HTTP::Server::Directory
|
|
|
|
|
|
|
|
|
Jupiter::HTTP::Server::Directory::Directory(const Jupiter::ReadableString &in_name) : name(in_name) { |
|
|
Jupiter::HTTP::Server::Directory::Directory(std::string in_name) |
|
|
name_checksum = Jupiter::HTTP::Server::Directory::name.calcChecksum(); |
|
|
: name(std::move(in_name)) { |
|
|
|
|
|
name_checksum = calc_checksum(name); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::HTTP::Server::Directory::~Directory() { |
|
|
Jupiter::HTTP::Server::Directory::~Directory() { |
|
@ -70,7 +92,7 @@ Jupiter::HTTP::Server::Directory::~Directory() { |
|
|
// host/dir/content
|
|
|
// host/dir/content
|
|
|
// .hook("dir/subdir/", content)
|
|
|
// .hook("dir/subdir/", content)
|
|
|
|
|
|
|
|
|
void Jupiter::HTTP::Server::Directory::hook(const Jupiter::ReadableString &in_name, std::unique_ptr<Content> in_content) { |
|
|
void Jupiter::HTTP::Server::Directory::hook(std::string_view in_name, std::unique_ptr<Content> in_content) { |
|
|
Jupiter::ReferenceString in_name_ref = in_name; |
|
|
Jupiter::ReferenceString in_name_ref = in_name; |
|
|
in_name_ref.shiftRight(in_name_ref.span('/')); |
|
|
in_name_ref.shiftRight(in_name_ref.span('/')); |
|
|
|
|
|
|
|
@ -80,7 +102,7 @@ void Jupiter::HTTP::Server::Directory::hook(const Jupiter::ReadableString &in_na |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
size_t index = in_name_ref.find('/'); |
|
|
size_t index = in_name_ref.find('/'); |
|
|
Jupiter::ReferenceString dir_name; |
|
|
std::string_view dir_name; |
|
|
if (index == Jupiter::INVALID_INDEX) { |
|
|
if (index == Jupiter::INVALID_INDEX) { |
|
|
dir_name = in_name_ref; |
|
|
dir_name = in_name_ref; |
|
|
} |
|
|
} |
|
@ -89,17 +111,17 @@ void Jupiter::HTTP::Server::Directory::hook(const Jupiter::ReadableString &in_na |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
in_name_ref.shiftRight(dir_name.size()); |
|
|
in_name_ref.shiftRight(dir_name.size()); |
|
|
unsigned int dir_name_checksum = dir_name.calcChecksum(); |
|
|
unsigned int dir_name_checksum = calc_checksum(dir_name); |
|
|
index = directories.size(); |
|
|
index = directories.size(); |
|
|
for (auto& directory : directories) { |
|
|
for (auto& directory : directories) { |
|
|
if (directory->name_checksum == dir_name_checksum && directory->name.equals(dir_name)) { |
|
|
if (directory->name_checksum == dir_name_checksum && directory->name == dir_name) { |
|
|
directory->hook(in_name_ref, std::move(in_content)); |
|
|
directory->hook(in_name_ref, std::move(in_content)); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// create directories
|
|
|
// create directories
|
|
|
Directory* directory = directories.emplace_back(std::make_unique<Directory>(dir_name)).get(); |
|
|
Directory* directory = directories.emplace_back(std::make_unique<Directory>(static_cast<std::string>(dir_name))).get(); |
|
|
|
|
|
|
|
|
directory_add_loop: // TODO: for the love of god, why why why
|
|
|
directory_add_loop: // TODO: for the love of god, why why why
|
|
|
in_name_ref.shiftRight(in_name_ref.span('/')); |
|
|
in_name_ref.shiftRight(in_name_ref.span('/')); |
|
@ -107,12 +129,12 @@ directory_add_loop: // TODO: for the love of god, why why why |
|
|
// add directory
|
|
|
// add directory
|
|
|
index = in_name_ref.find('/'); |
|
|
index = in_name_ref.find('/'); |
|
|
if (index != Jupiter::INVALID_INDEX) { |
|
|
if (index != Jupiter::INVALID_INDEX) { |
|
|
directory->directories.push_back(std::make_unique<Directory>(in_name_ref.substring(size_t{ 0 }, index))); |
|
|
directory->directories.push_back(std::make_unique<Directory>(static_cast<std::string>(in_name_ref.substring(size_t{ 0 }, index)))); |
|
|
directory = directory->directories[directories.size() - 1].get(); |
|
|
directory = directory->directories[directories.size() - 1].get(); |
|
|
in_name_ref.shiftRight(index + 1); |
|
|
in_name_ref.shiftRight(index + 1); |
|
|
goto directory_add_loop; |
|
|
goto directory_add_loop; |
|
|
} |
|
|
} |
|
|
directory->directories.push_back(std::make_unique<Directory>(in_name_ref)); |
|
|
directory->directories.push_back(std::make_unique<Directory>(static_cast<std::string>(in_name_ref))); |
|
|
directory = directory->directories[directories.size() - 1].get(); |
|
|
directory = directory->directories[directories.size() - 1].get(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -120,16 +142,16 @@ directory_add_loop: // TODO: for the love of god, why why why |
|
|
directory->content.push_back(std::move(in_content)); |
|
|
directory->content.push_back(std::move(in_content)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Jupiter::HTTP::Server::Directory::remove(const Jupiter::ReadableString &path, const Jupiter::ReadableString &content_name) { |
|
|
bool Jupiter::HTTP::Server::Directory::remove(std::string_view path, std::string_view content_name) { |
|
|
Jupiter::ReferenceString in_name_ref = path; |
|
|
Jupiter::ReferenceString in_name_ref = path; |
|
|
in_name_ref.shiftRight(in_name_ref.span('/')); |
|
|
in_name_ref.shiftRight(in_name_ref.span('/')); |
|
|
unsigned int checksum; |
|
|
unsigned int checksum; |
|
|
|
|
|
|
|
|
if (in_name_ref.isEmpty()) { // Remove content
|
|
|
if (in_name_ref.isEmpty()) { // Remove content
|
|
|
checksum = content_name.calcChecksum(); |
|
|
checksum = calc_checksum(content_name); |
|
|
for (auto itr = content.begin(); itr != content.end(); ++itr) { |
|
|
for (auto itr = content.begin(); itr != content.end(); ++itr) { |
|
|
auto& content_node = *itr; |
|
|
auto& content_node = *itr; |
|
|
if (content_node->name_checksum == checksum && content_node->name.equals(content_name)) { |
|
|
if (content_node->name_checksum == checksum && content_node->name == content_name) { |
|
|
content.erase(itr); |
|
|
content.erase(itr); |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
@ -140,50 +162,51 @@ bool Jupiter::HTTP::Server::Directory::remove(const Jupiter::ReadableString &pat |
|
|
|
|
|
|
|
|
// Call remove() on next directory in path
|
|
|
// Call remove() on next directory in path
|
|
|
size_t index = in_name_ref.find('/'); |
|
|
size_t index = in_name_ref.find('/'); |
|
|
Jupiter::ReferenceString dir_name; |
|
|
std::string_view dir_name; |
|
|
if (index == Jupiter::INVALID_INDEX) |
|
|
if (index == Jupiter::INVALID_INDEX) |
|
|
dir_name = in_name_ref; |
|
|
dir_name = in_name_ref; |
|
|
else |
|
|
else |
|
|
dir_name = in_name_ref.substring(size_t{ 0 }, index); |
|
|
dir_name = in_name_ref.substring(size_t{ 0 }, index); |
|
|
|
|
|
|
|
|
in_name_ref.shiftRight(dir_name.size()); |
|
|
in_name_ref.shiftRight(dir_name.size()); |
|
|
checksum = dir_name.calcChecksum(); |
|
|
checksum = calc_checksum(dir_name); |
|
|
for (auto& directory : directories) { |
|
|
for (auto& directory : directories) { |
|
|
if (directory->name_checksum == checksum && directory->name.equals(dir_name)) { |
|
|
if (directory->name_checksum == checksum && directory->name == dir_name) { |
|
|
return directory->remove(in_name_ref, content_name); |
|
|
return directory->remove(in_name_ref, content_name); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Jupiter::HTTP::Server::Directory::has(const Jupiter::ReadableString &in_name) |
|
|
bool Jupiter::HTTP::Server::Directory::has(std::string_view in_name) { |
|
|
{ |
|
|
|
|
|
return find(in_name) != nullptr; |
|
|
return find(in_name) != nullptr; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::Directory::find(const Jupiter::ReadableString &in_name) |
|
|
Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::Directory::find(std::string_view in_name) { |
|
|
{ |
|
|
std::string_view in_name_ref = in_name; |
|
|
Jupiter::ReferenceString in_name_ref = in_name; |
|
|
while (!in_name_ref.empty() && in_name_ref.front() == '/') { |
|
|
in_name_ref.shiftRight(in_name_ref.span("/"_jrs)); |
|
|
in_name.remove_prefix(1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
size_t index = in_name_ref.find('/'); |
|
|
size_t index = in_name_ref.find('/'); |
|
|
if (index == Jupiter::INVALID_INDEX) { // Search content
|
|
|
if (index == Jupiter::INVALID_INDEX) { // Search content
|
|
|
unsigned int content_name_checksum = in_name_ref.calcChecksum(); |
|
|
unsigned int content_name_checksum = calc_checksum(in_name_ref); |
|
|
index = content.size(); |
|
|
index = content.size(); |
|
|
for (auto& content_item : content) { |
|
|
for (auto& content_item : content) { |
|
|
if (content_item->name_checksum == content_name_checksum && content_item->name.equals(in_name_ref)) { |
|
|
if (content_item->name_checksum == content_name_checksum && content_item->name == in_name_ref) { |
|
|
return content_item.get(); |
|
|
return content_item.get(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return nullptr; // No such content
|
|
|
return nullptr; // No such content
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::ReferenceString dir_name(in_name_ref.ptr(), index); |
|
|
// Just use split_once?
|
|
|
in_name_ref.shiftRight(dir_name.size() + 1); |
|
|
std::string_view dir_name(in_name_ref.data(), index); |
|
|
unsigned int dir_name_checksum = dir_name.calcChecksum(); |
|
|
in_name_ref.remove_prefix(dir_name.size() + 1); |
|
|
|
|
|
unsigned int dir_name_checksum = calc_checksum(dir_name); |
|
|
|
|
|
|
|
|
for (auto& directory : directories) { |
|
|
for (auto& directory : directories) { |
|
|
if (directory->name_checksum == dir_name_checksum && directory->name.equals(dir_name)) { |
|
|
if (directory->name_checksum == dir_name_checksum && directory->name == dir_name) { |
|
|
return directory->find(in_name_ref); |
|
|
return directory->find(in_name_ref); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -191,7 +214,7 @@ Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::Directory::find(const Jup |
|
|
return nullptr; // No such directory
|
|
|
return nullptr; // No such directory
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::ReadableString* Jupiter::HTTP::Server::Directory::execute(const Jupiter::ReadableString &in_name, const Jupiter::ReadableString &query_string) { |
|
|
Jupiter::ReadableString* Jupiter::HTTP::Server::Directory::execute(std::string_view in_name, std::string_view query_string) { |
|
|
Jupiter::HTTP::Server::Content *content_ptr = find(in_name); |
|
|
Jupiter::HTTP::Server::Content *content_ptr = find(in_name); |
|
|
if (content_ptr == nullptr) |
|
|
if (content_ptr == nullptr) |
|
|
return nullptr; |
|
|
return nullptr; |
|
@ -201,15 +224,16 @@ Jupiter::ReadableString* Jupiter::HTTP::Server::Directory::execute(const Jupiter |
|
|
|
|
|
|
|
|
// HTTP::Server::Host
|
|
|
// HTTP::Server::Host
|
|
|
|
|
|
|
|
|
Jupiter::HTTP::Server::Host::Host(const Jupiter::ReadableString &in_name) : Directory(in_name) { |
|
|
Jupiter::HTTP::Server::Host::Host(std::string in_name) |
|
|
name_checksum = Jupiter::HTTP::Server::Host::name.calcChecksumi(); |
|
|
: Directory(std::move(in_name)) { |
|
|
|
|
|
name_checksum = calc_checksumi(name); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// HTTPSession struct
|
|
|
// HTTPSession struct
|
|
|
|
|
|
|
|
|
struct HTTPSession { |
|
|
struct HTTPSession { |
|
|
Jupiter::Socket sock; |
|
|
Jupiter::Socket sock; |
|
|
Jupiter::String request; |
|
|
std::string request; |
|
|
bool keep_alive = false; |
|
|
bool keep_alive = false; |
|
|
Jupiter::HTTP::Server::Host* host = nullptr; |
|
|
Jupiter::HTTP::Server::Host* host = nullptr; |
|
|
HTTPVersion version = HTTPVersion::HTTP_1_0; |
|
|
HTTPVersion version = HTTPVersion::HTTP_1_0; |
|
@ -238,17 +262,17 @@ struct Jupiter::HTTP::Server::Data { |
|
|
bool permit_keept_alive = true; // TODO: Config variable
|
|
|
bool permit_keept_alive = true; // TODO: Config variable
|
|
|
|
|
|
|
|
|
/** Foward functions */ |
|
|
/** Foward functions */ |
|
|
void hook(const Jupiter::ReadableString &host, const Jupiter::ReadableString &path, std::unique_ptr<Content> in_content); |
|
|
void hook(std::string_view host, std::string_view path, std::unique_ptr<Content> in_content); |
|
|
bool remove(const Jupiter::ReadableString &hostname); |
|
|
bool remove(std::string_view hostname); |
|
|
//bool remove(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &path);
|
|
|
//bool remove(std::string_view hostname, std::string_view path);
|
|
|
bool remove(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &path, const Jupiter::ReadableString &name); |
|
|
bool remove(std::string_view hostname, std::string_view path, std::string_view name); |
|
|
bool has(const Jupiter::ReadableString &hostname); |
|
|
bool has(std::string_view hostname); |
|
|
bool has(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &name); |
|
|
bool has(std::string_view hostname, std::string_view name); |
|
|
Jupiter::HTTP::Server::Host *find_host(const Jupiter::ReadableString &name); |
|
|
Jupiter::HTTP::Server::Host *find_host(std::string_view name); |
|
|
Content* find(const Jupiter::ReadableString &name); |
|
|
Content* find(std::string_view name); |
|
|
Content* find(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &name); |
|
|
Content* find(std::string_view hostname, std::string_view name); |
|
|
Jupiter::ReadableString *execute(const Jupiter::ReadableString &name, const Jupiter::ReadableString &query_string); |
|
|
Jupiter::ReadableString *execute(std::string_view name, std::string_view query_string); |
|
|
Jupiter::ReadableString *execute(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &name, const Jupiter::ReadableString &query_string); |
|
|
Jupiter::ReadableString *execute(std::string_view hostname, std::string_view name, std::string_view query_string); |
|
|
|
|
|
|
|
|
int process_request(HTTPSession &session); |
|
|
int process_request(HTTPSession &session); |
|
|
|
|
|
|
|
@ -265,7 +289,7 @@ struct Jupiter::HTTP::Server::Data { |
|
|
|
|
|
|
|
|
Jupiter::HTTP::Server::Data::Data() { |
|
|
Jupiter::HTTP::Server::Data::Data() { |
|
|
// hosts[0] is always the "global" namespace.
|
|
|
// hosts[0] is always the "global" namespace.
|
|
|
m_hosts.push_back(std::make_unique<Host>(Jupiter::HTTP::Server::global_namespace)); |
|
|
m_hosts.push_back(std::make_unique<Host>(static_cast<std::string>(Jupiter::HTTP::Server::global_namespace))); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Data destructor
|
|
|
// Data destructor
|
|
@ -275,14 +299,14 @@ Jupiter::HTTP::Server::Data::~Data() { |
|
|
|
|
|
|
|
|
// Data functions
|
|
|
// Data functions
|
|
|
|
|
|
|
|
|
void Jupiter::HTTP::Server::Data::hook(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &in_path, std::unique_ptr<Content> in_content) { |
|
|
void Jupiter::HTTP::Server::Data::hook(std::string_view hostname, std::string_view in_path, std::unique_ptr<Content> in_content) { |
|
|
Jupiter::ReferenceString path = in_path; |
|
|
Jupiter::ReferenceString path = in_path; |
|
|
Jupiter::ReferenceString dir_name; |
|
|
Jupiter::ReferenceString dir_name; |
|
|
Jupiter::HTTP::Server::Host* host = find_host(hostname); |
|
|
Jupiter::HTTP::Server::Host* host = find_host(hostname); |
|
|
|
|
|
|
|
|
if (host == nullptr) { |
|
|
if (host == nullptr) { |
|
|
//host = new Jupiter::HTTP::Server::Host(hostname);
|
|
|
//host = new Jupiter::HTTP::Server::Host(hostname);
|
|
|
host = m_hosts.emplace_back(std::make_unique<Host>(hostname)).get(); |
|
|
host = m_hosts.emplace_back(std::make_unique<Host>(static_cast<std::string>(hostname))).get(); |
|
|
// OPTIMIZE: create directory tree and return.
|
|
|
// OPTIMIZE: create directory tree and return.
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -295,10 +319,10 @@ void Jupiter::HTTP::Server::Data::hook(const Jupiter::ReadableString &hostname, |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Jupiter::HTTP::Server::Data::remove(const Jupiter::ReadableString &hostname) { |
|
|
bool Jupiter::HTTP::Server::Data::remove(std::string_view hostname) { |
|
|
unsigned int name_checksum = hostname.calcChecksumi(); |
|
|
unsigned int name_checksum = calc_checksumi(hostname); |
|
|
for (auto host_itr = m_hosts.begin(); host_itr != m_hosts.end(); ++host_itr) { |
|
|
for (auto host_itr = m_hosts.begin(); host_itr != m_hosts.end(); ++host_itr) { |
|
|
if (name_checksum == (*host_itr)->name_checksum && (*host_itr)->name.equalsi(hostname)) { |
|
|
if (name_checksum == (*host_itr)->name_checksum && jessilib::equalsi((*host_itr)->name, hostname)) { |
|
|
m_hosts.erase(host_itr); |
|
|
m_hosts.erase(host_itr); |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
@ -307,7 +331,7 @@ bool Jupiter::HTTP::Server::Data::remove(const Jupiter::ReadableString &hostname |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// name: path/to/resource OR path/
|
|
|
// name: path/to/resource OR path/
|
|
|
bool Jupiter::HTTP::Server::Data::remove(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &path, const Jupiter::ReadableString &name) { |
|
|
bool Jupiter::HTTP::Server::Data::remove(std::string_view hostname, std::string_view path, std::string_view name) { |
|
|
Jupiter::HTTP::Server::Host *host = find_host(hostname); |
|
|
Jupiter::HTTP::Server::Host *host = find_host(hostname); |
|
|
if (host == nullptr) { |
|
|
if (host == nullptr) { |
|
|
return false; |
|
|
return false; |
|
@ -315,10 +339,10 @@ bool Jupiter::HTTP::Server::Data::remove(const Jupiter::ReadableString &hostname |
|
|
return host->remove(path, name); |
|
|
return host->remove(path, name); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Jupiter::HTTP::Server::Data::has(const Jupiter::ReadableString &hostname) { |
|
|
bool Jupiter::HTTP::Server::Data::has(std::string_view hostname) { |
|
|
unsigned int name_checksum = hostname.calcChecksumi(); |
|
|
unsigned int name_checksum = calc_checksumi(hostname); |
|
|
for (const auto& host : m_hosts) { |
|
|
for (const auto& host : m_hosts) { |
|
|
if (name_checksum == host->name_checksum && host->name.equalsi(hostname)) { |
|
|
if (name_checksum == host->name_checksum && jessilib::equalsi(host->name, hostname)) { |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -326,13 +350,13 @@ bool Jupiter::HTTP::Server::Data::has(const Jupiter::ReadableString &hostname) { |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Jupiter::HTTP::Server::Data::has(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &name) { |
|
|
bool Jupiter::HTTP::Server::Data::has(std::string_view hostname, std::string_view name) { |
|
|
unsigned int name_checksum = hostname.calcChecksumi(); |
|
|
unsigned int name_checksum = calc_checksumi(hostname); |
|
|
for (const auto& host : m_hosts) { |
|
|
for (const auto& host : m_hosts) { |
|
|
if (name_checksum == host->name_checksum && host->name.equalsi(hostname)) { |
|
|
if (name_checksum == host->name_checksum && jessilib::equalsi(host->name, hostname)) { |
|
|
name_checksum = name.calcChecksum(); // switch to equalsi to make case-insensitive
|
|
|
name_checksum = calc_checksum(name); // switch to equalsi to make case-insensitive
|
|
|
for (const auto& content : host->content) { |
|
|
for (const auto& content : host->content) { |
|
|
if (name_checksum == content->name_checksum && content->name.equals(name)) { // switch to equalsi to make case-insensitive
|
|
|
if (name_checksum == content->name_checksum && content->name == name) { // switch to equalsi to make case-insensitive
|
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -342,10 +366,10 @@ bool Jupiter::HTTP::Server::Data::has(const Jupiter::ReadableString &hostname, c |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::HTTP::Server::Host *Jupiter::HTTP::Server::Data::find_host(const Jupiter::ReadableString &name) { |
|
|
Jupiter::HTTP::Server::Host *Jupiter::HTTP::Server::Data::find_host(std::string_view name) { |
|
|
unsigned int name_checksum = name.calcChecksumi(); |
|
|
unsigned int name_checksum = calc_checksumi(name); |
|
|
for (const auto& host : m_hosts) { |
|
|
for (const auto& host : m_hosts) { |
|
|
if (name_checksum == host->name_checksum && host->name.equalsi(name)) { |
|
|
if (name_checksum == host->name_checksum && host->name == name) { |
|
|
return host.get(); |
|
|
return host.get(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -353,11 +377,11 @@ Jupiter::HTTP::Server::Host *Jupiter::HTTP::Server::Data::find_host(const Jupite |
|
|
return nullptr; |
|
|
return nullptr; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::Data::find(const Jupiter::ReadableString &name) { |
|
|
Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::Data::find(std::string_view name) { |
|
|
return m_hosts[0]->find(name); |
|
|
return m_hosts[0]->find(name); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::Data::find(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &name) { |
|
|
Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::Data::find(std::string_view hostname, std::string_view name) { |
|
|
Jupiter::HTTP::Server::Host *host = find_host(hostname); |
|
|
Jupiter::HTTP::Server::Host *host = find_host(hostname); |
|
|
if (host == nullptr) |
|
|
if (host == nullptr) |
|
|
return nullptr; |
|
|
return nullptr; |
|
@ -365,7 +389,7 @@ Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::Data::find(const Jupiter: |
|
|
return host->find(name); |
|
|
return host->find(name); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::ReadableString *Jupiter::HTTP::Server::Data::execute(const Jupiter::ReadableString &name, const Jupiter::ReadableString &query_string) { |
|
|
Jupiter::ReadableString *Jupiter::HTTP::Server::Data::execute(std::string_view name, std::string_view query_string) { |
|
|
Jupiter::HTTP::Server::Content *content = find(name); |
|
|
Jupiter::HTTP::Server::Content *content = find(name); |
|
|
if (content == nullptr) |
|
|
if (content == nullptr) |
|
|
return nullptr; |
|
|
return nullptr; |
|
@ -373,7 +397,7 @@ Jupiter::ReadableString *Jupiter::HTTP::Server::Data::execute(const Jupiter::Rea |
|
|
return content->execute(query_string); |
|
|
return content->execute(query_string); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::ReadableString *Jupiter::HTTP::Server::Data::execute(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &name, const Jupiter::ReadableString &query_string) { |
|
|
Jupiter::ReadableString *Jupiter::HTTP::Server::Data::execute(std::string_view hostname, std::string_view name, std::string_view query_string) { |
|
|
Jupiter::HTTP::Server::Content *content = find(hostname, name); |
|
|
Jupiter::HTTP::Server::Content *content = find(hostname, name); |
|
|
if (content == nullptr) |
|
|
if (content == nullptr) |
|
|
return nullptr; |
|
|
return nullptr; |
|
@ -389,11 +413,11 @@ char* html_time() { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session) { |
|
|
int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session) { |
|
|
Jupiter::ReadableString::TokenizeResult<Jupiter::Reference_String> lines = Jupiter::ReferenceString::tokenize(session.request, STRING_LITERAL_AS_REFERENCE(ENDL)); |
|
|
auto lines = jessilib::split_view(session.request, "\r\n"sv); |
|
|
HTTPCommand command = HTTPCommand::NONE_SPECIFIED; |
|
|
HTTPCommand command = HTTPCommand::NONE_SPECIFIED; |
|
|
Content *content = nullptr; |
|
|
Content *content = nullptr; |
|
|
Jupiter::ReferenceString query_string; |
|
|
std::string_view query_string; |
|
|
Jupiter::ReferenceString first_token; |
|
|
std::string_view first_token; |
|
|
size_t index = 0; |
|
|
size_t index = 0; |
|
|
size_t span; |
|
|
size_t span; |
|
|
|
|
|
|
|
@ -401,20 +425,20 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session) { |
|
|
{ |
|
|
{ |
|
|
size_t offset = 0; |
|
|
size_t offset = 0; |
|
|
while (index != 0) |
|
|
while (index != 0) |
|
|
offset += lines.tokens[--index].size() + 2; |
|
|
offset += lines[--index].size() + 2; |
|
|
return offset; |
|
|
return offset; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
while (index != lines.token_count) |
|
|
while (index != lines.size()) |
|
|
{ |
|
|
{ |
|
|
Jupiter::ReferenceString &line = lines.tokens[index++]; |
|
|
std::string_view line = lines[index++]; |
|
|
|
|
|
|
|
|
// trim front-end spaces.
|
|
|
// trim front-end spaces.
|
|
|
span = line.span(" "_jrs); |
|
|
while (!line.empty() && line.front() == ' ') { |
|
|
if (span != 0) |
|
|
line.remove_prefix(1); |
|
|
line.shiftRight(span); |
|
|
} |
|
|
|
|
|
|
|
|
if (line.isEmpty()) // end of http request
|
|
|
if (!line.empty()) // end of http request
|
|
|
{ |
|
|
{ |
|
|
Jupiter::String result(256); |
|
|
Jupiter::String result(256); |
|
|
switch (command) |
|
|
switch (command) |
|
@ -424,7 +448,8 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session) { |
|
|
if (content != nullptr) |
|
|
if (content != nullptr) |
|
|
{ |
|
|
{ |
|
|
// 200 (success)
|
|
|
// 200 (success)
|
|
|
Jupiter::ReadableString *content_result = content->execute(query_string); |
|
|
// TODO: remove referencestring warpper
|
|
|
|
|
|
Jupiter::ReadableString *content_result = content->execute(Jupiter::ReferenceString{query_string}); |
|
|
|
|
|
|
|
|
switch (session.version) |
|
|
switch (session.version) |
|
|
{ |
|
|
{ |
|
@ -517,97 +542,107 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session) { |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (session.keep_alive == false) // not keep-alive -- will be destroyed on return
|
|
|
if (session.keep_alive == false) {// not keep-alive -- will be destroyed on return
|
|
|
break; |
|
|
break; |
|
|
if (index == lines.token_count) // end of packet
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (index == lines.size()) { // end of packet
|
|
|
session.request.erase(); |
|
|
session.request.erase(); |
|
|
else // end of request -- another request is following
|
|
|
} |
|
|
session.request.shiftRight(get_line_offset(index)); |
|
|
else { // end of request -- another request is following
|
|
|
|
|
|
// Maybe there's still some value in a shifty string, to avoid substr calls & heap allocations...
|
|
|
|
|
|
session.request = session.request.substr(get_line_offset(index)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (session.request.find(HTTP_REQUEST_ENDING) != Jupiter::INVALID_INDEX) // there's another full request already received
|
|
|
if (session.request.find(HTTP_REQUEST_ENDING) != Jupiter::INVALID_INDEX) { // there's another full request already received
|
|
|
return process_request(session); |
|
|
return process_request(session); |
|
|
|
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Not empty
|
|
|
// Not empty
|
|
|
first_token = line.getToken(0, ' '); |
|
|
auto first_split = jessilib::split_once_view(line, ' '); |
|
|
|
|
|
first_token = first_split.first; |
|
|
|
|
|
|
|
|
if (first_token.get(first_token.size() - 1) == ':') // header field
|
|
|
if (first_token.back() == ':') { // header field
|
|
|
{ |
|
|
first_token.remove_suffix(1); // trim trailing ':'
|
|
|
first_token.truncate(1); // trim trailing ':'
|
|
|
if (jessilib::equalsi(first_token, "HOST"sv)) { |
|
|
if (first_token.equalsi("HOST"_jrs)) |
|
|
session.host = find_host(first_split.second); |
|
|
session.host = find_host(line.getWord(1, " ")); |
|
|
} |
|
|
else if (first_token.equalsi("CONNECTION"_jrs)) |
|
|
else if (jessilib::equalsi(first_token, "CONNECTION"sv)) { |
|
|
{ |
|
|
std::string_view connection_type = first_split.second; |
|
|
Jupiter::ReferenceString connection_type = line.getWord(1, " "); |
|
|
if (jessilib::equalsi(connection_type, "keep-alive"sv)) { |
|
|
if (connection_type.equalsi("keep-alive"_jrs)) |
|
|
|
|
|
session.keep_alive = permit_keept_alive; |
|
|
session.keep_alive = permit_keept_alive; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
else // command
|
|
|
else { // command
|
|
|
{ |
|
|
if (first_token == "GET"sv) { |
|
|
if (first_token.equals("GET"_jrs)) |
|
|
|
|
|
{ |
|
|
|
|
|
command = HTTPCommand::GET; |
|
|
command = HTTPCommand::GET; |
|
|
|
|
|
|
|
|
query_string = line.getWord(1, " "); |
|
|
auto second_split = jessilib::split_once_view(first_split.second, ' '); |
|
|
|
|
|
query_string = second_split.first; |
|
|
span = query_string.find('?'); // repurposing 'span'
|
|
|
span = query_string.find('?'); // repurposing 'span'
|
|
|
if (span == Jupiter::INVALID_INDEX) |
|
|
if (span == Jupiter::INVALID_INDEX) { |
|
|
{ |
|
|
if (session.host == nullptr) { |
|
|
if (session.host == nullptr) |
|
|
|
|
|
content = find(query_string); |
|
|
content = find(query_string); |
|
|
else |
|
|
} |
|
|
|
|
|
else { |
|
|
content = session.host->find(query_string); |
|
|
content = session.host->find(query_string); |
|
|
query_string.erase(); |
|
|
} |
|
|
|
|
|
query_string = std::string_view{}; |
|
|
} |
|
|
} |
|
|
else |
|
|
else { |
|
|
{ |
|
|
if (session.host == nullptr) { |
|
|
if (session.host == nullptr) |
|
|
content = find(query_string.substr(size_t{ 0 }, span)); |
|
|
content = find(query_string.substring(size_t{ 0 }, span)); |
|
|
} |
|
|
else |
|
|
else { |
|
|
content = session.host->find(query_string.substring(size_t{ 0 }, span)); |
|
|
content = session.host->find(query_string.substr(size_t{ 0 }, span)); |
|
|
query_string.shiftRight(span + 1); |
|
|
} |
|
|
|
|
|
query_string.remove_prefix(span + 1); |
|
|
// decode query_string here
|
|
|
// decode query_string here
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::ReferenceString protocol_str = line.getWord(2, " "); |
|
|
std::string_view protocol_str = second_split.second; |
|
|
if (protocol_str.equalsi("http/1.0"_jrs)) |
|
|
if (jessilib::equalsi(protocol_str, "http/1.0"sv)) { |
|
|
session.version = HTTPVersion::HTTP_1_0; |
|
|
session.version = HTTPVersion::HTTP_1_0; |
|
|
else if (protocol_str.equalsi("http/1.1"_jrs)) |
|
|
} |
|
|
{ |
|
|
else if (jessilib::equalsi(protocol_str, "http/1.1"sv)) { |
|
|
session.version = HTTPVersion::HTTP_1_1; |
|
|
session.version = HTTPVersion::HTTP_1_1; |
|
|
session.keep_alive = permit_keept_alive; |
|
|
session.keep_alive = permit_keept_alive; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
else if (first_token.equals("HEAD"_jrs)) |
|
|
else if (first_token == "HEAD"sv) { |
|
|
{ |
|
|
|
|
|
command = HTTPCommand::HEAD; |
|
|
command = HTTPCommand::HEAD; |
|
|
|
|
|
|
|
|
query_string = line.getWord(1, " "); |
|
|
auto second_split = jessilib::split_once_view(first_split.second, ' '); |
|
|
|
|
|
query_string = second_split.first; |
|
|
span = query_string.find('?'); // repurposing 'span'
|
|
|
span = query_string.find('?'); // repurposing 'span'
|
|
|
if (span == Jupiter::INVALID_INDEX) |
|
|
if (span == Jupiter::INVALID_INDEX) { |
|
|
{ |
|
|
if (session.host == nullptr) { |
|
|
if (session.host == nullptr) |
|
|
|
|
|
content = find(query_string); |
|
|
content = find(query_string); |
|
|
else |
|
|
} |
|
|
|
|
|
else { |
|
|
content = session.host->find(query_string); |
|
|
content = session.host->find(query_string); |
|
|
query_string.erase(); |
|
|
} |
|
|
|
|
|
query_string = std::string_view{}; |
|
|
} |
|
|
} |
|
|
else |
|
|
else { |
|
|
{ |
|
|
if (session.host == nullptr) { |
|
|
if (session.host == nullptr) |
|
|
content = find(query_string.substr(size_t{ 0 }, span)); |
|
|
content = find(query_string.substring(size_t{ 0 }, span)); |
|
|
} |
|
|
else |
|
|
else { |
|
|
content = session.host->find(query_string.substring(size_t{ 0 }, span)); |
|
|
content = session.host->find(query_string.substr(size_t{ 0 }, span)); |
|
|
query_string.shiftRight(span + 1); |
|
|
} |
|
|
|
|
|
query_string.remove_prefix(span + 1); |
|
|
// decode query_string here
|
|
|
// decode query_string here
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::ReferenceString protocol_str = line.getWord(2, " "); |
|
|
std::string_view protocol_str = second_split.second; |
|
|
if (protocol_str.equalsi("http/1.0"_jrs)) |
|
|
if (jessilib::equalsi(protocol_str, "http/1.0"sv)) { |
|
|
session.version = HTTPVersion::HTTP_1_0; |
|
|
session.version = HTTPVersion::HTTP_1_0; |
|
|
else if (protocol_str.equalsi("http/1.1"_jrs)) |
|
|
} |
|
|
{ |
|
|
else if (jessilib::equalsi(protocol_str, "http/1.1"sv)) { |
|
|
session.version = HTTPVersion::HTTP_1_1; |
|
|
session.version = HTTPVersion::HTTP_1_1; |
|
|
session.keep_alive = permit_keept_alive; |
|
|
session.keep_alive = permit_keept_alive; |
|
|
} |
|
|
} |
|
@ -638,47 +673,43 @@ Jupiter::HTTP::Server::~Server() { |
|
|
|
|
|
|
|
|
// Server functions
|
|
|
// Server functions
|
|
|
|
|
|
|
|
|
void Jupiter::HTTP::Server::hook(const Jupiter::ReadableString &host, const Jupiter::ReadableString &name, std::unique_ptr<Content> content) { |
|
|
void Jupiter::HTTP::Server::hook(std::string_view host, std::string_view name, std::unique_ptr<Content> content) { |
|
|
return m_data->hook(host, name, std::move(content)); |
|
|
return m_data->hook(host, name, std::move(content)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Jupiter::HTTP::Server::remove(const Jupiter::ReadableString &host) { |
|
|
bool Jupiter::HTTP::Server::remove(std::string_view host) { |
|
|
return m_data->remove(host); |
|
|
return m_data->remove(host); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/*bool Jupiter::HTTP::Server::remove(const Jupiter::ReadableString &host, const Jupiter::ReadableString &path) {
|
|
|
bool Jupiter::HTTP::Server::remove(std::string_view host, std::string_view path, std::string_view name) { |
|
|
return m_data->remove(host, path); |
|
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
|
|
bool Jupiter::HTTP::Server::remove(const Jupiter::ReadableString &host, const Jupiter::ReadableString &path, const Jupiter::ReadableString &name) { |
|
|
|
|
|
return m_data->remove(host, path, name); |
|
|
return m_data->remove(host, path, name); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Jupiter::HTTP::Server::has(const Jupiter::ReadableString &host) { |
|
|
bool Jupiter::HTTP::Server::has(std::string_view host) { |
|
|
return m_data->has(host); |
|
|
return m_data->has(host); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Jupiter::HTTP::Server::has(const Jupiter::ReadableString &host, const Jupiter::ReadableString &name) { |
|
|
bool Jupiter::HTTP::Server::has(std::string_view host, std::string_view name) { |
|
|
return m_data->has(host, name); |
|
|
return m_data->has(host, name); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::find(const Jupiter::ReadableString &name) { |
|
|
Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::find(std::string_view name) { |
|
|
return m_data->find(name); |
|
|
return m_data->find(name); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::find(const Jupiter::ReadableString &host, const Jupiter::ReadableString &name) { |
|
|
Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::find(std::string_view host, std::string_view name) { |
|
|
return m_data->find(host, name); |
|
|
return m_data->find(host, name); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::ReadableString *Jupiter::HTTP::Server::execute(const Jupiter::ReadableString &name, const Jupiter::ReadableString &query_string) { |
|
|
Jupiter::ReadableString *Jupiter::HTTP::Server::execute(std::string_view name, std::string_view query_string) { |
|
|
return m_data->execute(name, query_string); |
|
|
return m_data->execute(name, query_string); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Jupiter::ReadableString *Jupiter::HTTP::Server::execute(const Jupiter::ReadableString &host, const Jupiter::ReadableString &name, const Jupiter::ReadableString &query_string) { |
|
|
Jupiter::ReadableString *Jupiter::HTTP::Server::execute(std::string_view host, std::string_view name, std::string_view query_string) { |
|
|
return m_data->execute(host, name, query_string); |
|
|
return m_data->execute(host, name, query_string); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Jupiter::HTTP::Server::bind(const Jupiter::ReadableString &hostname, uint16_t port) { |
|
|
bool Jupiter::HTTP::Server::bind(std::string_view hostname, uint16_t port) { |
|
|
auto socket = std::make_unique<Jupiter::TCPSocket>(); |
|
|
auto socket = std::make_unique<Jupiter::TCPSocket>(); |
|
|
if (socket->bind(static_cast<std::string>(hostname).c_str(), port, true)) { |
|
|
if (socket->bind(static_cast<std::string>(hostname).c_str(), port, true)) { |
|
|
socket->setBlocking(false); |
|
|
socket->setBlocking(false); |
|
@ -689,7 +720,7 @@ bool Jupiter::HTTP::Server::bind(const Jupiter::ReadableString &hostname, uint16 |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool Jupiter::HTTP::Server::tls_bind(const Jupiter::ReadableString &hostname, uint16_t port) { |
|
|
bool Jupiter::HTTP::Server::tls_bind(std::string_view hostname, uint16_t port) { |
|
|
auto socket = std::make_unique<Jupiter::SecureTCPSocket>(); |
|
|
auto socket = std::make_unique<Jupiter::SecureTCPSocket>(); |
|
|
if (socket->bind(static_cast<std::string>(hostname).c_str(), port, true)) { |
|
|
if (socket->bind(static_cast<std::string>(hostname).c_str(), port, true)) { |
|
|
m_data->m_ports.push_back(std::move(socket)); |
|
|
m_data->m_ports.push_back(std::move(socket)); |
|
@ -715,7 +746,7 @@ int Jupiter::HTTP::Server::think() { |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
else if (session->sock.recv() > 0) { |
|
|
else if (session->sock.recv() > 0) { |
|
|
const Jupiter::ReadableString &sock_buffer = session->sock.getBuffer(); |
|
|
std::string_view sock_buffer = session->sock.getBuffer(); |
|
|
if (session->request.size() + sock_buffer.size() <= m_data->max_request_size) { // accept
|
|
|
if (session->request.size() + sock_buffer.size() <= m_data->max_request_size) { // accept
|
|
|
session->request += sock_buffer; |
|
|
session->request += sock_buffer; |
|
|
if (session->request.find(HTTP_REQUEST_ENDING) != Jupiter::INVALID_INDEX) { // completed request
|
|
|
if (session->request.find(HTTP_REQUEST_ENDING) != Jupiter::INVALID_INDEX) { // completed request
|
|
@ -756,7 +787,7 @@ int Jupiter::HTTP::Server::think() { |
|
|
socket->setBlocking(false); |
|
|
socket->setBlocking(false); |
|
|
auto session = std::make_unique<HTTPSession>(std::move(*socket)); |
|
|
auto session = std::make_unique<HTTPSession>(std::move(*socket)); |
|
|
if (session->sock.recv() > 0) { // data received
|
|
|
if (session->sock.recv() > 0) { // data received
|
|
|
const Jupiter::ReadableString &sock_buffer = session->sock.getBuffer(); |
|
|
std::string_view sock_buffer = session->sock.getBuffer(); |
|
|
if (sock_buffer.size() < m_data->max_request_size) { // accept
|
|
|
if (sock_buffer.size() < m_data->max_request_size) { // accept
|
|
|
session->request = session->sock.getBuffer(); |
|
|
session->request = session->sock.getBuffer(); |
|
|
if (sock_buffer.find(HTTP_REQUEST_ENDING) != Jupiter::INVALID_INDEX) { // completed request
|
|
|
if (sock_buffer.find(HTTP_REQUEST_ENDING) != Jupiter::INVALID_INDEX) { // completed request
|
|
|