small fixes
This commit is contained in:
parent
141ac52f7d
commit
8dc707cf6b
@ -3,36 +3,45 @@ cmake_minimum_required(VERSION 3.25)
|
|||||||
project(Rum VERSION 1.0)
|
project(Rum VERSION 1.0)
|
||||||
|
|
||||||
# compiler setup
|
# compiler setup
|
||||||
set(CMAKE_CXX_COMPILER "clang++")
|
set(CMAKE_C_COMPILER clang)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror") # warnings
|
set(CMAKE_CXX_COMPILER clang++)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++2b") # std c++23
|
|
||||||
|
|
||||||
if (STATIC)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static") # static
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
endif()
|
|
||||||
|
|
||||||
if (DEBUG)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") # debug symbols
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") # optimisations
|
|
||||||
|
|
||||||
# IDE setup (clangd)
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS true)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS true)
|
||||||
|
|
||||||
file(GLOB_RECURSE SOURCES "${CMAKE_SOURCE_DIR}/src/*.cpp")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-variable -Wno-unused-private-field")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-variable -Wno-unused-private-field")
|
||||||
|
|
||||||
add_executable(server.bin ${SOURCES})
|
file(GLOB_RECURSE SOURCES "${CMAKE_SOURCE_DIR}/src/rum/*.cpp")
|
||||||
|
set(HEADERS "${CMAKE_SOURCE_DIR}/inc/rum")
|
||||||
|
add_library(rum OBJECT ${SOURCES})
|
||||||
|
set_target_properties(rum PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||||
|
target_include_directories(rum PUBLIC "${CMAKE_SOURCE_DIR}/inc")
|
||||||
|
|
||||||
target_include_directories(server.bin PRIVATE "${CMAKE_SOURCE_DIR}/inc")
|
add_library(rum-static STATIC $<TARGET_OBJECTS:rum>)
|
||||||
|
set_target_properties(rum-static PROPERTIES OUTPUT_NAME rum)
|
||||||
|
target_include_directories(rum-static PUBLIC "${CMAKE_SOURCE_DIR}/inc")
|
||||||
|
|
||||||
add_custom_target(run
|
add_library(rum-shared SHARED $<TARGET_OBJECTS:rum>)
|
||||||
COMMAND $<TARGET_FILE:server.bin>
|
set_target_properties(rum-shared PROPERTIES OUTPUT_NAME rum)
|
||||||
DEPENDS server.bin
|
target_include_directories(rum-shared PUBLIC "${CMAKE_SOURCE_DIR}/inc")
|
||||||
COMMENT "Running server.bin"
|
|
||||||
)
|
add_executable(example "${CMAKE_SOURCE_DIR}/src/server.cpp")
|
||||||
|
target_link_libraries(example rum-shared)
|
||||||
add_custom_target(docker
|
if(USE_FLAGS)
|
||||||
COMMAND docker build -t dowerx/rum:${CMAKE_PROJECT_VERSION} ..
|
target_link_libraries(example flags-cpp)
|
||||||
COMMENT "Building docker image"
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS
|
||||||
|
rum-static
|
||||||
|
rum-shared
|
||||||
|
RUNTIME
|
||||||
|
COMPONENT Runtime
|
||||||
|
LIBRARY
|
||||||
|
COMPONENT Runtime
|
||||||
|
ARCHIVE
|
||||||
|
COMPONENT Development
|
||||||
)
|
)
|
||||||
|
install(DIRECTORY ${HEADERS} DESTINATION include COMPONENT Development)
|
@ -13,6 +13,7 @@ class Request {
|
|||||||
|
|
||||||
Method get_method() const { return method; }
|
Method get_method() const { return method; }
|
||||||
URI& get_uri() { return uri; }
|
URI& get_uri() { return uri; }
|
||||||
|
URI copy_uri() const { return uri; }
|
||||||
|
|
||||||
const std::map<std::string, std::string>& get_headers() const { return headers; }
|
const std::map<std::string, std::string>& get_headers() const { return headers; }
|
||||||
std::string get_header(std::string name) const { return headers.at(name); }
|
std::string get_header(std::string name) const { return headers.at(name); }
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <format>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -2,8 +2,11 @@
|
|||||||
#include <rum/tcp/error.h>
|
#include <rum/tcp/error.h>
|
||||||
#include <rum/tcp/server.h>
|
#include <rum/tcp/server.h>
|
||||||
#include <rum/tcp/utility.h>
|
#include <rum/tcp/utility.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstddef>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Rum::HTTP {
|
namespace Rum::HTTP {
|
||||||
@ -28,8 +31,11 @@ Server::Server(unsigned int port, size_t worker_count, size_t buffer_size) : Rum
|
|||||||
tasks.pop();
|
tasks.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
std::cout << "Worker #" << i << " accepted a connection." << std::endl;
|
std::cout << "Worker #" << i << " accepted a connection." << std::endl;
|
||||||
|
#else
|
||||||
|
(void)i;
|
||||||
|
#endif
|
||||||
handler(task.client_sock, task.sockaddr, buffer);
|
handler(task.client_sock, task.sockaddr, buffer);
|
||||||
if (int status = close(task.client_sock); status == TCP::Error::UNKNOWN) {
|
if (int status = close(task.client_sock); status == TCP::Error::UNKNOWN) {
|
||||||
std::cerr << TCP::to_string(task.sockaddr) << ": " << TCP::Error((TCP::Error::Type)status).what() << std::endl;
|
std::cerr << TCP::to_string(task.sockaddr) << ": " << TCP::Error((TCP::Error::Type)status).what() << std::endl;
|
||||||
@ -37,7 +43,9 @@ Server::Server(unsigned int port, size_t worker_count, size_t buffer_size) : Rum
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
workers.emplace_back(std::move(worker));
|
workers.emplace_back(std::move(worker));
|
||||||
|
#ifdef DEBUG
|
||||||
std::cout << "Worker #" << i << " created" << std::endl;
|
std::cout << "Worker #" << i << " created" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,8 +96,9 @@ Method string_to_method(std::string text) {
|
|||||||
|
|
||||||
void Server::handler(int client_sock, const sockaddr_in& client_address, char* buffer) {
|
void Server::handler(int client_sock, const sockaddr_in& client_address, char* buffer) {
|
||||||
std::string address = TCP::to_string(client_address);
|
std::string address = TCP::to_string(client_address);
|
||||||
|
#ifdef DEBUG
|
||||||
std::cout << address << ": connected" << std::endl;
|
std::cout << address << ": connected" << std::endl;
|
||||||
|
#endif
|
||||||
Request request;
|
Request request;
|
||||||
|
|
||||||
enum Stage { METHOD, HEADER, BODY };
|
enum Stage { METHOD, HEADER, BODY };
|
||||||
@ -152,10 +161,13 @@ void Server::handler(int client_sock, const sockaddr_in& client_address, char* b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
request.set_header(it->str(1), it->str(2));
|
std::string key(it->str(1));
|
||||||
|
std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||||
|
request.set_header(key, it->str(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
message = message.substr(message.find("\r\n\r\n"));
|
|
||||||
|
message = message.substr(message.find("\r\n\r\n") + 4);
|
||||||
|
|
||||||
if (Method method = request.get_method(); method == POST || method == PUT)
|
if (Method method = request.get_method(); method == POST || method == PUT)
|
||||||
stage = BODY;
|
stage = BODY;
|
||||||
@ -164,6 +176,17 @@ void Server::handler(int client_sock, const sockaddr_in& client_address, char* b
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stage == BODY) {
|
if (stage == BODY) {
|
||||||
|
std::cout << "here" << std::endl;
|
||||||
|
|
||||||
|
try {
|
||||||
|
size_t content_length = std::stoul(request.get_header("content-length"));
|
||||||
|
std::cout << message.size() << " " << content_length << std::endl;
|
||||||
|
if (message.size() < content_length)
|
||||||
|
continue;
|
||||||
|
} catch (std::out_of_range) {
|
||||||
|
} catch (std::invalid_argument e) {
|
||||||
|
std::cerr << "invlaid Content-Length header" << std::endl;
|
||||||
|
}
|
||||||
request.set_body(message);
|
request.set_body(message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <format>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Rum::HTTP {
|
namespace Rum::HTTP {
|
||||||
@ -27,11 +28,13 @@ URI::operator std::string() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
URI::URI(const std::string& uri) {
|
URI::URI(const std::string& uri) {
|
||||||
std::regex uri_regex(R"((([\w\d]+):\/\/)?(([\w\d]+)(:([\w\d]+)?)@)?([\w\d\.]+)(:(\d+))?(\/?[\w\d\.\/]+)?(\?([\w\d\=\&]+))?(\#([\w\d]*))?)");
|
std::regex uri_regex(R"((([\w\d]+):\/\/)?(([\w\d]+)(:([\w\d]+)?)@)?([\w\d\.]+)(:(\d+))?(\/?[\w\d\.\/]+)?(\?([^#]+))?(\#([\w\d]*))?)");
|
||||||
|
|
||||||
std::smatch match;
|
std::smatch match;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
std::cout << uri << std::endl;
|
std::cout << uri << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (std::regex_match(uri.cbegin(), uri.cend(), match, uri_regex)) {
|
if (std::regex_match(uri.cbegin(), uri.cend(), match, uri_regex)) {
|
||||||
#define MATCH(var, i) \
|
#define MATCH(var, i) \
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include <flags/flags.h>
|
#ifdef USE_FLAGS
|
||||||
|
#include <flags-cpp/flags-cpp.h>
|
||||||
|
#endif
|
||||||
#include <rum/http/http.h>
|
#include <rum/http/http.h>
|
||||||
#include <rum/tcp/error.h>
|
#include <rum/tcp/error.h>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
@ -7,6 +9,8 @@
|
|||||||
Rum::HTTP::Server* server;
|
Rum::HTTP::Server* server;
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
#ifdef USE_FLAGS
|
||||||
|
|
||||||
Flags::Parser parser;
|
Flags::Parser parser;
|
||||||
int* port = parser.add<int>("port", "tcp port number", false, 8080);
|
int* port = parser.add<int>("port", "tcp port number", false, 8080);
|
||||||
unsigned long int* workers = parser.add<unsigned long int>("workers", "number of worker threads", false, 10);
|
unsigned long int* workers = parser.add<unsigned long int>("workers", "number of worker threads", false, 10);
|
||||||
@ -18,6 +22,11 @@ int main(int argc, char** argv) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
int* port = new int(argc >= 2 ? atoi(argv[1]) : 8080);
|
||||||
|
unsigned long* workers = new unsigned long(10);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::cout << "Port: " << *port << std::endl;
|
std::cout << "Port: " << *port << std::endl;
|
||||||
std::cout << "Workers: " << *workers << std::endl;
|
std::cout << "Workers: " << *workers << std::endl;
|
||||||
|
|
||||||
@ -41,6 +50,11 @@ int main(int argc, char** argv) {
|
|||||||
resp.body = "<h1>Cookie</h1><pre>" + (std::string)req + "</pre>";
|
resp.body = "<h1>Cookie</h1><pre>" + (std::string)req + "</pre>";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server->add_path<Rum::HTTP::POST>("/add", [](const Rum::HTTP::Request& req, Rum::HTTP::Response& resp) {
|
||||||
|
std::cout << (std::string)req << std::endl;
|
||||||
|
resp.body = "<h1>Hello World</h1><pre>" + (std::string)req + "</pre>";
|
||||||
|
});
|
||||||
|
|
||||||
server->add_path<Rum::HTTP::GET>("/.*", [](const Rum::HTTP::Request& req, Rum::HTTP::Response& resp) {
|
server->add_path<Rum::HTTP::GET>("/.*", [](const Rum::HTTP::Request& req, Rum::HTTP::Response& resp) {
|
||||||
std::cout << "request accepted" << std::endl;
|
std::cout << "request accepted" << std::endl;
|
||||||
resp.body = "<h1>Hello World</h1><pre>" + (std::string)req + "</pre>";
|
resp.body = "<h1>Hello World</h1><pre>" + (std::string)req + "</pre>";
|
||||||
|
Loading…
Reference in New Issue
Block a user