diff --git a/.gitignore b/.gitignore index 378eac2..707f4da 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ build +projects/build* +projects/qt-creator/*.user diff --git a/Makefile b/Makefile index 2451e56..5900f8e 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ $(BUILDDIR): $(MKDIR) $@ $(EXECUTABLE): $(OBJECTS) - $(CXX) $(LDFLAGS) $(OBJECTS) -o $@ + $(CXX) $(OBJECTS) -o $@ $(LDFLAGS) $(OBJECTS) : $(OBJDIR)/%.o : $(SOURCEDIR)/%.cpp @$(MKDIR) $(dir $@) diff --git a/projects/msvs/httpserverapp.vcxproj b/projects/msvs/httpserverapp.vcxproj index 7994785..cec4a76 100644 --- a/projects/msvs/httpserverapp.vcxproj +++ b/projects/msvs/httpserverapp.vcxproj @@ -20,14 +20,13 @@ - - - - - - + + + + + @@ -42,14 +41,13 @@ - - - - - - + + + + + diff --git a/projects/msvs/httpserverapp.vcxproj.filters b/projects/msvs/httpserverapp.vcxproj.filters index f082fe2..1e4277e 100644 --- a/projects/msvs/httpserverapp.vcxproj.filters +++ b/projects/msvs/httpserverapp.vcxproj.filters @@ -54,25 +54,22 @@ Source Files - - Source Files - - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files @@ -128,25 +125,22 @@ Header Files - - Header Files - - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files diff --git a/projects/msvs/httpserverapp.vcxproj.user b/projects/msvs/httpserverapp.vcxproj.user index deabe1c..223f65b 100644 --- a/projects/msvs/httpserverapp.vcxproj.user +++ b/projects/msvs/httpserverapp.vcxproj.user @@ -12,4 +12,7 @@ $(ProjectDir) WindowsLocalDebugger + + true + \ No newline at end of file diff --git a/projects/qt-creator/httpserverapp.qbs b/projects/qt-creator/httpserverapp.qbs index e12b20e..56d90fc 100644 --- a/projects/qt-creator/httpserverapp.qbs +++ b/projects/qt-creator/httpserverapp.qbs @@ -26,14 +26,14 @@ Project { "../../src/Init.h", "../../src/application/Test.cpp", "../../src/application/Test.h", - "../../src/client/protocol/ClientHttp1.cpp", - "../../src/client/protocol/ClientHttp1.h", - "../../src/client/protocol/ClientHttp2.cpp", - "../../src/client/protocol/ClientHttp2.h", - "../../src/client/protocol/ClientProtocol.cpp", - "../../src/client/protocol/ClientProtocol.h", - "../../src/client/protocol/WebSocket.cpp", - "../../src/client/protocol/WebSocket.h", + "../../src/server/protocol/ServerHttp1.cpp", + "../../src/server/protocol/ServerHttp1.h", + "../../src/server/protocol/ServerHttp2.cpp", + "../../src/server/protocol/ServerHttp2.h", + "../../src/server/protocol/ServerProtocol.cpp", + "../../src/server/protocol/ServerProtocol.h", + "../../src/server/protocol/WebSocket.cpp", + "../../src/server/protocol/WebSocket.h", "../../src/utils/Event.cpp", "../../src/utils/Event.h", "../../src/transfer/FileIncoming.cpp", @@ -45,10 +45,10 @@ Project { "../../src/transfer/HttpStatusCode.h", "../../src/Main.cpp", "../../src/Main.h", - "../../src/client/Request.cpp", - "../../src/client/Request.h", - "../../src/client/Response.cpp", - "../../src/client/Response.h", + "../../src/server/Request.cpp", + "../../src/server/Request.h", + "../../src/server/Response.cpp", + "../../src/server/Response.h", "../../src/transfer/ProtocolVariant.h", "../../src/transfer/AppRequest.h", "../../src/transfer/AppResponse.h", diff --git a/src/Init.cpp b/src/Init.cpp index 6cd85d2..0831bdb 100644 --- a/src/Init.cpp +++ b/src/Init.cpp @@ -7,93 +7,147 @@ #include "transfer/http2/Http2.h" #include "utils/Utils.h" -#include "client/protocol/ClientHttp1.h" -#include "client/protocol/ClientHttp2.h" +#include "server/protocol/ServerHttp1.h" +#include "server/protocol/ServerHttp2.h" -Socket::Adapter *createSocketAdapter(Transfer::app_request *request, void *addr) -{ - if (request->tls_session) - { +#include +#include + +Socket::Adapter *createSocketAdapter( + Transfer::app_request *request, + void *addr +) { + if (request->tls_session) { return new (addr) Socket::AdapterTls(request->tls_session); } return new (addr) Socket::AdapterDefault(request->socket); } -void destroySocketAdapter(Socket::Adapter *adapter) -{ - if (adapter) - { +void destroySocketAdapter(Socket::Adapter *adapter) { + if (adapter) { adapter->~Adapter(); } } -std::string getClearPath(const std::string &path) +std::string utf8ToLocal(const std::string &u8str) { - const size_t pos = path.find_first_of("?#"); + std::locale loc(""); - if (std::string::npos == pos) - { - return Utils::urlDecode(path); - } + std::wstring_convert > conv; + std::wstring wstr = conv.from_bytes(u8str); + + std::string str(wstr.size(), 0); + + std::use_facet >(loc).narrow( + wstr.data(), + wstr.data() + wstr.size(), + '?', + &str.front() + ); - return Utils::urlDecode(path.substr(0, pos) ); + return str; } -static void getIncomingVars(std::unordered_multimap ¶ms, const std::string &uri) +std::string getClearPath(const std::string &path) { + const size_t pos = path.find_first_of("?#"); + + const std::string clean = Utils::urlDecode( + std::string::npos == pos + ? path + : path.substr(0, pos) + ); + +#ifdef WIN32 + return utf8ToLocal(clean); +#else + return clean; +#endif +} + +static void getIncomingVars( + std::unordered_multimap ¶ms, + const std::string &uri +) { const size_t start = uri.find('?'); - if (std::string::npos == start) - { + if (std::string::npos == start) { return; } const size_t finish = uri.find('#'); - if (finish < start) - { + if (finish < start) { return; } - for (size_t var_pos = start + 1, var_end = 0; std::string::npos != var_end; var_pos = var_end + 1) - { + for ( + size_t var_pos = start + 1, var_end = 0; + std::string::npos != var_end; + var_pos = var_end + 1 + ) { var_end = uri.find('&', var_pos); - if (var_end > finish) - { + if (var_end > finish) { var_end = std::string::npos; } size_t delimiter = uri.find('=', var_pos); - if (delimiter >= var_end) - { - std::string var_name = Utils::urlDecode(uri.substr(var_pos, std::string::npos != var_end ? var_end - var_pos : std::string::npos) ); - - params.emplace(std::move(var_name), std::string() ); - } - else - { - std::string var_name = Utils::urlDecode(uri.substr(var_pos, delimiter - var_pos) ); + if (delimiter >= var_end) { + std::string var_name = Utils::urlDecode( + uri.substr( + var_pos, + std::string::npos != var_end + ? var_end - var_pos + : std::string::npos + ) + ); + + params.emplace( + std::move(var_name), + std::string() + ); + } else { + std::string var_name = Utils::urlDecode( + uri.substr( + var_pos, + delimiter - var_pos + ) + ); ++delimiter; - std::string var_value = Utils::urlDecode(uri.substr(delimiter, std::string::npos != var_end ? var_end - delimiter : std::string::npos) ); - - params.emplace(std::move(var_name), std::move(var_value) ); + std::string var_value = Utils::urlDecode( + uri.substr( + delimiter, + std::string::npos != var_end + ? var_end - delimiter + : std::string::npos + ) + ); + + params.emplace( + std::move(var_name), + std::move(var_value) + ); } } } -bool initServerObjects(HttpClient::Request *procRequest, HttpClient::Response *procResponse, const Transfer::app_request *request, Socket::Adapter *socket_adapter) -{ +bool initServerObjects( + HttpServer::Request *procRequest, + HttpServer::Response *procResponse, + const Transfer::app_request *request, + Socket::Adapter *socket_adapter +) { const uint8_t *src = reinterpret_cast(request->request_data); size_t protocol_number; src = Utils::unpackNumber(&protocol_number, src); Transfer::ProtocolVariant protocol_variant = static_cast(protocol_number); - HttpClient::ClientProtocol *prot = nullptr; + HttpServer::ServerProtocol *prot = nullptr; std::string document_root; std::string host; @@ -121,14 +175,13 @@ bool initServerObjects(HttpClient::Request *procRequest, HttpClient::Response *p auto const it_cookie = headers.find("cookie"); - if (headers.cend() != it_cookie) - { + if (headers.cend() != it_cookie) { Utils::parseCookies(it_cookie->second, cookies); } getIncomingVars(params, path); - prot = new HttpClient::ClientHttp1(socket_adapter); + prot = new HttpServer::ServerHttp1(socket_adapter); break; } @@ -140,26 +193,25 @@ bool initServerObjects(HttpClient::Request *procRequest, HttpClient::Response *p src = Utils::unpackString(path, src); src = Utils::unpackString(method, src); - size_t stream_id; + size_t number; - src = Utils::unpackNumber(&stream_id, src); + src = Utils::unpackNumber(&number, src); + const uint32_t stream_id = static_cast(number); Http2::ConnectionSettings settings; - size_t number; - src = Utils::unpackNumber(&number, src); - settings.header_table_size = number; + settings.header_table_size = static_cast(number); src = Utils::unpackNumber(&number, src); - settings.enable_push = number; + settings.enable_push = static_cast(number); src = Utils::unpackNumber(&number, src); - settings.max_concurrent_streams = number; + settings.max_concurrent_streams = static_cast(number); src = Utils::unpackNumber(&number, src); - settings.initial_window_size = number; + settings.initial_window_size = static_cast(number); src = Utils::unpackNumber(&number, src); - settings.max_frame_size = number; + settings.max_frame_size = static_cast(number); src = Utils::unpackNumber(&number, src); - settings.max_header_list_size = number; + settings.max_header_list_size = static_cast(number); std::deque > dynamic_table; src = Utils::unpackVector(dynamic_table, src); @@ -171,23 +223,37 @@ bool initServerObjects(HttpClient::Request *procRequest, HttpClient::Response *p src = Utils::unpackContainer(data, src); src = Utils::unpackFilesIncoming(files, src); + auto const it_cookie = headers.find("cookie"); + + if (headers.cend() != it_cookie) { + Utils::parseCookies(it_cookie->second, cookies); + } + getIncomingVars(params, path); - Http2::OutStream *stream = new Http2::OutStream(stream_id, settings, Http2::DynamicTable(settings.header_table_size, settings.max_header_list_size, std::move(dynamic_table) ), mtx); + Http2::OutStream *stream = new Http2::OutStream( + stream_id, + settings, + Http2::DynamicTable( + settings.header_table_size, + settings.max_header_list_size, + std::move(dynamic_table) + ), + mtx + ); - prot = new HttpClient::ClientHttp2(socket_adapter, stream); + prot = new HttpServer::ServerHttp2(socket_adapter, stream); break; } - default: - { + default: { success = false; break; } } - *procRequest = HttpClient::Request { + *procRequest = HttpServer::Request { prot, std::move(document_root), std::move(host), @@ -201,7 +267,7 @@ bool initServerObjects(HttpClient::Request *procRequest, HttpClient::Response *p protocol_variant }; - *procResponse = HttpClient::Response { + *procResponse = HttpServer::Response { prot, protocol_variant, std::unordered_map(), @@ -211,32 +277,48 @@ bool initServerObjects(HttpClient::Request *procRequest, HttpClient::Response *p return success; } -void freeProtocolData(HttpClient::Response *response) -{ - if (response) - { +void freeProtocolData(HttpServer::Response *response) { + if (response) { delete response->prot; } } -bool isSwitchingProtocols(const HttpClient::Request &request, HttpClient::Response &response) -{ - if (request.prot->getSocket()->get_tls_session() != 0) - { +bool isSwitchingProtocols( + const HttpServer::Request &request, + HttpServer::Response &response +) { + // Check for https is not set + if (request.prot->getSocket()->get_tls_session() != nullptr) { return false; } + // Check for upgrade to https + /*auto const it_upgrade_insecure = request.headers.find("upgrade-insecure-requests"); + + if (request.headers.cend() != it_upgrade_insecure) { + if (it_upgrade_insecure->second == "1") { + response.status = Http::StatusCode::MOVED_TEMPORARILY; + response.headers["location"] = "https://" + request.host + request.path; + response.headers["strict-transport-security"] = "max-age=86400"; + + const std::string headers = "HTTP/1.1 307 Moved Temporarily\r\nLocation: https://" + request.host + request.path + "\r\nStrict-Transport-Security: max-age=86400\r\n\r\n"; + + response.prot->getSocket()->nonblock_send(headers, std::chrono::milliseconds(5000) ); + + return true; + } + }*/ + + // Check if switch protocol to h2c auto const it_upgrade = request.headers.find("upgrade"); - if (request.headers.cend() == it_upgrade) - { + if (request.headers.cend() == it_upgrade) { return false; } auto const it_connection = request.headers.find("connection"); - if (request.headers.cend() == it_connection) - { + if (request.headers.cend() == it_connection) { return false; } @@ -244,33 +326,28 @@ bool isSwitchingProtocols(const HttpClient::Request &request, HttpClient::Respon bool is_upgrade = false; - for (auto &item : list) - { + for (auto &item : list) { Utils::toLower(item); - if ("upgrade" == item) - { + if ("upgrade" == item) { is_upgrade = true; break; } } - if (false == is_upgrade) - { + if (false == is_upgrade) { return false; } const std::string &upgrade = it_upgrade->second; - if ("h2c" != upgrade) - { + if ("h2c" != upgrade) { return false; } auto const it_settings = request.headers.find("http2-settings"); - if (request.headers.cend() == it_settings) - { + if (request.headers.cend() == it_settings) { return false; } @@ -279,7 +356,10 @@ bool isSwitchingProtocols(const HttpClient::Request &request, HttpClient::Respon const std::string headers = "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nUpgrade: h2c\r\n\r\n"; - response.prot->getSocket()->nonblock_send(headers, std::chrono::milliseconds(5000) ); + response.prot->getSocket()->nonblock_send( + headers, + std::chrono::milliseconds(5000) + ); return true; } diff --git a/src/Init.h b/src/Init.h index 8c85e8b..b7a4c0b 100644 --- a/src/Init.h +++ b/src/Init.h @@ -1,16 +1,29 @@ #pragma once -#include "client/Request.h" -#include "client/Response.h" +#include "server/Request.h" +#include "server/Response.h" #include "transfer/AppRequest.h" #include "transfer/AppResponse.h" -Socket::Adapter *createSocketAdapter(Transfer::app_request *request, void *addr); +Socket::Adapter *createSocketAdapter( + Transfer::app_request *request, + void *addr +); + void destroySocketAdapter(Socket::Adapter *adapter); std::string getClearPath(const std::string &path); -bool initServerObjects(HttpClient::Request *procRequest, HttpClient::Response *procResponse, const Transfer::app_request *request, Socket::Adapter *socket_adapter); -void freeProtocolData(HttpClient::Response *response); +bool initServerObjects( + HttpServer::Request *procRequest, + HttpServer::Response *procResponse, + const Transfer::app_request *request, + Socket::Adapter *socket_adapter +); + +void freeProtocolData(HttpServer::Response *response); -bool isSwitchingProtocols(const HttpClient::Request &request, HttpClient::Response &response); +bool isSwitchingProtocols( + const HttpServer::Request &request, + HttpServer::Response &response +); diff --git a/src/Main.cpp b/src/Main.cpp index 2024468..270689e 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -1,4 +1,4 @@ - + #include "Main.h" #include "Init.h" @@ -11,19 +11,20 @@ EXPORT bool application_init(const char *root) return true; } -EXPORT int application_call(Transfer::app_request *request, Transfer::app_response *response) -{ +EXPORT int application_call( + Transfer::app_request *request, + Transfer::app_response *response +) { // Allocate memory on the stack uint8_t addr[sizeof(Socket::AdapterTls)]; // Create the socket adapter Socket::Adapter *socket_adapter = createSocketAdapter(request, addr); - HttpClient::Request proc_request; - HttpClient::Response proc_response; + HttpServer::Request proc_request; + HttpServer::Response proc_response; - if (false == initServerObjects(&proc_request, &proc_response, request, socket_adapter) ) - { + if (initServerObjects(&proc_request, &proc_response, request, socket_adapter) == false) { return EXIT_FAILURE; } @@ -31,34 +32,34 @@ EXPORT int application_call(Transfer::app_request *request, Transfer::app_respon int result = EXIT_SUCCESS; - if (isSwitchingProtocols(proc_request, proc_response) ) - { + if (isSwitchingProtocols(proc_request, proc_response) ) { - } - else if (std::string::npos == absolute_path.find("/../") && System::isFileExists(absolute_path) ) - { + } else if ( + std::string::npos == absolute_path.find("/../") && + System::isFileExists(absolute_path) + ) { auto it_connection = proc_request.headers.find("connection"); - if (proc_request.headers.cend() != it_connection) - { + if (proc_request.headers.cend() != it_connection) { proc_response.headers["connection"] = it_connection->second; } proc_response.headers["x-sendfile"] = absolute_path; - } - else - { + } else { // Call application result = Application::test(proc_request, proc_response); } destroySocketAdapter(socket_adapter); - if (proc_response.headers.size() ) - { + if (proc_response.headers.size() ) { response->data_size = Utils::getPackContainerSize(proc_response.headers); response->response_data = new uint8_t[response->data_size]; - Utils::packContainer(reinterpret_cast(response->response_data), proc_response.headers); + + Utils::packContainer( + reinterpret_cast(response->response_data), + proc_response.headers + ); } freeProtocolData(&proc_response); @@ -68,8 +69,7 @@ EXPORT int application_call(Transfer::app_request *request, Transfer::app_respon EXPORT void application_clear(void *response_data, size_t response_size) { - if (response_data && response_size) - { + if (response_data && response_size) { delete[] reinterpret_cast(response_data); } } diff --git a/src/application/Test.cpp b/src/application/Test.cpp index d503da5..78249e0 100644 --- a/src/application/Test.cpp +++ b/src/application/Test.cpp @@ -5,8 +5,10 @@ namespace Application { - bool test(HttpClient::Request &request, HttpClient::Response &response) - { + bool test( + HttpServer::Request &request, + HttpServer::Response &response + ) { // Output incoming headers std::string s = R"( @@ -135,14 +137,12 @@ namespace Application const std::chrono::milliseconds timeout(5000); - if (response.sendHeaders(additional, timeout, s.empty() ) ) - { - if (false == s.empty() ) - { + if (response.sendHeaders(additional, timeout, s.empty() ) ) { + if (s.empty() == false) { response.sendData(s.data(), s.size(), timeout, true); } } return EXIT_SUCCESS; } -}; +} diff --git a/src/application/Test.h b/src/application/Test.h index 66764ce..d6a6316 100644 --- a/src/application/Test.h +++ b/src/application/Test.h @@ -1,9 +1,12 @@ #pragma once -#include "../client/Request.h" -#include "../client/Response.h" +#include "../server/Request.h" +#include "../server/Response.h" namespace Application { - bool test(HttpClient::Request &, HttpClient::Response &); -}; + bool test( + HttpServer::Request &, + HttpServer::Response & + ); +} diff --git a/src/client/Request.cpp b/src/client/Request.cpp deleted file mode 100644 index c6686fc..0000000 --- a/src/client/Request.cpp +++ /dev/null @@ -1,54 +0,0 @@ - -#include "Request.h" - -namespace HttpClient -{ - std::string Request::getHeader(const std::string &key) const - { - auto it = headers.find(key); - - return headers.end() != it ? it->second : ""; - } - - bool Request::isDataExists(const std::string &key) const - { - return data.cend() != data.find(key); - } - - std::string Request::getDataAsString(const std::string &key) const - { - auto it = data.find(key); - - return data.end() != it ? it->second : ""; - } - - std::vector Request::getDataAsArray(const std::string &key) const - { - std::vector arr; - - size_t count = data.count(key); - - if (count) - { - auto range = data.equal_range(key); - - arr.resize(count); - - size_t i = 0; - - for (auto it = range.first; it != range.second; ++it) - { - arr[i++] = it->second; - } - } - - return arr; - } - - std::string Request::getCookieAsString(const std::string &cookieName) const - { - auto it = cookies.find(cookieName); - - return cookies.end() != it ? it->second : ""; - } -}; diff --git a/src/client/Response.cpp b/src/client/Response.cpp deleted file mode 100644 index 2af748a..0000000 --- a/src/client/Response.cpp +++ /dev/null @@ -1,29 +0,0 @@ - -#include "Response.h" - -#include "../transfer/http2/HPack.h" - -#include - -namespace HttpClient -{ - void Response::setStatusCode(const Http::StatusCode status) - { - this->status = status; - } - - bool Response::sendHeaders(const std::vector > &additional, const std::chrono::milliseconds &timeout, const bool endStream) - { - std::vector > headers; - - std::copy(this->headers.begin(), this->headers.end(), std::back_inserter(headers) ); - std::copy(additional.begin(), additional.end(), std::back_inserter(headers) ); - - return this->prot->sendHeaders(this->status, headers, timeout, endStream); - } - - long Response::sendData(const void *src, const size_t size, const std::chrono::milliseconds &timeout, const bool endStream) const - { - return this->prot->sendData(src, size, timeout, endStream); - } -}; diff --git a/src/client/Response.h b/src/client/Response.h deleted file mode 100644 index 73b3343..0000000 --- a/src/client/Response.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "protocol/ClientProtocol.h" -#include "../transfer/ProtocolVariant.h" -#include "../transfer/HttpStatusCode.h" - -#include -#include - -namespace HttpClient -{ - struct Response - { - ClientProtocol *prot; - Transfer::ProtocolVariant protocol_variant; - std::unordered_map headers; - Http::StatusCode status; - - public: - void setStatusCode(const Http::StatusCode status); - - bool sendHeaders(const std::vector > &additional, const std::chrono::milliseconds &timeout, const bool endStream = true); - long sendData(const void *src, const size_t size, const std::chrono::milliseconds &timeout, const bool endStream = true) const; - }; -}; diff --git a/src/client/protocol/ClientHttp1.cpp b/src/client/protocol/ClientHttp1.cpp deleted file mode 100644 index cfa923b..0000000 --- a/src/client/protocol/ClientHttp1.cpp +++ /dev/null @@ -1,29 +0,0 @@ - -#include "ClientHttp1.h" - -namespace HttpClient -{ - ClientHttp1::ClientHttp1(Socket::Adapter *sock) : ClientProtocol(sock) - { - - } - - bool ClientHttp1::sendHeaders(const Http::StatusCode status, std::vector > &headers, const std::chrono::milliseconds &timeout, const bool endStream) const - { - std::string out = "HTTP/1.1 " + std::to_string(static_cast(status) ) + "\r\n"; - - for (auto const &h : headers) - { - out += h.first + ": " + h.second + "\r\n"; - } - - out += "\r\n"; - - return this->sock->nonblock_send(out, timeout) > 0; - } - - long ClientHttp1::sendData(const void *src, const size_t size, const std::chrono::milliseconds &timeout, const bool endStream) const - { - return this->sock->nonblock_send(src, size, timeout); - } -}; diff --git a/src/client/protocol/ClientHttp1.h b/src/client/protocol/ClientHttp1.h deleted file mode 100644 index 556d231..0000000 --- a/src/client/protocol/ClientHttp1.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "ClientProtocol.h" - -namespace HttpClient -{ - class ClientHttp1 : public ClientProtocol - { - public: - ClientHttp1(Socket::Adapter *sock); - - virtual bool sendHeaders(const Http::StatusCode status, std::vector > &headers, const std::chrono::milliseconds &timeout, const bool endStream = true) const override; - virtual long sendData(const void *src, const size_t size, const std::chrono::milliseconds &timeout, const bool endStream = true) const override; - }; -}; diff --git a/src/client/protocol/ClientHttp2.cpp b/src/client/protocol/ClientHttp2.cpp deleted file mode 100644 index ac91aae..0000000 --- a/src/client/protocol/ClientHttp2.cpp +++ /dev/null @@ -1,188 +0,0 @@ - -#include "ClientHttp2.h" - -#include "../../transfer/http2/HPack.h" - -#include -#include - -namespace HttpClient -{ - ClientHttp2::ClientHttp2(Socket::Adapter *sock, Http2::OutStream *stream) - : ClientProtocol(sock), stream(stream) - { - - } - - ClientHttp2::~ClientHttp2() noexcept - { - delete this->stream; - } - - static uint8_t getPaddingSize(const size_t dataSize) - { - if (0 == dataSize) - { - return 0; - } - - std::random_device rd; - - uint8_t padding = rd(); - - while (dataSize <= padding) - { - padding /= 2; - } - - return padding; - } - - bool ClientHttp2::sendHeaders(const Http::StatusCode status, std::vector > &headers, const std::chrono::milliseconds &timeout, const bool endStream) const - { - std::vector buf; - buf.reserve(4096); - buf.resize(Http2::FRAME_HEADER_SIZE + sizeof(uint8_t) ); - - headers.emplace(headers.begin(), ":status", std::to_string(static_cast(status) ) ); - - HPack::pack(buf, headers, this->stream->dynamic_table); - - uint32_t data_size = buf.size() - Http2::FRAME_HEADER_SIZE - sizeof(uint8_t); - - const uint8_t padding = getPaddingSize(data_size); - const uint16_t padding_size = padding + sizeof(uint8_t); - - if (data_size + padding_size > this->stream->settings.max_frame_size) - { - data_size = this->stream->settings.max_frame_size - padding_size; - } - - const size_t frame_size = data_size + padding_size; - - buf.resize(frame_size + Http2::FRAME_HEADER_SIZE); - - Http2::FrameFlag flags = Http2::FrameFlag::END_HEADERS; - - if (endStream) - { - flags |= Http2::FrameFlag::END_STREAM; - } - - flags |= Http2::FrameFlag::PADDED; - - buf[Http2::FRAME_HEADER_SIZE] = padding; - - if (padding) - { - std::fill(buf.end() - padding, buf.end(), 0); - } - - this->stream->setHttp2FrameHeader(reinterpret_cast(buf.data() ), frame_size, Http2::FrameType::HEADERS, flags); - - const std::unique_lock lock(*this->stream->mtx); - - return this->sock->nonblock_send(buf.data(), buf.size(), timeout) > 0; - } - - void ClientHttp2::sendWindowUpdate(const uint32_t size, const std::chrono::milliseconds &timeout) const - { - std::array buf; - uint8_t *addr = buf.data(); - - addr = this->stream->setHttp2FrameHeader(addr, sizeof(uint32_t), Http2::FrameType::WINDOW_UPDATE, Http2::FrameFlag::EMPTY); - - *reinterpret_cast(addr) = ::htonl(size); - - const std::unique_lock lock(*this->stream->mtx); - - this->sock->nonblock_send(buf.data(), buf.size(), timeout); - } - - long ClientHttp2::sendData(const void *src, const size_t size, const std::chrono::milliseconds &timeout, const bool endStream) const - { - const uint8_t *data = reinterpret_cast(src); - - std::vector buf; - buf.reserve(this->stream->settings.max_frame_size + Http2::FRAME_HEADER_SIZE); - - size_t total = 0; - - while (total < size) - { - size_t data_size = (size - total < this->stream->settings.max_frame_size) ? size - total : this->stream->settings.max_frame_size; - - const uint8_t padding = getPaddingSize(data_size); - const uint16_t padding_size = padding + sizeof(uint8_t); - - if (data_size + padding_size > this->stream->settings.max_frame_size) - { - data_size = this->stream->settings.max_frame_size - padding_size; - } - - const size_t frame_size = data_size + padding_size; - - buf.resize(frame_size + Http2::FRAME_HEADER_SIZE); - - if (static_cast(this->stream->window_size_out - this->stream->settings.max_frame_size) <= 0) - { - size_t update_size = this->stream->settings.initial_window_size + (size - total) - this->stream->window_size_out; - - if (update_size > Http2::MAX_WINDOW_UPDATE) - { - update_size = Http2::MAX_WINDOW_UPDATE; - } - - this->sendWindowUpdate(static_cast(update_size), timeout); - - this->stream->window_size_out += update_size; - } - - Http2::FrameFlag flags = Http2::FrameFlag::EMPTY; - - if (endStream && (total + data_size >= size) ) - { - flags |= Http2::FrameFlag::END_STREAM; - } - - size_t cur = Http2::FRAME_HEADER_SIZE; - - if (padding_size) - { - flags |= Http2::FrameFlag::PADDED; - - buf[cur] = padding; - - ++cur; - } - - this->stream->setHttp2FrameHeader(buf.data(), frame_size, Http2::FrameType::DATA, flags); - - std::copy(data, data + data_size, buf.begin() + cur); - - if (padding) - { - std::fill(buf.end() - padding, buf.end(), 0); - } - - this->stream->lock(); - - const long sended = this->sock->nonblock_send(buf.data(), buf.size(), timeout); - - this->stream->unlock(); - - if (sended <= 0) - { - total = 0; - break; - } - - this->stream->window_size_out -= frame_size; - - data += data_size; - total += data_size; - } - - return static_cast(total); - } -}; diff --git a/src/client/protocol/ClientHttp2.h b/src/client/protocol/ClientHttp2.h deleted file mode 100644 index 9aedbca..0000000 --- a/src/client/protocol/ClientHttp2.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "ClientProtocol.h" - -#include "../../transfer/http2/Http2.h" - -namespace HttpClient -{ - class ClientHttp2 : public ClientProtocol - { - protected: - Http2::OutStream *stream; - - public: - ClientHttp2(Socket::Adapter *sock, Http2::OutStream *stream); - virtual ~ClientHttp2() noexcept; - - void sendWindowUpdate(const uint32_t size, const std::chrono::milliseconds &timeout) const; - - virtual bool sendHeaders(const Http::StatusCode status, std::vector > &headers, const std::chrono::milliseconds &timeout, const bool endStream = true) const override; - virtual long sendData(const void *src, const size_t size, const std::chrono::milliseconds &timeout, const bool endStream = true) const override; - }; -}; diff --git a/src/client/protocol/ClientProtocol.cpp b/src/client/protocol/ClientProtocol.cpp deleted file mode 100644 index ca759f1..0000000 --- a/src/client/protocol/ClientProtocol.cpp +++ /dev/null @@ -1,20 +0,0 @@ - -#include "ClientProtocol.h" - -namespace HttpClient -{ - ClientProtocol::ClientProtocol(Socket::Adapter *sock) : sock(sock) - { - - } - - Socket::Adapter *ClientProtocol::getSocket() noexcept - { - return this->sock; - } - - void ClientProtocol::close() noexcept - { - this->sock->close(); - } -}; diff --git a/src/client/protocol/ClientProtocol.h b/src/client/protocol/ClientProtocol.h deleted file mode 100644 index 58ad9f2..0000000 --- a/src/client/protocol/ClientProtocol.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "../../socket/Adapter.h" -#include "../../transfer/HttpStatusCode.h" - -namespace HttpClient -{ - class ClientProtocol - { - protected: - Socket::Adapter *sock; - - public: - ClientProtocol(Socket::Adapter *sock); - virtual ~ClientProtocol() noexcept = default; - - Socket::Adapter *getSocket() noexcept; - - virtual bool sendHeaders(const Http::StatusCode status, std::vector > &headers, const std::chrono::milliseconds &timeout, const bool endStream = true) const = 0; - virtual long sendData(const void *src, const size_t size, const std::chrono::milliseconds &timeout, const bool endStream = true) const = 0; - - virtual void close() noexcept; - }; -}; diff --git a/src/server/Request.cpp b/src/server/Request.cpp new file mode 100644 index 0000000..c78934a --- /dev/null +++ b/src/server/Request.cpp @@ -0,0 +1,75 @@ + +#include "Request.h" + +namespace HttpServer +{ + std::string Request::getHeader(const std::string &key) const { + auto it = headers.find(key); + return headers.end() != it ? it->second : std::string(); + } + + bool Request::isDataExists(const std::string &key) const { + return data.cend() != data.find(key); + } + + std::string Request::getDataAsString(const std::string &key) const { + auto it = data.find(key); + return data.end() != it ? it->second : std::string(); + } + + std::vector Request::getDataAsArray(const std::string &key) const + { + std::vector arr; + + size_t count = data.count(key); + + if (count) { + auto range = data.equal_range(key); + + arr.resize(count); + + size_t i = 0; + + for (auto it = range.first; it != range.second; ++it) { + arr[i++] = it->second; + } + } + + return arr; + } + + bool Request::isFileExists(const std::string &key) const { + return this->files.cend() != this->files.find(key); + } + + Transfer::FileIncoming Request::getFile(const std::string &key) const { + auto const it = this->files.find(key); + return this->files.end() != it ? it->second : Transfer::FileIncoming(); + } + + std::vector Request::getFilesAsArray(const std::string &key) const + { + std::vector arr; + + const size_t count = this->files.count(key); + + if (count) { + auto const range = this->files.equal_range(key); + + arr.resize(count); + + size_t i = 0; + + for (auto it = range.first; it != range.second; ++it) { + arr[i++] = it->second; + } + } + + return arr; + } + + std::string Request::getCookieAsString(const std::string &cookieName) const { + auto it = cookies.find(cookieName); + return cookies.end() != it ? it->second : std::string(); + } +} diff --git a/src/client/Request.h b/src/server/Request.h similarity index 86% rename from src/client/Request.h rename to src/server/Request.h index cc74368..1255c65 100644 --- a/src/client/Request.h +++ b/src/server/Request.h @@ -1,12 +1,12 @@ -#pragma once +#pragma once -#include "protocol/ClientProtocol.h" +#include "protocol/ServerProtocol.h" #include "../transfer/FileIncoming.h" #include "../transfer/ProtocolVariant.h" #include -namespace HttpClient +namespace HttpServer { /** * Структура запроса (входные данные) @@ -23,7 +23,7 @@ namespace HttpClient */ struct Request { - ClientProtocol *prot; + ServerProtocol *prot; std::string document_root; std::string host; std::string path; @@ -45,6 +45,12 @@ namespace HttpClient std::vector getDataAsArray(const std::string &key) const; + bool isFileExists(const std::string &key) const; + + Transfer::FileIncoming getFile(const std::string &key) const; + + std::vector getFilesAsArray(const std::string &key) const; + std::string getCookieAsString(const std::string &cookieName) const; }; -}; +} diff --git a/src/server/Response.cpp b/src/server/Response.cpp new file mode 100644 index 0000000..27ec2c6 --- /dev/null +++ b/src/server/Response.cpp @@ -0,0 +1,60 @@ + +#include "Response.h" + +#include "../transfer/http2/HPack.h" + +#include + +namespace HttpServer +{ + void Response::setStatusCode( + const Http::StatusCode status + ) noexcept { + this->status = status; + } + + bool Response::sendHeaders( + const std::vector > &additional, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const { + std::vector > headers; + + headers.reserve( + this->headers.size() + additional.size() + ); + + headers.insert( + headers.end(), + this->headers.cbegin(), + this->headers.cend() + ); + + headers.insert( + headers.end(), + additional.cbegin(), + additional.cend() + ); + + return this->prot->sendHeaders( + this->status, + headers, + timeout, + endStream + ); + } + + long Response::sendData( + const void *src, + const size_t size, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const noexcept { + return this->prot->sendData( + src, + size, + timeout, + endStream + ); + } +} diff --git a/src/server/Response.h b/src/server/Response.h new file mode 100644 index 0000000..79ad7a8 --- /dev/null +++ b/src/server/Response.h @@ -0,0 +1,35 @@ +#pragma once + +#include "protocol/ServerProtocol.h" +#include "../transfer/ProtocolVariant.h" +#include "../transfer/HttpStatusCode.h" + +#include +#include + +namespace HttpServer +{ + struct Response + { + ServerProtocol *prot; + Transfer::ProtocolVariant protocol_variant; + std::unordered_map headers; + Http::StatusCode status; + + public: + void setStatusCode(const Http::StatusCode status) noexcept; + + bool sendHeaders( + const std::vector > &additional, + const std::chrono::milliseconds &timeout, + const bool endStream = true + ) const; + + long sendData( + const void *src, + const size_t size, + const std::chrono::milliseconds &timeout, + const bool endStream = true + ) const noexcept; + }; +} diff --git a/src/server/protocol/ServerHttp1.cpp b/src/server/protocol/ServerHttp1.cpp new file mode 100644 index 0000000..350f7c3 --- /dev/null +++ b/src/server/protocol/ServerHttp1.cpp @@ -0,0 +1,41 @@ + +#include "ServerHttp1.h" + +namespace HttpServer +{ + ServerHttp1::ServerHttp1(Socket::Adapter *sock) noexcept + : ServerProtocol(sock) + { + + } + + bool ServerHttp1::sendHeaders( + const Http::StatusCode status, + std::vector > &headers, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const { + std::string out = "HTTP/1.1 " + std::to_string(static_cast(status) ) + "\r\n"; + + for (auto const &h : headers) { + out += h.first + ": " + h.second + "\r\n"; + } + + out += "\r\n"; + + return this->sock->nonblock_send(out, timeout) > 0; + } + + long ServerHttp1::sendData( + const void *src, + const size_t size, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const noexcept { + return this->sock->nonblock_send( + src, + size, + timeout + ); + } +} diff --git a/src/server/protocol/ServerHttp1.h b/src/server/protocol/ServerHttp1.h new file mode 100644 index 0000000..55b3b08 --- /dev/null +++ b/src/server/protocol/ServerHttp1.h @@ -0,0 +1,26 @@ +#pragma once + +#include "ServerProtocol.h" + +namespace HttpServer +{ + class ServerHttp1 : public ServerProtocol + { + public: + ServerHttp1(Socket::Adapter *sock) noexcept; + + virtual bool sendHeaders( + const Http::StatusCode status, + std::vector > &headers, + const std::chrono::milliseconds &timeout, + const bool endStream = true + ) const override; + + virtual long sendData( + const void *src, + const size_t size, + const std::chrono::milliseconds &timeout, + const bool endStream = true + ) const noexcept override; + }; +} diff --git a/src/server/protocol/ServerHttp2.cpp b/src/server/protocol/ServerHttp2.cpp new file mode 100644 index 0000000..fd64c82 --- /dev/null +++ b/src/server/protocol/ServerHttp2.cpp @@ -0,0 +1,239 @@ + +#include "ServerHttp2.h" + +#include "../../transfer/http2/HPack.h" + +#include +#include + +namespace HttpServer +{ + ServerHttp2::ServerHttp2( + Socket::Adapter *sock, + Http2::OutStream *stream + ) noexcept + : ServerProtocol(sock), stream(stream) + { + + } + + ServerHttp2::~ServerHttp2() noexcept { + delete this->stream; + } + + static uint8_t getPaddingSize(const size_t dataSize) + { + if (0 == dataSize) { + return 0; + } + + std::random_device rd; + + uint8_t padding = uint8_t(rd()); + + while (dataSize <= padding) { + padding /= 2; + } + + return padding; + } + + bool ServerHttp2::sendHeaders( + const Http::StatusCode status, + std::vector > &headers, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const { + std::vector buf; + buf.reserve(4096); + + buf.resize( + Http2::FRAME_HEADER_SIZE + sizeof(uint8_t) + ); + + headers.emplace( + headers.begin(), + ":status", + std::to_string(static_cast(status) ) + ); + + HPack::pack(buf, headers, this->stream->dynamic_table); + + size_t data_size = ( + buf.size() - Http2::FRAME_HEADER_SIZE - sizeof(uint8_t) + ); + + const uint8_t padding = getPaddingSize(data_size); + const uint16_t padding_size = padding + sizeof(uint8_t); + + if (data_size + padding_size > this->stream->settings.max_frame_size) { + data_size = this->stream->settings.max_frame_size - padding_size; + } + + const uint32_t frame_size = static_cast( + data_size + padding_size + ); + + buf.resize( + frame_size + Http2::FRAME_HEADER_SIZE + ); + + Http2::FrameFlag flags = Http2::FrameFlag::END_HEADERS; + + if (endStream) { + flags |= Http2::FrameFlag::END_STREAM; + } + + flags |= Http2::FrameFlag::PADDED; + + buf[Http2::FRAME_HEADER_SIZE] = char(padding); + + if (padding) { + std::fill( + buf.end() - padding, + buf.end(), + 0 + ); + } + + this->stream->setHttp2FrameHeader( + reinterpret_cast(buf.data() ), + frame_size, + Http2::FrameType::HEADERS, + flags + ); + + const std::unique_lock lock(*this->stream->mtx); + + return this->sock->nonblock_send(buf.data(), buf.size(), timeout) > 0; + } + + void ServerHttp2::sendWindowUpdate( + const uint32_t size, + const std::chrono::milliseconds &timeout + ) const { + std::array buf; + uint8_t *addr = buf.data(); + + addr = this->stream->setHttp2FrameHeader( + addr, + sizeof(uint32_t), + Http2::FrameType::WINDOW_UPDATE, + Http2::FrameFlag::EMPTY + ); + + *reinterpret_cast(addr) = ::htonl(size); + + const std::unique_lock lock(*this->stream->mtx); + + this->sock->nonblock_send(buf.data(), buf.size(), timeout); + } + + long ServerHttp2::sendData( + const void *src, + const size_t size, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const noexcept { + const uint8_t *data = reinterpret_cast(src); + + std::vector buf; + + buf.reserve( + this->stream->settings.max_frame_size + Http2::FRAME_HEADER_SIZE + ); + + size_t total = 0; + + while (total < size) + { + size_t data_size = (size - total < this->stream->settings.max_frame_size) + ? size - total + : this->stream->settings.max_frame_size; + + const uint8_t padding = getPaddingSize(data_size); + const uint16_t padding_size = padding + sizeof(uint8_t); + + if (data_size + padding_size > this->stream->settings.max_frame_size) { + data_size = this->stream->settings.max_frame_size - padding_size; + } + + const uint32_t frame_size = static_cast( + data_size + padding_size + ); + + buf.resize(frame_size + Http2::FRAME_HEADER_SIZE); + + if (this->stream->window_size_out - long(this->stream->settings.max_frame_size) <= 0) + { + size_t update_size = this->stream->settings.initial_window_size + + (size - total) - size_t(this->stream->window_size_out); + + if (update_size > Http2::MAX_WINDOW_UPDATE) { + update_size = Http2::MAX_WINDOW_UPDATE; + } + + this->sendWindowUpdate(uint32_t(update_size), timeout); + + this->stream->window_size_out += update_size; + } + + Http2::FrameFlag flags = Http2::FrameFlag::EMPTY; + + if (endStream && (total + data_size >= size) ) { + flags |= Http2::FrameFlag::END_STREAM; + } + + size_t cur = Http2::FRAME_HEADER_SIZE; + + if (padding_size) { + flags |= Http2::FrameFlag::PADDED; + buf[cur] = padding; + ++cur; + } + + this->stream->setHttp2FrameHeader( + buf.data(), + frame_size, + Http2::FrameType::DATA, + flags + ); + + std::copy( + data, + data + data_size, + buf.data() + cur + ); + + if (padding) { + std::fill( + buf.end() - padding, + buf.end(), + 0 + ); + } + + this->stream->lock(); + + const long sended = this->sock->nonblock_send( + buf.data(), + buf.size(), + timeout + ); + + this->stream->unlock(); + + if (sended <= 0) { + total = 0; + break; + } + + this->stream->window_size_out -= frame_size; + + data += data_size; + total += data_size; + } + + return long(total); + } +} diff --git a/src/server/protocol/ServerHttp2.h b/src/server/protocol/ServerHttp2.h new file mode 100644 index 0000000..b7389f1 --- /dev/null +++ b/src/server/protocol/ServerHttp2.h @@ -0,0 +1,41 @@ +#pragma once + +#include "ServerProtocol.h" + +#include "../../transfer/http2/Http2.h" + +namespace HttpServer +{ + class ServerHttp2 : public ServerProtocol + { + protected: + Http2::OutStream *stream; + + public: + ServerHttp2( + Socket::Adapter *sock, + Http2::OutStream *stream + ) noexcept; + + virtual ~ServerHttp2() noexcept override; + + void sendWindowUpdate( + const uint32_t size, + const std::chrono::milliseconds &timeout + ) const; + + virtual bool sendHeaders( + const Http::StatusCode status, + std::vector > &headers, + const std::chrono::milliseconds &timeout, + const bool endStream = true + ) const override; + + virtual long sendData( + const void *src, + const size_t size, + const std::chrono::milliseconds &timeout, + const bool endStream = true + ) const noexcept override; + }; +} diff --git a/src/server/protocol/ServerProtocol.cpp b/src/server/protocol/ServerProtocol.cpp new file mode 100644 index 0000000..d5ac1dd --- /dev/null +++ b/src/server/protocol/ServerProtocol.cpp @@ -0,0 +1,19 @@ + +#include "ServerProtocol.h" + +namespace HttpServer +{ + ServerProtocol::ServerProtocol(Socket::Adapter *sock) noexcept + : sock(sock) + { + + } + + Socket::Adapter *ServerProtocol::getSocket() noexcept { + return this->sock; + } + + void ServerProtocol::close() noexcept { + this->sock->close(); + } +} diff --git a/src/server/protocol/ServerProtocol.h b/src/server/protocol/ServerProtocol.h new file mode 100644 index 0000000..f0c211c --- /dev/null +++ b/src/server/protocol/ServerProtocol.h @@ -0,0 +1,35 @@ +#pragma once + +#include "../../socket/Adapter.h" +#include "../../transfer/HttpStatusCode.h" + +namespace HttpServer +{ + class ServerProtocol + { + protected: + Socket::Adapter *sock; + + public: + ServerProtocol(Socket::Adapter *sock) noexcept; + virtual ~ServerProtocol() noexcept = default; + + Socket::Adapter *getSocket() noexcept; + + virtual bool sendHeaders( + const Http::StatusCode status, + std::vector > &headers, + const std::chrono::milliseconds &timeout, + const bool endStream = true + ) const = 0; + + virtual long sendData( + const void *src, + const size_t size, + const std::chrono::milliseconds &timeout, + const bool endStream = true + ) const noexcept = 0; + + virtual void close() noexcept; + }; +} diff --git a/src/client/protocol/WebSocket.cpp b/src/server/protocol/WebSocket.cpp similarity index 73% rename from src/client/protocol/WebSocket.cpp rename to src/server/protocol/WebSocket.cpp index cc09ae2..58bffd4 100644 --- a/src/client/protocol/WebSocket.cpp +++ b/src/server/protocol/WebSocket.cpp @@ -10,22 +10,15 @@ namespace HttpClient { - WebSocket::WebSocket(const WebSocket &obj) noexcept : sock(obj.sock) - { - - } - - WebSocket::WebSocket(Socket::Adapter *adapter) noexcept : sock(adapter) - { + WebSocket::WebSocket(const WebSocket &obj) noexcept : sock(obj.sock) {} - } + WebSocket::WebSocket(Socket::Adapter *adapter) noexcept : sock(adapter) {} std::vector WebSocket::packDataToMessageFrame(const void *data, const size_t size) { std::vector frame; - if (0 == size) - { + if (0 == size) { return frame; } @@ -37,20 +30,16 @@ namespace HttpClient size_t cur_pos = sizeof(uint8_t) * 2; - if (size <= 125) - { + if (size <= 125) { frame[1] = size; } - else if (size <= 65536) - { + else if (size <= 65536) { frame[1] = 126; *reinterpret_cast(&frame[2]) = htons(size); cur_pos += sizeof(uint16_t); - } - else // More - { + } else { // More frame[1] = 127; *reinterpret_cast(&frame[2]) = Utils::hton64(size); @@ -65,13 +54,11 @@ namespace HttpClient return frame; } - Socket::Adapter *WebSocket::getSocket() noexcept - { + Socket::Adapter *WebSocket::getSocket() noexcept { return this->sock; } - const Socket::Adapter *WebSocket::getSocket() const noexcept - { + const Socket::Adapter *WebSocket::getSocket() const noexcept { return this->sock; } @@ -81,8 +68,7 @@ namespace HttpClient const long recv_size = this->sock->nonblock_recv(buf, timeout); - if (recv_size <= 0) - { + if (recv_size <= 0) { return recv_size; } @@ -90,8 +76,7 @@ namespace HttpClient const uint8_t info_frame = buf[0]; - if ( (info_frame & 0x08) == 0x08) // opcode 0x08 — close connection - { + if ( (info_frame & 0x08) == 0x08) { // opcode 0x08 — close connection return -1; } @@ -105,60 +90,43 @@ namespace HttpClient uint64_t frame_size; - if (info_size <= 125) - { + if (info_size <= 125) { frame_size = info_size; } - else if (info_size == 126) - { + else if (info_size == 126) { frame_size = ntohs(*reinterpret_cast(&buf[cur_pos]) ); - cur_pos += sizeof(uint16_t); - } - else // if (info_size == 127) - { + } else { // if (info_size == 127) frame_size = Utils::ntoh64(*reinterpret_cast(&buf[cur_pos]) ); - cur_pos += sizeof(uint64_t); } - if (frame_size > (buf.size() - cur_pos) ) - { + if (frame_size > (buf.size() - cur_pos) ) { return -1; // Close connection } uint32_t mask; - if (is_mask_set) - { + if (is_mask_set) { mask = *reinterpret_cast(&buf[cur_pos]); - cur_pos += sizeof(uint32_t); } - const uint8_t align = (recv_size - cur_pos) % sizeof(uint32_t); - - frame.reserve(recv_size - cur_pos + align); + frame.reserve(recv_size - cur_pos); frame.assign(buf.cbegin() + cur_pos, buf.cbegin() + recv_size); - if (is_mask_set) - { - if (align) - { - frame.insert(frame.cend(), align, 0); - } + if (is_mask_set) { + const size_t aligned = frame.size() - (frame.size() % sizeof(mask)); - uint32_t *addr = reinterpret_cast(frame.data() ); + uint32_t * const addr = reinterpret_cast(frame.data() ); - for (size_t i = 0; i < frame.size() / sizeof(uint32_t); ++i) - { + for (size_t i = 0; i < aligned / sizeof(uint32_t); ++i) { addr[i] ^= mask; } - if (align) - { - frame.erase(frame.cend() - align, frame.cend() ); + for (size_t i = aligned; i < frame.size(); ++i) { + frame[i] ^= reinterpret_cast(&mask)[i % sizeof(mask)]; } } @@ -169,8 +137,7 @@ namespace HttpClient { const std::vector frame = WebSocket::packDataToMessageFrame(data, length); - if (frame.empty() ) - { + if (frame.empty() ) { return 0; } @@ -181,16 +148,14 @@ namespace HttpClient { const std::vector frame = WebSocket::packDataToMessageFrame(str.data(), str.length() ); - if (frame.empty() ) - { + if (frame.empty() ) { return 0; } return this->sock->nonblock_send(frame.data(), frame.size(), timeout); } - void WebSocket::close() noexcept - { + void WebSocket::close() noexcept { this->sock->close(); } -}; +} diff --git a/src/client/protocol/WebSocket.h b/src/server/protocol/WebSocket.h similarity index 99% rename from src/client/protocol/WebSocket.h rename to src/server/protocol/WebSocket.h index 937f9f1..ad1a672 100644 --- a/src/client/protocol/WebSocket.h +++ b/src/server/protocol/WebSocket.h @@ -27,4 +27,4 @@ namespace HttpClient void close() noexcept; }; -}; +} diff --git a/src/socket/Adapter.cpp b/src/socket/Adapter.cpp index d0524b0..c99bee6 100644 --- a/src/socket/Adapter.cpp +++ b/src/socket/Adapter.cpp @@ -3,23 +3,33 @@ namespace Socket { - long Adapter::nonblock_recv(std::vector &buf, const std::chrono::milliseconds &timeout) const noexcept - { - return this->nonblock_recv(buf.data(), buf.size(), timeout); + long Adapter::nonblock_recv( + std::vector &buf, + const std::chrono::milliseconds &timeout + ) const noexcept { + return this->nonblock_recv( + buf.data(), + buf.size(), + timeout + ); } - long Adapter::nonblock_send(const std::string &buf, const std::chrono::milliseconds &timeout) const noexcept - { - return this->nonblock_send(buf.data(), buf.length(), timeout); + long Adapter::nonblock_send( + const std::string &buf, + const std::chrono::milliseconds &timeout + ) const noexcept { + return this->nonblock_send( + buf.data(), + buf.length(), + timeout + ); } - bool Adapter::operator ==(const Adapter &obj) const noexcept - { + bool Adapter::operator ==(const Adapter &obj) const noexcept { return this->get_handle() == obj.get_handle(); } - bool Adapter::operator !=(const Adapter &obj) const noexcept - { + bool Adapter::operator !=(const Adapter &obj) const noexcept { return this->get_handle() != obj.get_handle(); } -}; +} diff --git a/src/socket/Adapter.h b/src/socket/Adapter.h index 554714f..2787176 100644 --- a/src/socket/Adapter.h +++ b/src/socket/Adapter.h @@ -19,15 +19,31 @@ namespace Socket virtual ::gnutls_session_t get_tls_session() const noexcept = 0; virtual Adapter *copy() const noexcept = 0; - long nonblock_recv(std::vector &buf, const std::chrono::milliseconds &timeout) const noexcept; - virtual long nonblock_recv(void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept = 0; - - long nonblock_send(const std::string &buf, const std::chrono::milliseconds &timeout) const noexcept; - virtual long nonblock_send(const void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept = 0; + long nonblock_recv( + std::vector &buf, + const std::chrono::milliseconds &timeout + ) const noexcept; + + virtual long nonblock_recv( + void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept = 0; + + long nonblock_send( + const std::string &buf, + const std::chrono::milliseconds &timeout + ) const noexcept; + + virtual long nonblock_send( + const void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept = 0; virtual void close() noexcept = 0; bool operator ==(const Adapter &obj) const noexcept; bool operator !=(const Adapter &obj) const noexcept; }; -}; +} diff --git a/src/socket/AdapterDefault.cpp b/src/socket/AdapterDefault.cpp index d71d6a2..2940daf 100644 --- a/src/socket/AdapterDefault.cpp +++ b/src/socket/AdapterDefault.cpp @@ -3,42 +3,41 @@ namespace Socket { - AdapterDefault::AdapterDefault(const Socket &_sock) noexcept : sock(_sock) - { + AdapterDefault::AdapterDefault(const Socket &sock) noexcept : sock(sock) {} - } - - System::native_socket_type AdapterDefault::get_handle() const noexcept - { + System::native_socket_type AdapterDefault::get_handle() const noexcept { return sock.get_handle(); } - ::gnutls_session_t AdapterDefault::get_tls_session() const noexcept - { - return 0; + ::gnutls_session_t AdapterDefault::get_tls_session() const noexcept { + return nullptr; } - Adapter *AdapterDefault::copy() const noexcept - { + Adapter *AdapterDefault::copy() const noexcept { return new AdapterDefault(this->sock); } - long AdapterDefault::nonblock_recv(void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept - { + long AdapterDefault::nonblock_recv( + void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept { return sock.nonblock_recv(buf, length, timeout); } - long AdapterDefault::nonblock_send(const void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept - { + long AdapterDefault::nonblock_send( + const void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept { return sock.nonblock_send(buf, length, timeout); } - void AdapterDefault::close() noexcept - { + void AdapterDefault::close() noexcept { // Wait for send all data to client sock.nonblock_send_sync(); sock.shutdown(); sock.close(); } -}; +} diff --git a/src/socket/AdapterDefault.h b/src/socket/AdapterDefault.h index 0008fa9..db8b191 100644 --- a/src/socket/AdapterDefault.h +++ b/src/socket/AdapterDefault.h @@ -18,9 +18,18 @@ namespace Socket virtual ::gnutls_session_t get_tls_session() const noexcept override; virtual Adapter *copy() const noexcept override; - virtual long nonblock_recv(void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept override; - virtual long nonblock_send(const void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept override; + virtual long nonblock_recv( + void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept override; + + virtual long nonblock_send( + const void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept override; virtual void close() noexcept override; }; -}; +} diff --git a/src/socket/AdapterTls.cpp b/src/socket/AdapterTls.cpp index 65de7f5..0126830 100644 --- a/src/socket/AdapterTls.cpp +++ b/src/socket/AdapterTls.cpp @@ -3,8 +3,11 @@ namespace Socket { - AdapterTls::AdapterTls(const Socket &sock, ::gnutls_priority_t priority_cache, ::gnutls_certificate_credentials_t x509_cred) noexcept - { + AdapterTls::AdapterTls( + const Socket &sock, + ::gnutls_priority_t priority_cache, + ::gnutls_certificate_credentials_t x509_cred + ) noexcept { // https://leandromoreira.com.br/2015/10/12/how-to-optimize-nginx-configuration-for-http2-tls-ssl/ // https://www.gnutls.org/manual/html_node/False-Start.html @@ -33,23 +36,20 @@ namespace Socket ::gnutls_alpn_set_protocols(this->session, protocols, sizeof(protocols) / sizeof(::gnutls_datum_t), 0); } - AdapterTls::AdapterTls(const ::gnutls_session_t session) noexcept : session(session) - { - - } + AdapterTls::AdapterTls(const ::gnutls_session_t session) noexcept : session(session) {} bool AdapterTls::handshake() noexcept { int ret; - do - { + ::gnutls_handshake_set_timeout(this->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); + + do { ret = ::gnutls_handshake(this->session); } while (ret < 0 && ::gnutls_error_is_fatal(ret) == 0); - if (ret < 0) - { + if (ret < 0) { Socket sock(this->get_handle() ); sock.close(); @@ -61,82 +61,94 @@ namespace Socket return true; } - long AdapterTls::nonblock_send_all(const void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept - { - // size_t record_size = ::gnutls_record_get_max_size(this->session); + long AdapterTls::nonblock_send_all( + const void *buf, const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept { size_t record_size = length; - if (0 == record_size) - { + if (0 == record_size) { return -1; } Socket sock(this->get_handle() ); - // ::gnutls_record_set_timeout(this->session, static_cast(timeout.count() ) ); - size_t total = 0; - while (total < length) - { - if (record_size > length - total) - { + while (total < length) { + if (record_size > length - total) { record_size = length - total; } - // const long send_size = ::gnutls_record_send(this->session, reinterpret_cast(buf) + total, record_size); - long send_size = 0; - do - { + do { sock.nonblock_send_sync(); + + send_size = ::gnutls_record_send( + this->session, + reinterpret_cast(buf) + total, + record_size + ); } - while (GNUTLS_E_AGAIN == (send_size = ::gnutls_record_send(this->session, reinterpret_cast(buf) + total, record_size) ) ); + while (GNUTLS_E_AGAIN == send_size); - if (send_size < 0) - { + if (send_size < 0) { return send_size; } - total += send_size; + total += long(send_size); } - return static_cast(total); + return long(total); } - System::native_socket_type AdapterTls::get_handle() const noexcept - { - return static_cast(::gnutls_transport_get_int(this->session) ); + System::native_socket_type AdapterTls::get_handle() const noexcept { + return static_cast( + ::gnutls_transport_get_int(this->session) + ); } - ::gnutls_session_t AdapterTls::get_tls_session() const noexcept - { + ::gnutls_session_t AdapterTls::get_tls_session() const noexcept { return this->session; } - Adapter *AdapterTls::copy() const noexcept - { + Adapter *AdapterTls::copy() const noexcept { return new AdapterTls(this->session); } - long AdapterTls::nonblock_recv(void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept - { - // ::gnutls_record_set_timeout(this->session, static_cast(timeout.count() ) ); - + long AdapterTls::nonblock_recv( + void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept { Socket sock(this->get_handle() ); - sock.nonblock_recv_sync(); - return ::gnutls_record_recv(this->session, buf, length); + long result; + + do { + if (sock.nonblock_recv_sync(timeout) == false) { + // Timeout + result = -1; + break; + } + + result = ::gnutls_record_recv(this->session, buf, length); + } + while (GNUTLS_E_AGAIN == result || GNUTLS_E_INTERRUPTED == result); + + return result; } - long AdapterTls::nonblock_send(const void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept - { + long AdapterTls::nonblock_send( + const void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept { return this->nonblock_send_all(buf, length, timeout); } - void AdapterTls::close() noexcept - { + void AdapterTls::close() noexcept { Socket sock(this->get_handle() ); // Wait for send all data to client @@ -148,4 +160,4 @@ namespace Socket ::gnutls_deinit(this->session); } -}; +} diff --git a/src/socket/AdapterTls.h b/src/socket/AdapterTls.h index 5751b7e..04aab40 100644 --- a/src/socket/AdapterTls.h +++ b/src/socket/AdapterTls.h @@ -12,19 +12,39 @@ namespace Socket public: AdapterTls() = delete; - AdapterTls(const Socket &sock, ::gnutls_priority_t priority_cache, ::gnutls_certificate_credentials_t x509_cred) noexcept; + + AdapterTls( + const Socket &sock, + ::gnutls_priority_t priority_cache, + ::gnutls_certificate_credentials_t x509_cred + ) noexcept; + AdapterTls(const ::gnutls_session_t session) noexcept; bool handshake() noexcept; - long nonblock_send_all(const void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept; + + long nonblock_send_all( + const void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept; virtual System::native_socket_type get_handle() const noexcept override; virtual ::gnutls_session_t get_tls_session() const noexcept override; virtual Adapter *copy() const noexcept override; - virtual long nonblock_recv(void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept override; - virtual long nonblock_send(const void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept override; + virtual long nonblock_recv( + void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept override; + + virtual long nonblock_send( + const void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept override; virtual void close() noexcept override; }; -}; +} diff --git a/src/socket/List.cpp b/src/socket/List.cpp index 8df0b9a..eab986d 100644 --- a/src/socket/List.cpp +++ b/src/socket/List.cpp @@ -1,4 +1,4 @@ - + #include "List.h" #ifdef POSIX @@ -16,7 +16,7 @@ namespace Socket #elif POSIX this->obj_list = ~0; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -30,12 +30,11 @@ namespace Socket obj.obj_list = ~0; obj.epoll_events.swap(this->epoll_events); #else - #error "Undefine platform" + #error "Undefined platform" #endif } - List::~List() noexcept - { + List::~List() noexcept { this->destroy(); } @@ -46,8 +45,7 @@ namespace Socket #ifdef WIN32 this->obj_list = (HANDLE) 1; - if (startListSize > 0) - { + if (startListSize > 0) { this->poll_events.reserve(startListSize); } @@ -55,19 +53,17 @@ namespace Socket #elif POSIX this->obj_list = ::epoll_create(startListSize); - if (this->obj_list == ~0) - { + if (this->obj_list == ~0) { return false; } - if (startListSize > 0) - { + if (startListSize > 0) { this->epoll_events.reserve(startListSize); } return true; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -83,7 +79,7 @@ namespace Socket this->obj_list = ~0; this->epoll_events.clear(); #else - #error "Undefine platform" + #error "Undefined platform" #endif } } @@ -95,19 +91,18 @@ namespace Socket #elif POSIX return this->obj_list != ~0; #else - #error "Undefine platform" + #error "Undefined platform" #endif } bool List::addSocket(const Socket &sock) noexcept { - if (false == this->is_created() ) - { + if (this->is_created() == false) { return false; } #ifdef WIN32 - WSAPOLLFD event = { + WSAPOLLFD event { sock.get_handle(), POLLRDNORM, 0 @@ -117,15 +112,19 @@ namespace Socket return true; #elif POSIX - struct ::epoll_event event = { + struct ::epoll_event event { EPOLLIN | EPOLLET | EPOLLRDHUP, reinterpret_cast(sock.get_handle() ) }; - const int result = ::epoll_ctl(this->obj_list, EPOLL_CTL_ADD, sock.get_handle(), &event); + const int result = ::epoll_ctl( + this->obj_list, + EPOLL_CTL_ADD, + sock.get_handle(), + &event + ); - if (result == ~0) - { + if (result == ~0) { return false; } @@ -133,22 +132,19 @@ namespace Socket return true; #else - #error "Undefine platform" + #error "Undefined platform" #endif } bool List::removeSocket(const Socket &sock) noexcept { - if (false == this->is_created() ) - { + if (this->is_created() == false) { return false; } #ifdef WIN32 - for (size_t i = 0; i < poll_events.size(); ++i) - { - if (sock.get_handle() == poll_events[i].fd) - { + for (size_t i = 0; i < poll_events.size(); ++i) { + if (sock.get_handle() == poll_events[i].fd) { poll_events.erase(poll_events.begin() + i); return true; } @@ -156,10 +152,14 @@ namespace Socket return false; #elif POSIX - const int result = ::epoll_ctl(this->obj_list, EPOLL_CTL_DEL, sock.get_handle(), nullptr); + const int result = ::epoll_ctl( + this->obj_list, + EPOLL_CTL_DEL, + sock.get_handle(), + nullptr + ); - if (result == ~0) - { + if (result == ~0) { return false; } @@ -167,7 +167,7 @@ namespace Socket return true; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -176,10 +176,13 @@ namespace Socket if (this->is_created() ) { #ifdef WIN32 - const int count = ::WSAPoll(this->poll_events.data(), static_cast<::ULONG>(this->poll_events.size() ), ~0); + const int count = ::WSAPoll( + this->poll_events.data(), + static_cast<::ULONG>(this->poll_events.size() ), + ~0 + ); - if (SOCKET_ERROR == count) - { + if (SOCKET_ERROR == count) { return false; } @@ -191,12 +194,14 @@ namespace Socket { System::native_socket_type client_socket = ~0; - do - { - client_socket = ::accept(event.fd, static_cast(nullptr), static_cast(nullptr) ); + do { + client_socket = ::accept( + event.fd, + static_cast(nullptr), + static_cast(nullptr) + ); - if (~0 != client_socket) - { + if (~0 != client_socket) { sockets.emplace_back(Socket(client_socket) ); } } @@ -206,10 +211,14 @@ namespace Socket return false == sockets.empty(); #elif POSIX - const int count = ::epoll_wait(this->obj_list, this->epoll_events.data(), this->epoll_events.size(), ~0); - - if (count == ~0) - { + const int count = ::epoll_wait( + this->obj_list, + this->epoll_events.data(), + this->epoll_events.size(), + ~0 + ); + + if (count == ~0) { return false; } @@ -221,12 +230,14 @@ namespace Socket { System::native_socket_type client_socket = ~0; - do - { - client_socket = ::accept(event.data.fd, static_cast(nullptr), static_cast(nullptr) ); + do { + client_socket = ::accept( + event.data.fd, + static_cast(nullptr), + static_cast(nullptr) + ); - if (~0 != client_socket) - { + if (~0 != client_socket) { sockets.emplace_back(Socket(client_socket) ); } } @@ -236,42 +247,47 @@ namespace Socket return false == sockets.empty(); #else - #error "Undefine platform" + #error "Undefined platform" #endif } return false; } - bool List::accept(std::vector &sockets, std::vector &socketsAddress) const noexcept - { + bool List::accept( + std::vector &sockets, + std::vector &socketsAddress + ) const noexcept { if (this->is_created() ) { #ifdef WIN32 - const int count = ::WSAPoll(this->poll_events.data(), static_cast<::ULONG>(this->poll_events.size() ), ~0); + const int count = ::WSAPoll( + this->poll_events.data(), + static_cast<::ULONG>(this->poll_events.size() ), + ~0 + ); - if (SOCKET_ERROR == count) - { + if (SOCKET_ERROR == count) { return false; } - for (size_t i = 0; i < this->poll_events.size(); ++i) + for (auto const &event : this->poll_events) { - const WSAPOLLFD &event = this->poll_events[i]; - if (event.revents & POLLRDNORM) { System::native_socket_type client_socket = ~0; - do - { + do { ::sockaddr_in client_addr {}; - socklen_t client_addr_len = sizeof(client_addr); + ::socklen_t client_addr_len = sizeof(client_addr); - client_socket = ::accept(event.fd, reinterpret_cast<::sockaddr *>(&client_addr), &client_addr_len); + client_socket = ::accept( + event.fd, + reinterpret_cast<::sockaddr *>(&client_addr), + &client_addr_len + ); - if (~0 != client_socket) - { + if (~0 != client_socket) { sockets.emplace_back(Socket(client_socket) ); socketsAddress.emplace_back(client_addr); } @@ -282,10 +298,14 @@ namespace Socket return false == sockets.empty(); #elif POSIX - const int count = ::epoll_wait(this->obj_list, this->epoll_events.data(), this->epoll_events.size(), ~0); - - if (count == ~0) - { + const int count = ::epoll_wait( + this->obj_list, + this->epoll_events.data(), + this->epoll_events.size(), + ~0 + ); + + if (count == ~0) { return false; } @@ -297,15 +317,17 @@ namespace Socket { System::native_socket_type client_socket = ~0; - do - { + do { ::sockaddr_in client_addr {}; socklen_t client_addr_len = sizeof(client_addr); - client_socket = ::accept(event.data.fd, reinterpret_cast<::sockaddr *>(&client_addr), &client_addr_len); + client_socket = ::accept( + event.data.fd, + reinterpret_cast<::sockaddr *>(&client_addr), + &client_addr_len + ); - if (~0 != client_socket) - { + if (~0 != client_socket) { sockets.emplace_back(Socket(client_socket) ); socketsAddress.emplace_back(client_addr); } @@ -316,48 +338,53 @@ namespace Socket return false == sockets.empty(); #else - #error "Undefine platform" + #error "Undefined platform" #endif } return false; } - bool List::recv(std::vector &sockets, std::vector &disconnected, std::chrono::milliseconds timeout) const noexcept - { - if (false == this->is_created() ) - { + bool List::recv( + std::vector &sockets, + std::vector &disconnected, + std::chrono::milliseconds timeout + ) const noexcept { + if (this->is_created() == false) { return false; } #ifdef WIN32 - const int count = ::WSAPoll(this->poll_events.data(), static_cast<::ULONG>(this->poll_events.size() ), static_cast<::INT>(timeout.count() ) ); + const int count = ::WSAPoll( + this->poll_events.data(), + static_cast<::ULONG>(this->poll_events.size() ), + static_cast<::INT>(timeout.count() ) + ); - if (SOCKET_ERROR == count) - { + if (SOCKET_ERROR == count) { return false; } - for (size_t i = 0; i < this->poll_events.size(); ++i) + for (auto const &event : this->poll_events) { - const WSAPOLLFD &event = this->poll_events[i]; - - if (event.revents & POLLRDNORM) - { + if (event.revents & POLLRDNORM) { sockets.emplace_back(Socket(event.fd) ); } - else if (event.revents & POLLHUP) - { + else if (event.revents & POLLHUP) { disconnected.emplace_back(Socket(event.fd) ); } } return false == sockets.empty() || false == disconnected.empty(); #elif POSIX - const int count = ::epoll_wait(this->obj_list, this->epoll_events.data(), this->epoll_events.size(), timeout.count() ); - - if (count == ~0) - { + const int count = ::epoll_wait( + this->obj_list, + this->epoll_events.data(), + this->epoll_events.size(), + timeout.count() + ); + + if (count == ~0) { return false; } @@ -365,19 +392,17 @@ namespace Socket { const epoll_event &event = this->epoll_events[i]; - if (event.events & EPOLLIN) - { + if (event.events & EPOLLIN) { sockets.emplace_back(Socket(event.data.fd) ); } - else if (event.events & EPOLLRDHUP) - { + else if (event.events & EPOLLRDHUP) { disconnected.emplace_back(Socket(event.data.fd) ); } } return false == sockets.empty() || false == disconnected.empty(); #else - #error "Undefine platform" + #error "Undefined platform" #endif } -}; +} diff --git a/src/socket/List.h b/src/socket/List.h index 650447f..cdd2747 100644 --- a/src/socket/List.h +++ b/src/socket/List.h @@ -19,7 +19,7 @@ namespace Socket int obj_list; mutable std::vector epoll_events; #else - #error "Undefine platform" + #error "Undefined platform" #endif public: @@ -35,9 +35,19 @@ namespace Socket bool addSocket(const Socket &sock) noexcept; bool removeSocket(const Socket &sock) noexcept; - bool accept(std::vector &sockets) const noexcept; - bool accept(std::vector &sockets, std::vector &socketsAddress) const noexcept; + bool accept( + std::vector &sockets + ) const noexcept; - bool recv(std::vector &sockets, std::vector &errors, std::chrono::milliseconds timeout = std::chrono::milliseconds(~0) ) const noexcept; + bool accept( + std::vector &sockets, + std::vector &socketsAddress + ) const noexcept; + + bool recv( + std::vector &sockets, + std::vector &errors, + std::chrono::milliseconds timeout = std::chrono::milliseconds(~0) + ) const noexcept; }; -}; +} diff --git a/src/socket/Socket.cpp b/src/socket/Socket.cpp index d2200bb..40b0f92 100644 --- a/src/socket/Socket.cpp +++ b/src/socket/Socket.cpp @@ -22,7 +22,7 @@ namespace Socket #elif POSIX return true; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -33,7 +33,7 @@ namespace Socket #elif POSIX return true; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -44,36 +44,25 @@ namespace Socket #elif POSIX return errno; #else - #error "Undefine platform" + #error "Undefined platform" #endif } - Socket::Socket() noexcept : socket_handle(~0) - { - - } + Socket::Socket() noexcept : socket_handle(~0) {} - Socket::Socket(const System::native_socket_type fd) noexcept : socket_handle(fd) - { - - } + Socket::Socket(const System::native_socket_type fd) noexcept : socket_handle(fd) {} - Socket::Socket(const Socket &obj) noexcept : socket_handle(obj.socket_handle) - { - - } + Socket::Socket(const Socket &obj) noexcept : socket_handle(obj.socket_handle) {} - Socket::Socket(Socket &&obj) noexcept : socket_handle(obj.socket_handle) + Socket::Socket(Socket &&obj) noexcept + : socket_handle(obj.socket_handle) { obj.socket_handle = ~0; } - bool Socket::open() noexcept - { + bool Socket::open() noexcept { this->close(); - this->socket_handle = ::socket(AF_INET, SOCK_STREAM, 0); - return this->is_open(); } @@ -86,13 +75,11 @@ namespace Socket #elif POSIX const int result = ::close(this->socket_handle); #else - #error "Undefine platform" + #error "Undefined platform" #endif - if (0 == result) - { + if (0 == result) { this->socket_handle = ~0; - return true; } } @@ -107,40 +94,49 @@ namespace Socket #elif POSIX return ~0 != this->socket_handle; #else - #error "Undefine platform" + #error "Undefined platform" #endif } - System::native_socket_type Socket::get_handle() const noexcept - { + System::native_socket_type Socket::get_handle() const noexcept { return this->socket_handle; } - bool Socket::bind(const int port) const noexcept - { - const ::sockaddr_in sock_addr = { - AF_INET, - htons(port), - ::htonl(INADDR_ANY), - 0 - }; + bool Socket::bind(const int port) const noexcept { + const ::sockaddr_in sock_addr { + AF_INET, + ::htons(port), + ::htonl(INADDR_ANY), + 0 + }; - return 0 == ::bind(this->socket_handle, reinterpret_cast(&sock_addr), sizeof(sockaddr_in) ); + return 0 == ::bind( + this->socket_handle, + reinterpret_cast(&sock_addr), + sizeof(sockaddr_in) + ); } - bool Socket::listen() const noexcept - { + bool Socket::listen() const noexcept { return 0 == ::listen(this->socket_handle, SOMAXCONN); } Socket Socket::accept() const noexcept { #ifdef WIN32 - System::native_socket_type client_socket = ::accept(this->socket_handle, static_cast(nullptr), static_cast(nullptr) ); + System::native_socket_type client_socket = ::accept( + this->socket_handle, + static_cast(nullptr), + static_cast(nullptr) + ); #elif POSIX - System::native_socket_type client_socket = ::accept(this->socket_handle, static_cast(nullptr), static_cast(nullptr) ); + System::native_socket_type client_socket = ::accept( + this->socket_handle, + static_cast(nullptr), + static_cast(nullptr) + ); #else - #error "Undefine platform" + #error "Undefined platform" #endif return Socket(client_socket); } @@ -149,29 +145,35 @@ namespace Socket { System::native_socket_type client_socket = ~0; #ifdef WIN32 - WSAPOLLFD event = { + WSAPOLLFD event { this->socket_handle, POLLRDNORM, 0 }; - if (1 == ::WSAPoll(&event, 1, ~0) && event.revents & POLLRDNORM) - { - client_socket = ::accept(this->socket_handle, static_cast(nullptr), static_cast(nullptr) ); + if (1 == ::WSAPoll(&event, 1, ~0) && event.revents & POLLRDNORM) { + client_socket = ::accept( + this->socket_handle, + static_cast(nullptr), + static_cast(nullptr) + ); } #elif POSIX - struct ::pollfd event = { + struct ::pollfd event { this->socket_handle, POLLIN, 0 }; - if (1 == ::poll(&event, 1, ~0) && event.revents & POLLIN) - { - client_socket = ::accept(this->socket_handle, static_cast(nullptr), static_cast(nullptr) ); + if (1 == ::poll(&event, 1, ~0) && event.revents & POLLIN) { + client_socket = ::accept( + this->socket_handle, + static_cast(nullptr), + static_cast(nullptr) + ); } #else - #error "Undefine platform" + #error "Undefined platform" #endif return Socket(client_socket); } @@ -180,29 +182,35 @@ namespace Socket { System::native_socket_type client_socket = ~0; #ifdef WIN32 - WSAPOLLFD event = { + WSAPOLLFD event { this->socket_handle, - POLLRDNORM, - 0 - }; + POLLRDNORM, + 0 + }; - if (1 == ::WSAPoll(&event, 1, static_cast<::INT>(timeout.count() ) ) && event.revents & POLLRDNORM) - { - client_socket = ::accept(this->socket_handle, static_cast(nullptr), static_cast(nullptr) ); + if (1 == ::WSAPoll(&event, 1, int(timeout.count()) ) && event.revents & POLLRDNORM) { + client_socket = ::accept( + this->socket_handle, + static_cast(nullptr), + static_cast(nullptr) + ); } #elif POSIX - struct ::pollfd event = { + struct ::pollfd event { this->socket_handle, - POLLIN, - 0 - }; + POLLIN, + 0 + }; - if (1 == ::poll(&event, 1, timeout.count() ) && event.revents & POLLIN) - { - client_socket = ::accept(this->socket_handle, static_cast(nullptr), static_cast(nullptr) ); + if (1 == ::poll(&event, 1, int(timeout.count()) ) && event.revents & POLLIN) { + client_socket = ::accept( + this->socket_handle, + static_cast(nullptr), + static_cast(nullptr) + ); } #else - #error "Undefine platform" + #error "Undefined platform" #endif return Socket(client_socket); } @@ -216,7 +224,7 @@ namespace Socket #elif POSIX return 0 == ::shutdown(this->socket_handle, SHUT_RDWR); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -227,11 +235,22 @@ namespace Socket { #ifdef WIN32 unsigned long value = isNonBlock; - return 0 == ::ioctlsocket(this->socket_handle, FIONBIO, &value); + + return 0 == ::ioctlsocket( + this->socket_handle, + FIONBIO, + &value + ); #elif POSIX - return ~0 != ::fcntl(this->socket_handle, F_SETFL, isNonBlock ? O_NONBLOCK : O_SYNC); + return ~0 != ::fcntl( + this->socket_handle, + F_SETFL, + isNonBlock + ? O_NONBLOCK + : O_SYNC + ); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -244,7 +263,7 @@ namespace Socket const int flags = ::fcntl(socket_handle, F_GETFL, 0); return (flags != ~0) && (flags & O_NONBLOCK); #else - #error "Undefine platform" + #error "Undefined platform" #endif } */ @@ -253,145 +272,188 @@ namespace Socket { #ifdef WIN32 int flags = nodelay ? 1 : 0; - return 0 == setsockopt(this->socket_handle, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&flags), sizeof(flags) ); + + return 0 == ::setsockopt( + this->socket_handle, + IPPROTO_TCP, + TCP_NODELAY, + reinterpret_cast(&flags), + sizeof(flags) + ); #elif POSIX int flags = nodelay ? 1 : 0; - return 0 == setsockopt(this->socket_handle, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(flags) ); + + return 0 == ::setsockopt( + this->socket_handle, + IPPROTO_TCP, + TCP_NODELAY, + &flags, + sizeof(flags) + ); #else - #error "Undefine platform" + #error "Undefined platform" #endif } - long Socket::recv(std::vector &buf) const noexcept - { + long Socket::recv( + std::vector &buf + ) const noexcept { return this->recv(buf.data(), buf.size() ); } - long Socket::recv(void *buf, const size_t length) const noexcept - { + long Socket::recv( + void *buf, + const size_t length + ) const noexcept { #ifdef WIN32 - return ::recv(this->socket_handle, reinterpret_cast(buf), static_cast(length), 0); + return ::recv( + this->socket_handle, + reinterpret_cast(buf), + static_cast(length), + 0 + ); #elif POSIX return ::recv(this->socket_handle, buf, length, 0); #else - #error "Undefine platform" + #error "Undefined platform" #endif } - long Socket::nonblock_recv(std::vector &buf, const std::chrono::milliseconds &timeout) const noexcept - { - return this->nonblock_recv(buf.data(), buf.size(), timeout); + long Socket::nonblock_recv( + std::vector &buf, + const std::chrono::milliseconds &timeout + ) const noexcept { + return this->nonblock_recv( + buf.data(), + buf.size(), + timeout + ); } - long Socket::nonblock_recv(void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept - { + long Socket::nonblock_recv( + void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept { long recv_len = ~0; #ifdef WIN32 - WSAPOLLFD event = { + WSAPOLLFD event { this->socket_handle, POLLRDNORM, 0 }; - if (1 == ::WSAPoll(&event, 1, static_cast<::INT>(timeout.count() ) ) && event.revents & POLLRDNORM) - { - recv_len = ::recv(this->socket_handle, reinterpret_cast(buf), static_cast(length), 0); + if (1 == ::WSAPoll(&event, 1, int(timeout.count()) ) && event.revents & POLLRDNORM) { + recv_len = ::recv( + this->socket_handle, + reinterpret_cast(buf), + static_cast(length), + 0 + ); } #elif POSIX - struct ::pollfd event = { + struct ::pollfd event { this->socket_handle, POLLIN, 0 }; - if (1 == ::poll(&event, 1, timeout.count() ) && event.revents & POLLIN) - { + if (1 == ::poll(&event, 1, int(timeout.count()) ) && event.revents & POLLIN) { recv_len = ::recv(this->socket_handle, buf, length, 0); } #else - #error "Undefine platform" + #error "Undefined platform" #endif return recv_len; } - void Socket::nonblock_recv_sync() const noexcept - { + bool Socket::nonblock_recv_sync( + const std::chrono::milliseconds &timeout + ) const noexcept { #ifdef WIN32 - WSAPOLLFD event = { + WSAPOLLFD event { this->socket_handle, - POLLRDNORM | POLLRDBAND, + POLLIN, 0 }; - ::WSAPoll(&event, 1, ~0); + return ::WSAPoll(&event, 1, int(timeout.count()) ) == 1; #elif POSIX - struct ::pollfd event = { + struct ::pollfd event { this->socket_handle, POLLIN, 0 }; - ::poll(&event, 1, ~0); + return ::poll(&event, 1, int(timeout.count()) ) == 1; #else - #error "Undefine platform" + #error "Undefined platform" #endif } - static long send_all(const System::native_socket_type socket_handle, const void *data, const size_t length) noexcept - { + static long send_all( + const System::native_socket_type socket_handle, + const void *data, + const size_t length + ) noexcept { size_t total = 0; - while (total < length) - { - const long send_size = ::send(socket_handle, reinterpret_cast(data) + total, length - total, 0); + while (total < length) { + const long send_size = ::send( + socket_handle, + reinterpret_cast(data) + total, + length - total, + 0 + ); - if (send_size < 0) - { + if (send_size < 0) { return send_size; } - total += send_size; + total += size_t(send_size); } return static_cast(total); } - long Socket::send(const std::string &buf) const noexcept - { + long Socket::send(const std::string &buf) const noexcept { return this->send(buf.data(), buf.length() ); } - long Socket::send(const void *buf, const size_t length) const noexcept - { + long Socket::send(const void *buf, const size_t length) const noexcept { return send_all(this->socket_handle, buf, length); } - static long nonblock_send_all(const System::native_socket_type socket_handle, const void *data, const size_t length, const std::chrono::milliseconds &timeout) noexcept - { + static long nonblock_send_all( + const System::native_socket_type socket_handle, + const void *data, + const size_t length, + const std::chrono::milliseconds &timeout + ) noexcept { size_t total = 0; #ifdef WIN32 WSAPOLLFD event = { socket_handle, - POLLWRNORM, + POLLOUT, 0 }; - while (total < length) - { - if (1 == ::WSAPoll(&event, 1, static_cast<::INT>(timeout.count() ) ) && event.revents & POLLWRNORM) - { - const long send_size = ::send(socket_handle, reinterpret_cast(data) + total, static_cast(length - total), 0); + while (total < length) { + if (1 == ::WSAPoll(&event, 1, int(timeout.count()) ) && event.revents & POLLOUT) { + const long send_size = ::send( + socket_handle, + reinterpret_cast(data) + total, + static_cast(length - total), + 0 + ); - if (send_size < 0) - { + if (send_size < 0) { return send_size; } - total += send_size; - } - else - { + total += size_t(send_size); + } else { return -1; } } @@ -403,53 +465,67 @@ namespace Socket 0 }; - while (total < length) - { - if (1 == ::poll(&event, 1, timeout.count() ) && event.revents & POLLOUT) - { - const long send_size = ::send(socket_handle, reinterpret_cast(data) + total, length - total, 0); + while (total < length) { + if (1 == ::poll(&event, 1, int(timeout.count()) ) && event.revents & POLLOUT) { + const long send_size = ::send( + socket_handle, + reinterpret_cast(data) + total, + length - total, + 0 + ); - if (send_size < 0) - { + if (send_size < 0) { return send_size; } - total += send_size; - } - else - { + total += size_t(send_size); + } else { return -1; } } #else - #error "Undefine platform" + #error "Undefined platform" #endif - return static_cast(total); + return long(total); } - long Socket::nonblock_send(const std::string &buf, const std::chrono::milliseconds &timeout) const noexcept - { - return this->nonblock_send(buf.data(), buf.length(), timeout); + long Socket::nonblock_send( + const std::string &buf, + const std::chrono::milliseconds &timeout + ) const noexcept { + return this->nonblock_send( + buf.data(), + buf.length(), + timeout + ); } - long Socket::nonblock_send(const void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept - { - return nonblock_send_all(this->socket_handle, buf, length, timeout); + long Socket::nonblock_send( + const void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept { + return nonblock_send_all( + this->socket_handle, + buf, + length, + timeout + ); } void Socket::nonblock_send_sync() const noexcept { #ifdef WIN32 - WSAPOLLFD event = { + WSAPOLLFD event { this->socket_handle, - POLLWRNORM, + POLLOUT, 0 }; ::WSAPoll(&event, 1, ~0); #elif POSIX - struct ::pollfd event = { + struct ::pollfd event { this->socket_handle, POLLOUT, 0 @@ -457,23 +533,20 @@ namespace Socket ::poll(&event, 1, ~0); #else - #error "Undefine platform" + #error "Undefined platform" #endif } - Socket &Socket::operator=(const Socket &obj) noexcept - { + Socket &Socket::operator=(const Socket &obj) noexcept { this->socket_handle = obj.socket_handle; return *this; } - bool Socket::operator ==(const Socket &obj) const noexcept - { + bool Socket::operator ==(const Socket &obj) const noexcept { return this->socket_handle == obj.socket_handle; } - bool Socket::operator !=(const Socket &obj) const noexcept - { + bool Socket::operator !=(const Socket &obj) const noexcept { return this->socket_handle != obj.socket_handle; } -}; +} diff --git a/src/socket/Socket.h b/src/socket/Socket.h index dbefb54..0d5b711 100644 --- a/src/socket/Socket.h +++ b/src/socket/Socket.h @@ -37,7 +37,10 @@ namespace Socket Socket accept() const noexcept; Socket nonblock_accept() const noexcept; - Socket nonblock_accept(const std::chrono::milliseconds &timeout) const noexcept; + + Socket nonblock_accept( + const std::chrono::milliseconds &timeout + ) const noexcept; bool shutdown() const noexcept; @@ -45,19 +48,43 @@ namespace Socket // bool is_nonblock() const noexcept; bool tcp_nodelay(const bool nodelay = true) const noexcept; - long recv(std::vector &buf) const noexcept; - long recv(void *buf, const size_t length) const noexcept; + long recv( + std::vector &buf + ) const noexcept; + + long recv( + void *buf, + const size_t length + ) const noexcept; + + long nonblock_recv( + std::vector &buf, + const std::chrono::milliseconds &timeout + ) const noexcept; - long nonblock_recv(std::vector &buf, const std::chrono::milliseconds &timeout) const noexcept; - long nonblock_recv(void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept; + long nonblock_recv( + void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept; - void nonblock_recv_sync() const noexcept; + bool nonblock_recv_sync( + const std::chrono::milliseconds &timeout + ) const noexcept; long send(const std::string &buf) const noexcept; long send(const void *buf, const size_t length) const noexcept; - long nonblock_send(const std::string &buf, const std::chrono::milliseconds &timeout) const noexcept; - long nonblock_send(const void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept; + long nonblock_send( + const std::string &buf, + const std::chrono::milliseconds &timeout + ) const noexcept; + + long nonblock_send( + const void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept; void nonblock_send_sync() const noexcept; @@ -66,16 +93,14 @@ namespace Socket bool operator ==(const Socket &obj) const noexcept; bool operator !=(const Socket &obj) const noexcept; }; -}; +} namespace std { // Hash for Socket - template<> struct hash - { - std::size_t operator()(const Socket::Socket &obj) const noexcept - { + template<> struct hash { + std::size_t operator()(const Socket::Socket &obj) const noexcept { return std::hash{}(obj.get_handle() ); } }; -}; +} diff --git a/src/system/System.cpp b/src/system/System.cpp index 16714d2..ebb5935 100644 --- a/src/system/System.cpp +++ b/src/system/System.cpp @@ -1,4 +1,4 @@ - + #include "System.h" #include @@ -20,8 +20,7 @@ namespace System { #ifdef WIN32 - struct EnumData - { + struct EnumData { native_processid_type process_id; ::HWND hWnd; }; @@ -34,16 +33,14 @@ namespace System ::GetWindowThreadProcessId(hWnd, &process_id); - if (process_id == ed.process_id && ::GetConsoleWindow() != hWnd) + if (process_id == ed.process_id && ::GetConsoleWindow() != hWnd) { std::array<::TCHAR, 257> class_name; - ::GetClassName(hWnd, class_name.data(), static_cast(class_name.size() - 1) ); + ::GetClassName(hWnd, class_name.data(), int(class_name.size() - 1) ); - if (0 == ::_tcscmp(class_name.data(), myWndClassName) ) - { + if (0 == ::_tcscmp(class_name.data(), myWndClassName) ) { ed.hWnd = hWnd; - return false; } } @@ -59,7 +56,7 @@ namespace System #elif POSIX return ::getpid(); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -76,7 +73,7 @@ namespace System #elif POSIX return 0 == ::chdir(dir.c_str() ); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -89,7 +86,7 @@ namespace System #elif POSIX return 0 == ::kill(pid, 0); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -100,8 +97,7 @@ namespace System ::EnumWindows(EnumProc, reinterpret_cast<::LPARAM>(&ed) ); - if (0 == ed.hWnd) - { + if (0 == ed.hWnd) { return false; } @@ -109,7 +105,7 @@ namespace System #elif POSIX return 0 == ::kill(pid, signal); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -120,7 +116,7 @@ namespace System #elif POSIX return 0 != ::pthread_kill(handle, 0); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -138,23 +134,21 @@ namespace System return std::string(buf.cbegin(), buf.cbegin() + len); #endif #elif POSIX - const char *buf = ::getenv("TMPDIR"); + const char *buf = ::getenv("TMPDIR"); - if (nullptr == buf) - { + if (nullptr == buf) { return std::string("/tmp/"); } std::string str(buf); - if ('/' != str.back() ) - { + if (str.back() != '/') { str.push_back('/'); } return str; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -170,8 +164,7 @@ namespace System const ::DWORD attrib = ::GetFileAttributes(file_name.c_str() ); - if (INVALID_FILE_ATTRIBUTES == attrib) - { + if (INVALID_FILE_ATTRIBUTES == attrib) { return false; } @@ -179,19 +172,21 @@ namespace System #elif POSIX struct ::stat attrib; - if (-1 == ::stat(fileName.c_str(), &attrib) ) - { + if (-1 == ::stat(fileName.c_str(), &attrib) ) { return false; } return S_ISREG(attrib.st_mode); #else - #error "Undefine platform" + #error "Undefined platform" #endif } - bool getFileSizeAndTimeGmt(const std::string &filePath, size_t *fileSize, time_t *fileTime) - { + bool getFileSizeAndTimeGmt( + const std::string &filePath, + size_t *fileSize, + time_t *fileTime + ) { #ifdef WIN32 #ifdef UNICODE std::wstring_convert> converter; @@ -200,27 +195,37 @@ namespace System const std::string &file_path = filePath; #endif - const ::HANDLE hFile = ::CreateFile(file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); + const ::HANDLE hFile = ::CreateFile( + file_path.c_str(), + GENERIC_READ, + FILE_SHARE_READ, + nullptr, + OPEN_EXISTING, + 0, + nullptr + ); - if (INVALID_HANDLE_VALUE == hFile) - { + if (INVALID_HANDLE_VALUE == hFile) { return false; } - if (false == ::GetFileSizeEx(hFile, reinterpret_cast<::PLARGE_INTEGER>(fileSize) ) ) - { + if (::GetFileSizeEx(hFile, reinterpret_cast<::PLARGE_INTEGER>(fileSize) ) == false) { ::CloseHandle(hFile); return false; } ::FILETIME ftWrite; - ::BOOL result = ::GetFileTime(hFile, nullptr, nullptr, &ftWrite); + ::BOOL result = ::GetFileTime( + hFile, + nullptr, + nullptr, + &ftWrite + ); ::CloseHandle(hFile); - if (false == result) - { + if (false == result) { return false; } @@ -237,7 +242,7 @@ namespace System stUtc.wYear - 1900, 0, 0, - -1 + -1 }; *fileTime = std::mktime(&tm_time); @@ -246,22 +251,21 @@ namespace System #elif POSIX struct ::stat attrib {}; - if (-1 == ::stat(filePath.c_str(), &attrib) ) - { + if (-1 == ::stat(filePath.c_str(), &attrib) ) { return false; } - *fileSize = attrib.st_size; + *fileSize = static_cast(attrib.st_size); std::tm clock {}; - + ::gmtime_r(&(attrib.st_mtime), &clock); *fileTime = std::mktime(&clock); return true; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -279,9 +283,11 @@ namespace System const size_t pos = memory_name.rfind(file_ext); - if (pos == memory_name.length() - file_ext.length() ) - { - memory_name.erase(memory_name.begin() + pos, memory_name.end() ); + if (pos == memory_name.length() - file_ext.length() ) { + memory_name.erase( + pos, + memory_name.length() + ); } ::TCHAR buf[MAX_PATH + 1] {}; @@ -293,28 +299,23 @@ namespace System memName = buf; #endif - for (size_t i = 1; i < memName.length(); ++i) - { - if ('/' == memName[i] || '\\' == memName[i]) - { + for (size_t i = 1; i < memName.length(); ++i) { + if ('/' == memName[i] || '\\' == memName[i]) { memName[i] = '-'; } } #elif POSIX - if ('/' != memName.front() ) - { + if (memName.front() != '/') { memName = '/' + memName; } - for (size_t i = 1; i < memName.length(); ++i) - { - if ('/' == memName[i] || '\\' == memName[i]) - { + for (size_t i = 1; i < memName.length(); ++i) { + if ('/' == memName[i] || '\\' == memName[i]) { memName[i] = '-'; } } #else - #error "Undefine platform" + #error "Undefined platform" #endif } -}; +} diff --git a/src/system/System.h b/src/system/System.h index 1ce46d2..8b637d4 100644 --- a/src/system/System.h +++ b/src/system/System.h @@ -1,33 +1,35 @@ -#pragma once +#pragma once #ifdef WIN32 #include - typedef long ssize_t; + #ifndef ssize_t + typedef long ssize_t; + #endif ::TCHAR myWndClassName[]; - #ifdef SIGTERM - #undef SIGTERM - #define SIGTERM (WM_USER + 15) - #endif + #ifdef SIGTERM + #undef SIGTERM + #define SIGTERM (WM_USER + 15) + #endif - #ifdef SIGINT - #undef SIGINT - #define SIGINT (WM_USER + 2) - #endif + #ifdef SIGINT + #undef SIGINT + #define SIGINT (WM_USER + 2) + #endif - #ifndef SIGUSR1 - #define SIGUSR1 (WM_USER + 10) - #endif + #ifndef SIGUSR1 + #define SIGUSR1 (WM_USER + 10) + #endif - #ifndef SIGUSR2 - #define SIGUSR2 (WM_USER + 12) - #endif + #ifndef SIGUSR2 + #define SIGUSR2 (WM_USER + 12) + #endif #elif POSIX #include #else - #error "Undefine platform" + #error "Undefined platform" #endif #include @@ -41,7 +43,7 @@ namespace System #elif POSIX typedef int native_socket_type; #else - #error "Undefine platform" + #error "Undefined platform" #endif #ifdef WIN32 @@ -49,7 +51,7 @@ namespace System #elif POSIX typedef ::pid_t native_processid_type; #else - #error "Undefine platform" + #error "Undefined platform" #endif native_processid_type getProcessId() noexcept; @@ -69,4 +71,4 @@ namespace System bool getFileSizeAndTimeGmt(const std::string &filePath, size_t *fileSize, time_t *fileTime); void filterSharedMemoryName(std::string &memName); -}; +} diff --git a/src/transfer/AppRequest.h b/src/transfer/AppRequest.h index 5676b34..52d894e 100644 --- a/src/transfer/AppRequest.h +++ b/src/transfer/AppRequest.h @@ -7,17 +7,15 @@ namespace Transfer { - struct request_data - { + struct request_data { std::unordered_multimap incoming_headers; std::unordered_multimap incoming_data; std::unordered_multimap incoming_files; }; - struct app_request - { + struct app_request { const System::native_socket_type socket; const ::gnutls_session_t tls_session; const void * const request_data; }; -}; +} diff --git a/src/transfer/AppResponse.h b/src/transfer/AppResponse.h index 80937dd..e059e55 100644 --- a/src/transfer/AppResponse.h +++ b/src/transfer/AppResponse.h @@ -5,9 +5,8 @@ namespace Transfer { - struct app_response - { + struct app_response { void *response_data; size_t data_size; }; -}; +} diff --git a/src/transfer/FileIncoming.cpp b/src/transfer/FileIncoming.cpp index 58188fc..07fb877 100644 --- a/src/transfer/FileIncoming.cpp +++ b/src/transfer/FileIncoming.cpp @@ -6,67 +6,71 @@ namespace Transfer { - FileIncoming::FileIncoming(std::string &&fileTmpName, std::string &&fileName, std::string &&fileType, const size_t fileSize) noexcept - : file_tmp_name(std::move(fileTmpName) ), file_name(std::move(fileName) ), - file_type(std::move(fileType) ), file_size(fileSize) + FileIncoming::FileIncoming( + std::string &&fileTmpName, + std::string &&fileName, + std::string &&fileType, + const size_t fileSize + ) noexcept + : file_tmp_name(std::move(fileTmpName) ), + file_name(std::move(fileName) ), + file_type(std::move(fileType) ), + file_size(fileSize) { } FileIncoming::FileIncoming(const FileIncoming &obj) - : file_tmp_name(obj.file_tmp_name), file_name(obj.file_name), - file_type(obj.file_type), file_size(obj.file_size) + : file_tmp_name(obj.file_tmp_name), + file_name(obj.file_name), + file_type(obj.file_type), + file_size(obj.file_size) { } FileIncoming::FileIncoming(FileIncoming &&obj) noexcept - : file_tmp_name(std::move(obj.file_tmp_name) ), file_name(std::move(obj.file_name) ), - file_type(std::move(obj.file_type) ), file_size(obj.file_size) + : file_tmp_name(std::move(obj.file_tmp_name) ), + file_name(std::move(obj.file_name) ), + file_type(std::move(obj.file_type) ), + file_size(obj.file_size) { obj.file_size = 0; } - const std::string &FileIncoming::getTmpName() const noexcept - { + const std::string &FileIncoming::getTmpName() const noexcept { return this->file_tmp_name; } - const std::string &FileIncoming::getName() const noexcept - { + const std::string &FileIncoming::getName() const noexcept { return this->file_name; } - const std::string &FileIncoming::getType() const noexcept - { + const std::string &FileIncoming::getType() const noexcept { return this->file_type; } - size_t FileIncoming::getSize() const noexcept - { + size_t FileIncoming::getSize() const noexcept { return this->file_size; } - bool FileIncoming::isExists() const noexcept - { + bool FileIncoming::isExists() const noexcept { std::ifstream file(this->file_tmp_name, std::ifstream::binary); - const bool is_exists = file.good(); - file.close(); - return is_exists; } -}; +} namespace Utils { - void packFilesIncoming(std::vector &buf, const std::unordered_multimap &map) - { + void packFilesIncoming( + std::vector &buf, + const std::unordered_multimap &map + ) { packNumber(buf, map.size() ); - for (auto it = map.cbegin(); map.cend() != it; ++it) - { + for (auto it = map.cbegin(); map.cend() != it; ++it) { packString(buf, it->first); const Transfer::FileIncoming &file = it->second; @@ -78,13 +82,14 @@ namespace Utils } } - const uint8_t *unpackFilesIncoming(std::unordered_multimap &map, const uint8_t *src) - { + const uint8_t *unpackFilesIncoming( + std::unordered_multimap &map, + const uint8_t *src + ) { size_t count; src = unpackNumber(&count, src); - for (size_t i = 0; i < count; ++i) - { + for (size_t i = 0; i < count; ++i) { std::string key; src = unpackString(key, src); @@ -100,9 +105,17 @@ namespace Utils size_t file_size; src = unpackNumber(&file_size, src); - map.emplace(std::move(key), Transfer::FileIncoming(std::move(file_tmp_name), std::move(file_name), std::move(file_type), file_size) ); + map.emplace( + std::move(key), + Transfer::FileIncoming( + std::move(file_tmp_name), + std::move(file_name), + std::move(file_type), + file_size + ) + ); } return src; } -}; +} diff --git a/src/transfer/FileIncoming.h b/src/transfer/FileIncoming.h index 0d853eb..448c8c8 100644 --- a/src/transfer/FileIncoming.h +++ b/src/transfer/FileIncoming.h @@ -14,16 +14,23 @@ namespace Transfer std::string file_type; size_t file_size; - private: - FileIncoming() = delete; - public: - FileIncoming(std::string &&fileTmpName, std::string &&fileName, std::string &&fileType, const size_t fileSize) noexcept; + FileIncoming() = default; + + FileIncoming( + std::string &&fileTmpName, + std::string &&fileName, + std::string &&fileType, + const size_t fileSize + ) noexcept; + FileIncoming(const FileIncoming &obj); FileIncoming(FileIncoming &&obj) noexcept; ~FileIncoming() noexcept = default; + FileIncoming &operator =(const FileIncoming &) = default; + const std::string &getTmpName() const noexcept; const std::string &getName() const noexcept; const std::string &getType() const noexcept; @@ -31,10 +38,17 @@ namespace Transfer bool isExists() const noexcept; }; -}; +} namespace Utils { - void packFilesIncoming(std::vector &buf, const std::unordered_multimap &map); - const uint8_t *unpackFilesIncoming(std::unordered_multimap &map, const uint8_t *src); -}; + void packFilesIncoming( + std::vector &buf, + const std::unordered_multimap &map + ); + + const uint8_t *unpackFilesIncoming( + std::unordered_multimap &map, + const uint8_t *src + ); +} diff --git a/src/transfer/HttpStatusCode.h b/src/transfer/HttpStatusCode.h index 169326a..abb0c85 100644 --- a/src/transfer/HttpStatusCode.h +++ b/src/transfer/HttpStatusCode.h @@ -2,8 +2,7 @@ namespace Http { - enum class StatusCode - { + enum class StatusCode { EMPTY = 0, CONTINUE = 100, @@ -49,4 +48,4 @@ namespace Http GATEWAY_TIMEOUT = 504, HTTP_VERSION_NOT_SUPPORTED = 505, }; -}; +} diff --git a/src/transfer/ProtocolVariant.h b/src/transfer/ProtocolVariant.h index 11954bf..093a02a 100644 --- a/src/transfer/ProtocolVariant.h +++ b/src/transfer/ProtocolVariant.h @@ -2,10 +2,9 @@ namespace Transfer { - enum class ProtocolVariant - { + enum class ProtocolVariant { UNKNOWN = 0, HTTP_1, HTTP_2 }; -}; +} diff --git a/src/transfer/http2/HPack.cpp b/src/transfer/http2/HPack.cpp index 60889d2..b8d0128 100644 --- a/src/transfer/http2/HPack.cpp +++ b/src/transfer/http2/HPack.cpp @@ -11,8 +11,7 @@ namespace HPack { - struct HuffmanSymbol - { + struct HuffmanSymbol { int nbits; uint32_t code; }; @@ -277,8 +276,7 @@ namespace HPack {30, 0x3fffffff}, }; - struct HuffmanDecodeNode - { + struct HuffmanDecodeNode { uint8_t state; uint8_t flags; uint8_t symbol; @@ -5214,33 +5212,34 @@ namespace HPack {"www-authenticate", ""}, }; - static constexpr size_t getStaticTableSize() noexcept - { + static constexpr size_t getStaticTableSize() noexcept { return sizeof(staticTable) / sizeof(*staticTable); } - static size_t huffmanEncodeLength(const void *dest, const size_t length) noexcept - { + static size_t huffmanEncodeLength( + const void *dest, + const size_t length + ) noexcept { const uint8_t *data = reinterpret_cast(dest); size_t n = 0; - for (size_t i = 0; i < length; ++i) - { - n += huffmanSymbolTable[data[i] ].nbits; + for (size_t i = 0; i < length; ++i) { + n += size_t(huffmanSymbolTable[data[i] ].nbits); } return (n + 7) / 8; } - static uint8_t huffmanEncodeSymbol(std::vector &dest, uint8_t rembits, const HuffmanSymbol &sym) - { - uint8_t nbits = sym.nbits; + static uint8_t huffmanEncodeSymbol( + std::vector &dest, + uint8_t rembits, + const HuffmanSymbol &sym + ) { + uint8_t nbits = uint8_t(sym.nbits); - for (;;) - { - if (rembits > nbits) - { + for (;;) { + if (rembits > nbits) { dest.back() |= uint8_t(sym.code << (rembits - nbits) ); rembits -= nbits; break; @@ -5251,8 +5250,7 @@ namespace HPack nbits -= rembits; rembits = 8; - if (0 == nbits) - { + if (0 == nbits) { break; } @@ -5262,41 +5260,42 @@ namespace HPack return rembits; } - static void encode(std::vector &dest, const void* src, const size_t srcSize) - { + static void encode( + std::vector &dest, + const void* src, + const size_t srcSize + ) { const uint8_t *data = reinterpret_cast(src); uint8_t rembits = 8; - for (size_t i = 0; i < srcSize; ++i) - { + for (size_t i = 0; i < srcSize; ++i) { const HuffmanSymbol &sym = huffmanSymbolTable[data[i] ]; - if (8 == rembits) - { + if (8 == rembits) { dest.emplace_back(0); } rembits = huffmanEncodeSymbol(dest, rembits, sym); } - if (rembits < 8) - { + if (rembits < 8) { const HuffmanSymbol &sym = huffmanSymbolTable[256]; - dest.back() |= uint8_t(sym.code >> (sym.nbits - rembits) ); } } - enum HuffmanDecode - { + enum HuffmanDecode { ACCEPT = 0x1, SYMBOL = 0x2, FAIL = 0x4 }; - static bool decode(std::vector &dest, const void* src, const size_t srcSize) - { + static bool decode( + std::vector &dest, + const void* src, + const size_t srcSize + ) { const uint8_t *data = reinterpret_cast(src); const uint8_t *end = data + srcSize; @@ -5312,13 +5311,11 @@ namespace HPack { const HuffmanDecodeNode &node = huffmanDecodeTable[state][x]; - if (node.flags & HuffmanDecode::FAIL) - { + if (node.flags & HuffmanDecode::FAIL) { return false; } - if (node.flags & HuffmanDecode::SYMBOL) - { + if (node.flags & HuffmanDecode::SYMBOL) { dest.emplace_back(node.symbol); } @@ -5332,12 +5329,14 @@ namespace HPack return accept; } - static void packInteger(std::vector &dest, uint64_t num, const uint8_t prefix) - { - uint64_t k = (1 << prefix) - 1; + static void packInteger( + std::vector &dest, + uint64_t num, + const uint8_t prefix + ) { + const uint64_t k = (1 << prefix) - 1; - if (num < k) - { + if (num < k) { dest.emplace_back(num); return; } @@ -5346,10 +5345,8 @@ namespace HPack num -= k; - for (;;) - { - if (num < 128) - { + for (;;) { + if (num < 128) { dest.emplace_back(num); break; } @@ -5358,24 +5355,25 @@ namespace HPack num >>= 7; - if (0 == num) - { + if (0 == num) { break; } } } - static void packIndex(std::vector &dest, const size_t index) - { + static void packIndex( + std::vector &dest, + const size_t index + ) { const size_t head = dest.size(); - packInteger(dest, index, 7); - dest[head] |= 0x80; } - static std::tuple findHeaderInTable(const std::pair &header, const Http2::DynamicTable &dynamicTable) - { + static std::tuple findHeaderInTable( + const std::pair &header, + const Http2::DynamicTable &dynamicTable + ) { std::tuple result { 0, false }; @@ -5383,39 +5381,30 @@ namespace HPack size_t &index = std::get(result); bool &is_full_match = std::get(result); - for (size_t i = 0; i < getStaticTableSize(); ++i) - { + for (size_t i = 0; i < getStaticTableSize(); ++i) { auto const &pair = staticTable[i]; - if (pair.first == header.first) - { + if (pair.first == header.first) { index = i + 1; - if (pair.second == header.second) - { + if (pair.second == header.second) { is_full_match = true; - return result; } } - else if (0 != index) - { + else if (0 != index) { break; } } - for (size_t i = 0; i < dynamicTable.size(); ++i) - { + for (size_t i = 0; i < dynamicTable.size(); ++i) { auto const &pair = dynamicTable[i]; - if (pair.first == header.first) - { + if (pair.first == header.first) { index = i + getStaticTableSize() + 1; - if (pair.second == header.second) - { + if (pair.second == header.second) { is_full_match = true; - break; } } @@ -5426,13 +5415,11 @@ namespace HPack static uint8_t packFirstByte(const bool indexing) noexcept { - if (indexing) - { + if (indexing) { return 0x40; } - /* if (never_indexing) - { + /* if (never_indexing) { return 0x10; }*/ @@ -5443,31 +5430,40 @@ namespace HPack { const size_t huffman_length = huffmanEncodeLength(str.data(), str.length() ); - if (huffman_length < str.length() ) - { + if (huffman_length < str.length() ) { const size_t head = dest.size(); packInteger(dest, huffman_length, 7); encode(dest, str.data(), str.length() ); dest[head] |= 0x80; - } - else - { + } else { packInteger(dest, str.length(), 7); - std::copy(str.cbegin(), str.cend(), std::back_inserter(dest) ); + + dest.insert( + dest.end(), + str.cbegin(), + str.cend() + ); } } - static void packFullHeader(std::vector &dest, const std::pair &header, const bool indexing) - { + static void packFullHeader( + std::vector &dest, + const std::pair &header, + const bool indexing + ) { dest.emplace_back(packFirstByte(indexing) ); packString(dest, header.first); packString(dest, header.second); } - static void packHeaderValue(std::vector &dest, const size_t keyIndex, const std::pair &header, const bool indexing) - { + static void packHeaderValue( + std::vector &dest, + const size_t keyIndex, + const std::pair &header, + const bool indexing + ) { const size_t head = dest.size(); const uint8_t prefix = indexing ? 6 : 4; @@ -5483,41 +5479,37 @@ namespace HPack { /* const std::string &key = header.first; - if ("content-length" == key || "set-cookie" == key) - { + if ("content-length" == key || "set-cookie" == key) { return true; }*/ return false; } - static void packHeader(std::vector &dest, const std::pair &header, Http2::DynamicTable &dynamicTable) - { + static void packHeader( + std::vector &dest, + const std::pair &header, + Http2::DynamicTable &dynamicTable + ) { size_t index; bool is_full_match; std::tie(index, is_full_match) = findHeaderInTable(header, dynamicTable); - if (is_full_match) - { + if (is_full_match) { packIndex(dest, index); - return; } const bool indexing = shouldIndexing(header); - if (indexing) - { + if (indexing) { dynamicTable.addHeader(header); } - if (0 == index) - { + if (0 == index) { packFullHeader(dest, header, indexing); - } - else - { + } else { packHeaderValue(dest, index, header, indexing); } } @@ -5531,24 +5523,24 @@ namespace HPack dest[head] |= 0x20; } */ - void pack(std::vector &dest, const std::vector > &headers, Http2::DynamicTable &dynamicTable) - { - for (auto const &header : headers) - { + void pack( + std::vector &dest, + const std::vector > &headers, + Http2::DynamicTable &dynamicTable + ) { + for (auto const &header : headers) { packHeader(dest, header, dynamicTable); } } - enum class HuffmanDecodeOpcode - { + enum class HuffmanDecodeOpcode { NONE, INDEXED, NOT_INDEXED, INDEXED_KEY, }; - enum class HuffmanDecodeState - { + enum class HuffmanDecodeState { OPCODE, READ_TABLE_SIZE, READ_INDEX, @@ -5562,65 +5554,85 @@ namespace HPack READ_VALUE, }; - static size_t getMaxTableIndex(const Http2::IncStream &stream) noexcept - { + static size_t getMaxTableIndex(const Http2::IncStream &stream) noexcept { return getStaticTableSize() + stream.conn.decoding_dynamic_table.size(); } - static const std::pair *getHeaderFromTable(const size_t index, const Http2::IncStream &stream) noexcept - { - if (getStaticTableSize() >= index) - { + static const std::pair *getHeaderFromTable( + const size_t index, + const Http2::IncStream &stream + ) noexcept { + if (getStaticTableSize() >= index) { return &staticTable[index - 1]; } - else if (stream.conn.decoding_dynamic_table.size() + getStaticTableSize() >= index) - { + else if (stream.conn.decoding_dynamic_table.size() + getStaticTableSize() >= index) { return &stream.conn.decoding_dynamic_table[index - getStaticTableSize() - 1]; } return nullptr; } - static const std::pair *unpackIndexed(const size_t index, const Http2::IncStream &stream) noexcept - { + static const std::pair *unpackIndexed( + const size_t index, + const Http2::IncStream &stream + ) noexcept { return getHeaderFromTable(index, stream); } - static bool checkHuffmanEncoded(const uint8_t c) noexcept - { + static bool checkHuffmanEncoded(const uint8_t c) noexcept { return c & (1 << 7); } - static std::tuple unpackHuffman(std::vector &dest, const uint8_t *data, const size_t dataSize, const uint64_t left) - { + static std::tuple unpackHuffman( + std::vector &dest, + const uint8_t *data, + const size_t dataSize, + const uint64_t left + ) { std::tuple result { left, false }; - if (dataSize < left) - { + if (dataSize < left) { std::get(result) = dataSize; } - std::get(result) = decode(dest, data, std::get(result) ); + std::get(result) = decode( + dest, + data, + std::get(result) + ); return result; } - static uint64_t unpackString(std::vector &dest, const uint8_t *data, const size_t dataSize, uint64_t left) - { - if (dataSize < left) - { + static uint64_t unpackString( + std::vector &dest, + const uint8_t *data, + const size_t dataSize, + uint64_t left + ) { + if (dataSize < left) { left = dataSize; } - std::copy(data, data + left, std::back_inserter(dest) ); + dest.insert( + dest.end(), + data, + data + left + ); return left; } - static std::tuple unpackInteger(const uint8_t *data, const size_t dataSize, const uint64_t initial, const uint8_t initialShift, const uint8_t prefix) - { + static std::tuple + unpackInteger( + const uint8_t *data, + const size_t dataSize, + const uint64_t initial, + const uint8_t initialShift, + const uint8_t prefix + ) { std::tuple result { initial, 0, initialShift, true }; @@ -5629,7 +5641,7 @@ namespace HPack uint64_t &nread = std::get<1>(result); uint8_t &shift = std::get(result); - uint8_t k = (1 << prefix) - 1; + const uint8_t k = uint8_t(1 << prefix) - 1; if (0 == num) { @@ -5637,17 +5649,14 @@ namespace HPack ++nread; - if (k != (c & k) ) - { + if (k != (c & k) ) { num = c & k; - return result; } num = k; - if (nread == dataSize) - { + if (nread == dataSize) { return result; } } @@ -5658,34 +5667,28 @@ namespace HPack uint32_t add = c & 0x7f; - if (add > (std::numeric_limits::max() >> shift) ) - { + if (add > (std::numeric_limits::max() >> shift) ) { std::get(result) = false; - return result; } add <<= shift; - if (std::numeric_limits::max() - add < num) - { + if (std::numeric_limits::max() - add < num) { std::get(result) = false; - return result; } num += add; - if (0 == (c & (1 << 7) ) ) - { + if (0 == (c & (1 << 7) ) ) { break; } shift += 7; } - if (nread != dataSize) - { + if (nread != dataSize) { ++nread; } @@ -5714,14 +5717,13 @@ namespace HPack std::pair unpackFullHeader(Http2::IncStream &stream) { std::pair header { - std::string(this->buf.cbegin(), this->buf.cbegin() + this->key_length), - std::string(this->buf.cbegin() + this->key_length, this->buf.cend() ) + std::string(this->buf.cbegin(), this->buf.cbegin() + long(this->key_length)), + std::string(this->buf.cbegin() + long(this->key_length), this->buf.cend() ) }; this->buf.clear(); - if (this->index_required) - { + if (this->index_required) { stream.conn.decoding_dynamic_table.addHeader(header); } @@ -5732,8 +5734,7 @@ namespace HPack { auto entry = getHeaderFromTable(this->key_index, stream); - if (nullptr == entry) - { + if (nullptr == entry) { return std::pair(); } @@ -5745,8 +5746,7 @@ namespace HPack this->key_index = 0; this->buf.clear(); - if (this->index_required) - { + if (this->index_required) { stream.conn.decoding_dynamic_table.addHeader(header); } @@ -5754,8 +5754,11 @@ namespace HPack } }; - bool unpack(const void *src, const size_t srcSize, Http2::IncStream &stream) - { + bool unpack( + const void *src, + const size_t srcSize, + Http2::IncStream &stream + ) { const uint8_t *data = reinterpret_cast(src); size_t cur = 0; @@ -5770,27 +5773,20 @@ namespace HPack { const uint8_t c = data[cur]; - if (0x20 == (c & 0xe0) ) - { + if (0x20 == (c & 0xe0) ) { dec.opcode = HuffmanDecodeOpcode::INDEXED; dec.state = HuffmanDecodeState::READ_TABLE_SIZE; } - else if (c & 0x80) - { + else if (c & 0x80) { dec.opcode = HuffmanDecodeOpcode::INDEXED; dec.state = HuffmanDecodeState::READ_INDEX; - } - else - { - if (0 == c || 0x40 == c || 0x10 == c) - { + } else { + if (0 == c || 0x40 == c || 0x10 == c) { dec.opcode = HuffmanDecodeOpcode::NOT_INDEXED; dec.state = HuffmanDecodeState::CHECK_KEY_LENGTH; ++cur; - } - else - { + } else { dec.opcode = HuffmanDecodeOpcode::INDEXED_KEY; dec.state = HuffmanDecodeState::READ_INDEX; } @@ -5809,22 +5805,28 @@ namespace HPack uint64_t nread; bool success; - std::tie(dec.left, nread, dec.shift, success) = unpackInteger(data + cur, srcSize - cur, dec.left, dec.shift, 5); + std::tie(dec.left, nread, dec.shift, success) = unpackInteger( + data + cur, + srcSize - cur, + dec.left, + dec.shift, + 5 + ); cur += nread; - if (false == success) - { + if (false == success) { return false; } - if (dec.left > stream.conn.client_settings.header_table_size) - { + if (dec.left > stream.conn.client_settings.header_table_size) { // TODO: invalid max table size error code return false; } - stream.conn.decoding_dynamic_table.changeHeaderTableSize(dec.left); + stream.conn.decoding_dynamic_table.changeHeaderTableSize( + static_cast(dec.left) + ); dec.state = HuffmanDecodeState::OPCODE; @@ -5835,41 +5837,37 @@ namespace HPack { uint8_t prefixlen; - if (HuffmanDecodeOpcode::INDEXED == dec.opcode) - { + if (HuffmanDecodeOpcode::INDEXED == dec.opcode) { prefixlen = 7; } - else if (dec.index_required) - { + else if (dec.index_required) { prefixlen = 6; - } - else - { + } else { prefixlen = 4; } uint64_t nread; bool success; - std::tie(dec.left, nread, dec.shift, success) = unpackInteger(data + cur, srcSize - cur, dec.left, dec.shift, prefixlen); + std::tie(dec.left, nread, dec.shift, success) = unpackInteger( + data + cur, + srcSize - cur, + dec.left, + dec.shift, + prefixlen + ); cur += nread; - if (false == success || 0 == dec.left || dec.left > getMaxTableIndex(stream) ) - { + if (false == success || 0 == dec.left || dec.left > getMaxTableIndex(stream) ) { return false; } - if (HuffmanDecodeOpcode::INDEXED == dec.opcode) - { + if (HuffmanDecodeOpcode::INDEXED == dec.opcode) { stream.incoming_headers.emplace(*unpackIndexed(dec.left, stream) ); - dec.state = HuffmanDecodeState::OPCODE; - } - else - { + } else { dec.key_index = dec.left; - dec.state = HuffmanDecodeState::CHECK_VALUE_LENGTH; } @@ -5889,18 +5887,23 @@ namespace HPack uint64_t nread; bool success; - std::tie(dec.left, nread, dec.shift, success) = unpackInteger(data + cur, srcSize - cur, dec.left, dec.shift, 7); + std::tie(dec.left, nread, dec.shift, success) = unpackInteger( + data + cur, + srcSize - cur, + dec.left, + dec.shift, + 7 + ); cur += nread; - if (false == success) - { + if (false == success) { return false; } - dec.state = dec.huffman_encoded ? - HuffmanDecodeState::READ_KEY_HUFFMAN : - HuffmanDecodeState::READ_KEY; + dec.state = dec.huffman_encoded + ? HuffmanDecodeState::READ_KEY_HUFFMAN + : HuffmanDecodeState::READ_KEY; break; } @@ -5910,13 +5913,17 @@ namespace HPack uint64_t nread; bool success; - std::tie(nread, success) = unpackHuffman(dec.buf, data + cur, srcSize - cur, dec.left); + std::tie(nread, success) = unpackHuffman( + dec.buf, + data + cur, + srcSize - cur, + dec.left + ); cur += nread; dec.left -= nread; - if (false == success || dec.left > 0) - { + if (false == success || dec.left > 0) { return false; } @@ -5929,13 +5936,17 @@ namespace HPack case HuffmanDecodeState::READ_KEY: { - const uint64_t nread = unpackString(dec.buf, data + cur, srcSize - cur, dec.left); + const uint64_t nread = unpackString( + dec.buf, + data + cur, + srcSize - cur, + dec.left + ); cur += nread; dec.left -= nread; - if (dec.left > 0) - { + if (dec.left > 0) { return false; } @@ -5959,29 +5970,34 @@ namespace HPack uint64_t nread; bool success; - std::tie(dec.left, nread, dec.shift, success) = unpackInteger(data + cur, srcSize - cur, dec.left, dec.shift, 7); + std::tie(dec.left, nread, dec.shift, success) = unpackInteger( + data + cur, + srcSize - cur, + dec.left, + dec.shift, + 7 + ); cur += nread; - if (false == success) - { + if (false == success) { return false; } if (0 == dec.left) { - HuffmanDecodeOpcode::NOT_INDEXED == dec.opcode ? - stream.incoming_headers.emplace(dec.unpackFullHeader(stream) ) : - stream.incoming_headers.emplace(dec.unpackHeaderValue(stream) ); + HuffmanDecodeOpcode::NOT_INDEXED == dec.opcode + ? stream.incoming_headers.emplace(dec.unpackFullHeader(stream) ) + : stream.incoming_headers.emplace(dec.unpackHeaderValue(stream) ); dec.state = HuffmanDecodeState::OPCODE; break; } - dec.state = dec.huffman_encoded ? - HuffmanDecodeState::READ_VALUE_HUFFMAN : - HuffmanDecodeState::READ_VALUE; + dec.state = dec.huffman_encoded + ? HuffmanDecodeState::READ_VALUE_HUFFMAN + : HuffmanDecodeState::READ_VALUE; break; } @@ -5991,19 +6007,23 @@ namespace HPack uint64_t nread; bool success; - std::tie(nread, success) = unpackHuffman(dec.buf, data + cur, srcSize - cur, dec.left); + std::tie(nread, success) = unpackHuffman( + dec.buf, + data + cur, + srcSize - cur, + dec.left + ); cur += nread; dec.left -= nread; - if (false == success || dec.left > 0) - { + if (false == success || dec.left > 0) { return false; } - HuffmanDecodeOpcode::NOT_INDEXED == dec.opcode ? - stream.incoming_headers.emplace(dec.unpackFullHeader(stream) ) : - stream.incoming_headers.emplace(dec.unpackHeaderValue(stream) ); + HuffmanDecodeOpcode::NOT_INDEXED == dec.opcode + ? stream.incoming_headers.emplace(dec.unpackFullHeader(stream) ) + : stream.incoming_headers.emplace(dec.unpackHeaderValue(stream) ); dec.state = HuffmanDecodeState::OPCODE; @@ -6012,19 +6032,23 @@ namespace HPack case HuffmanDecodeState::READ_VALUE: { - const uint64_t nread = unpackString(dec.buf, data + cur, srcSize - cur, dec.left); + const uint64_t nread = unpackString( + dec.buf, + data + cur, + srcSize - cur, + dec.left + ); cur += nread; dec.left -= nread; - if (dec.left > 0) - { + if (dec.left > 0) { return false; } - HuffmanDecodeOpcode::NOT_INDEXED == dec.opcode ? - stream.incoming_headers.emplace(dec.unpackFullHeader(stream) ) : - stream.incoming_headers.emplace(dec.unpackHeaderValue(stream) ); + HuffmanDecodeOpcode::NOT_INDEXED == dec.opcode + ? stream.incoming_headers.emplace(dec.unpackFullHeader(stream) ) + : stream.incoming_headers.emplace(dec.unpackHeaderValue(stream) ); dec.state = HuffmanDecodeState::OPCODE; @@ -6035,4 +6059,4 @@ namespace HPack return true; } -}; +} diff --git a/src/transfer/http2/HPack.h b/src/transfer/http2/HPack.h index d71375c..c030a7f 100644 --- a/src/transfer/http2/HPack.h +++ b/src/transfer/http2/HPack.h @@ -8,8 +8,16 @@ namespace HPack { - void pack(std::vector &dest, const std::vector > &headers, Http2::DynamicTable &dynamicTable); + void pack( + std::vector &dest, + const std::vector > &headers, + Http2::DynamicTable &dynamicTable + ); // TODO: replace IncStream to DynamicTable if possible - bool unpack(const void *src, const size_t srcSize, Http2::IncStream &stream); -}; + bool unpack( + const void *src, + const size_t srcSize, + Http2::IncStream &stream + ); +} diff --git a/src/transfer/http2/Http2.cpp b/src/transfer/http2/Http2.cpp index 93280ba..71c60c9 100644 --- a/src/transfer/http2/Http2.cpp +++ b/src/transfer/http2/Http2.cpp @@ -4,23 +4,32 @@ namespace Http2 { - bool operator &(const FrameFlag left, const FrameFlag right) noexcept - { + bool operator &( + const FrameFlag left, + const FrameFlag right + ) noexcept { return static_cast(left) & static_cast(right); } - FrameFlag operator |(const FrameFlag left, const FrameFlag right) noexcept - { - return static_cast(static_cast(left) | static_cast(right) ); + FrameFlag operator |( + const FrameFlag left, + const FrameFlag right + ) noexcept { + return static_cast( + static_cast(left) | static_cast(right) + ); } - FrameFlag operator |=(FrameFlag &left, const FrameFlag right) noexcept - { - return static_cast(*reinterpret_cast(&left) |= static_cast(right) ); + FrameFlag operator |=( + FrameFlag &left, + const FrameFlag right + ) noexcept { + return static_cast( + *reinterpret_cast(&left) |= static_cast(right) + ); } - ConnectionSettings ConnectionSettings::defaultSettings() noexcept - { + ConnectionSettings ConnectionSettings::defaultSettings() noexcept { return ConnectionSettings { 4096, 1, @@ -32,21 +41,28 @@ namespace Http2 } DynamicTable::DynamicTable() noexcept - : header_table_size(0), max_header_list_size(0), cur_header_list_size(0) + : header_table_size(0), + max_header_list_size(0), + cur_header_list_size(0) { } - size_t DynamicTable::size() const noexcept - { + size_t DynamicTable::size() const noexcept { return this->list.size(); } - DynamicTable::DynamicTable(const uint32_t headerTableSize, const uint32_t maxHeaderListSize, std::deque > &&list) noexcept - : list(std::move(list) ), header_table_size(headerTableSize), max_header_list_size(maxHeaderListSize), cur_header_list_size(0) + DynamicTable::DynamicTable( + const uint32_t headerTableSize, + const uint32_t maxHeaderListSize, + std::deque > &&list + ) noexcept + : list(std::move(list) ), + header_table_size(headerTableSize), + max_header_list_size(maxHeaderListSize), + cur_header_list_size(0) { - for (auto const &pair : list) - { + for (auto const &pair : list) { this->cur_header_list_size += pair.first.length() + pair.second.length(); } } @@ -57,8 +73,12 @@ namespace Http2 this->list.emplace_front(header); - while (this->list.size() > this->header_table_size || (0 != this->max_header_list_size && this->cur_header_list_size > this->max_header_list_size) ) - { + while ( + this->list.size() > this->header_table_size || ( + this->max_header_list_size != 0 && + this->cur_header_list_size > this->max_header_list_size + ) + ) { auto const &pair = this->list.back(); this->cur_header_list_size -= pair.first.length() + pair.second.length(); @@ -73,8 +93,12 @@ namespace Http2 this->list.emplace_front(std::move(header) ); - while (this->list.size() > this->header_table_size || (0 != this->max_header_list_size && this->cur_header_list_size > this->max_header_list_size) ) - { + while ( + this->list.size() > this->header_table_size || ( + this->max_header_list_size != 0 && + this->cur_header_list_size > this->max_header_list_size + ) + ) { auto const &pair = this->list.back(); this->cur_header_list_size -= pair.first.length() + pair.second.length(); @@ -87,8 +111,7 @@ namespace Http2 { this->header_table_size = headerTableSize; - while (this->list.size() > this->header_table_size) - { + while (this->list.size() > this->header_table_size) { auto const &pair = this->list.back(); this->cur_header_list_size -= pair.first.length() + pair.second.length(); @@ -101,8 +124,10 @@ namespace Http2 { this->max_header_list_size = maxHeaderListSize; - while (0 != this->max_header_list_size && this->cur_header_list_size > this->max_header_list_size) - { + while ( + this->max_header_list_size != 0 && + this->cur_header_list_size > this->max_header_list_size + ) { auto const &pair = this->list.back(); this->cur_header_list_size -= pair.first.length() + pair.second.length(); @@ -111,31 +136,38 @@ namespace Http2 } } - const std::pair &DynamicTable::operator[](const size_t index) const noexcept - { + const std::pair & + DynamicTable::operator[](const size_t index) const noexcept { return this->list[index]; } - std::pair &DynamicTable::operator[](const size_t index) noexcept - { + std::pair & + DynamicTable::operator[](const size_t index) noexcept { return this->list[index]; } - const std::deque > &DynamicTable::getList() const noexcept - { + const std::deque > &DynamicTable::getList() const noexcept { return this->list; } IncStream::IncStream(const uint32_t streamId, ConnectionData &conn) noexcept - : conn(conn), window_size_inc(conn.server_settings.initial_window_size), - window_size_out(conn.client_settings.initial_window_size), stream_id(streamId), - state(StreamState::IDLE), priority(0), reserved(nullptr) + : conn(conn), + window_size_inc(int32_t(conn.server_settings.initial_window_size)), + window_size_out(int32_t(conn.client_settings.initial_window_size)), + stream_id(streamId), + state(StreamState::IDLE), + priority(0), + reserved(nullptr) { } - uint8_t *IncStream::setHttp2FrameHeader(uint8_t *addr, const uint32_t frameSize, const Http2::FrameType frameType, const Http2::FrameFlag frameFlags) noexcept - { + uint8_t *IncStream::setHttp2FrameHeader( + uint8_t *addr, + const uint32_t frameSize, + const Http2::FrameType frameType, + const Http2::FrameFlag frameFlags + ) noexcept { Utils::hton24(addr, frameSize); *(addr + 3) = static_cast(frameType); *(addr + 4) = static_cast(frameFlags); @@ -144,18 +176,15 @@ namespace Http2 return (addr + Http2::FRAME_HEADER_SIZE); } - void IncStream::lock() - { + void IncStream::lock() { this->conn.sync.mtx.lock(); } - void IncStream::unlock() noexcept - { + void IncStream::unlock() noexcept { this->conn.sync.mtx.unlock(); } - void IncStream::close() noexcept - { + void IncStream::close() noexcept { this->incoming_headers.clear(); this->incoming_data.clear(); this->incoming_files.clear(); @@ -167,21 +196,37 @@ namespace Http2 // this->state = StreamState::CLOSED; } - OutStream::OutStream(const uint32_t streamId, const ConnectionSettings &settings, DynamicTable &&dynamic_table, std::mutex *mtx) noexcept - : stream_id(streamId), settings(settings), window_size_out(settings.initial_window_size), dynamic_table(std::move(dynamic_table) ), mtx(mtx) + OutStream::OutStream( + const uint32_t streamId, + const ConnectionSettings &settings, + DynamicTable &&dynamic_table, + std::mutex *mtx + ) noexcept + : stream_id(streamId), + window_size_out(int32_t(settings.initial_window_size)), + settings(settings), + dynamic_table(std::move(dynamic_table) ), + mtx(mtx) { } OutStream::OutStream(const IncStream &stream) - : stream_id(stream.stream_id), settings(stream.conn.client_settings), - window_size_out(stream.window_size_out), dynamic_table(stream.conn.encoding_dynamic_table), mtx(&stream.conn.sync.mtx) + : stream_id(stream.stream_id), + window_size_out(stream.window_size_out), + settings(stream.conn.client_settings), + dynamic_table(stream.conn.encoding_dynamic_table), + mtx(&stream.conn.sync.mtx) { } - uint8_t *OutStream::setHttp2FrameHeader(uint8_t *addr, const uint32_t frameSize, const Http2::FrameType frameType, const Http2::FrameFlag frameFlags) noexcept - { + uint8_t *OutStream::setHttp2FrameHeader( + uint8_t *addr, + const uint32_t frameSize, + const Http2::FrameType frameType, + const Http2::FrameFlag frameFlags + ) noexcept { Utils::hton24(addr, frameSize); *(addr + 3) = static_cast(frameType); *(addr + 4) = static_cast(frameFlags); @@ -190,13 +235,11 @@ namespace Http2 return (addr + Http2::FRAME_HEADER_SIZE); } - void OutStream::lock() - { + void OutStream::lock() { this->mtx->lock(); } - void OutStream::unlock() noexcept - { + void OutStream::unlock() noexcept { this->mtx->unlock(); } -}; +} diff --git a/src/transfer/http2/Http2.h b/src/transfer/http2/Http2.h index 6647fee..f4927f2 100644 --- a/src/transfer/http2/Http2.h +++ b/src/transfer/http2/Http2.h @@ -17,8 +17,7 @@ namespace Http2 { - enum class ErrorCode : uint32_t - { + enum class ErrorCode : uint32_t { NO_ERROR = 0x0, PROTOCOL_ERROR, INTERNAL_ERROR, @@ -35,8 +34,7 @@ namespace Http2 HTTP_1_1_REQUIRED }; - enum class FrameType : uint8_t - { + enum class FrameType : uint8_t { DATA = 0x0, HEADERS, PRIORITY, @@ -49,8 +47,7 @@ namespace Http2 CONTINUATION }; - enum class FrameFlag : uint8_t - { + enum class FrameFlag : uint8_t { EMPTY = 0x0, ACK = 0x1, END_STREAM = 0x1, @@ -63,8 +60,7 @@ namespace Http2 FrameFlag operator |(const FrameFlag left, const FrameFlag right) noexcept; FrameFlag operator |=(FrameFlag &left, const FrameFlag right) noexcept; - struct FrameMeta - { + struct FrameMeta { uint32_t stream_id; uint32_t length; FrameType type; @@ -72,10 +68,9 @@ namespace Http2 }; constexpr uint32_t FRAME_HEADER_SIZE = 9; - constexpr uint32_t MAX_WINDOW_UPDATE = uint32_t(1 << 31) - 1; + constexpr uint32_t MAX_WINDOW_UPDATE = (uint32_t(1) << 31) - 1; - enum class ConnectionSetting : uint16_t - { + enum class ConnectionSetting : uint16_t { SETTINGS_HEADER_TABLE_SIZE = 0x1, SETTINGS_ENABLE_PUSH = 0x2, SETTINGS_MAX_CONCURRENT_STREAMS = 0x3, @@ -84,8 +79,7 @@ namespace Http2 SETTINGS_MAX_HEADER_LIST_SIZE = 0x6 }; - struct ConnectionSettings - { + struct ConnectionSettings { uint32_t header_table_size; uint32_t enable_push; uint32_t max_concurrent_streams; @@ -96,8 +90,7 @@ namespace Http2 static ConnectionSettings defaultSettings() noexcept; }; - enum class StreamState : uint8_t - { + enum class StreamState : uint8_t { IDLE, RESERVED, OPEN, @@ -105,8 +98,7 @@ namespace Http2 CLOSED }; - struct ConnectionSync - { + struct ConnectionSync { Utils::Event event; std::mutex mtx; std::atomic completed {}; @@ -124,7 +116,12 @@ namespace Http2 public: DynamicTable() noexcept; - DynamicTable(const uint32_t headerTableSize, const uint32_t maxHeaderListSize, std::deque > &&list) noexcept; + + DynamicTable( + const uint32_t headerTableSize, + const uint32_t maxHeaderListSize, + std::deque > &&list + ) noexcept; size_t size() const noexcept; @@ -134,14 +131,17 @@ namespace Http2 void changeHeaderTableSize(const uint32_t headerTableSize); void changeMaxHeaderListSize(const uint32_t maxHeaderListSize); - const std::pair &operator[](const size_t index) const noexcept; - std::pair &operator[](const size_t index) noexcept; + const std::pair & + operator[](const size_t index) const noexcept; - const std::deque > &getList() const noexcept; + std::pair & + operator[](const size_t index) noexcept; + + const std::deque > & + getList() const noexcept; }; - struct ConnectionData - { + struct ConnectionData { DynamicTable decoding_dynamic_table; DynamicTable encoding_dynamic_table; @@ -169,9 +169,17 @@ namespace Http2 void *reserved; public: - IncStream(const uint32_t streamId, ConnectionData &conn) noexcept; - - uint8_t *setHttp2FrameHeader(uint8_t *addr, const uint32_t frameSize, const Http2::FrameType frameType, const Http2::FrameFlag frameFlags) noexcept; + IncStream( + const uint32_t streamId, + ConnectionData &conn + ) noexcept; + + uint8_t *setHttp2FrameHeader( + uint8_t *addr, + const uint32_t frameSize, + const Http2::FrameType frameType, + const Http2::FrameFlag frameFlags + ) noexcept; void lock(); void unlock() noexcept; @@ -182,22 +190,31 @@ namespace Http2 struct OutStream { uint32_t stream_id; - - ConnectionSettings settings; - int32_t window_size_out; + ConnectionSettings settings; DynamicTable dynamic_table; std::mutex *mtx; public: - OutStream(const uint32_t streamId, const ConnectionSettings &settings, DynamicTable &&dynamic_table, std::mutex *mtx) noexcept; + OutStream( + const uint32_t streamId, + const ConnectionSettings &settings, + DynamicTable &&dynamic_table, + std::mutex *mtx + ) noexcept; + OutStream(const IncStream &stream); - uint8_t *setHttp2FrameHeader(uint8_t *addr, const uint32_t frameSize, const Http2::FrameType frameType, const Http2::FrameFlag frameFlags) noexcept; + uint8_t *setHttp2FrameHeader( + uint8_t *addr, + const uint32_t frameSize, + const Http2::FrameType frameType, + const Http2::FrameFlag frameFlags + ) noexcept; void lock(); void unlock() noexcept; }; -}; +} diff --git a/src/utils/Event.cpp b/src/utils/Event.cpp index 6b23628..3c9fd01 100644 --- a/src/utils/Event.cpp +++ b/src/utils/Event.cpp @@ -11,19 +11,16 @@ namespace Utils void Event::wait() { - if (false == this->signaled.load() ) - { + if (this->signaled.load() == false) { std::unique_lock lck(this->mtx); - do - { + do { this->cv.wait(lck); } - while (false == this->signaled.load() ); + while (this->signaled.load() == false); } - if (false == this->manually) - { + if (false == this->manually) { this->signaled.store(false); } } @@ -32,71 +29,63 @@ namespace Utils { bool is_timeout = false; - if (false == this->signaled.load() ) - { + if (this->signaled.load() == false) { std::unique_lock lck(this->mtx); - is_timeout = false == this->cv.wait_for(lck, ms, [this] { return this->notifed(); } ); + is_timeout = false == this->cv.wait_for(lck, ms, [this] { + return this->notifed(); + }); } - if (false == this->manually) - { + if (false == this->manually) { this->signaled.store(false); } return is_timeout; } - bool Event::wait_until(const std::chrono::high_resolution_clock::time_point &tp) - { + bool Event::wait_until( + const std::chrono::high_resolution_clock::time_point &tp + ) { bool is_timeout = false; - if (false == this->signaled.load() ) - { + if (this->signaled.load() == false) { std::unique_lock lck(this->mtx); - do - { - if (std::cv_status::timeout == this->cv.wait_until(lck, tp) ) - { + do { + if (std::cv_status::timeout == this->cv.wait_until(lck, tp) ) { is_timeout = true; break; } } - while (false == this->signaled.load() ); + while (this->signaled.load() == false); } - if (false == this->manually) - { + if (false == this->manually) { this->signaled.store(false); } return is_timeout; } - void Event::notify() noexcept - { + void Event::notify() noexcept { this->signaled.store(true); this->cv.notify_all(); } - void Event::notify(const size_t threadsCount) noexcept - { + void Event::notify(const size_t threadsCount) noexcept { this->signaled.store(true); - for (size_t i = 0; i < threadsCount; ++i) - { + for (size_t i = 0; i < threadsCount; ++i) { this->cv.notify_one(); } } - void Event::reset() noexcept - { + void Event::reset() noexcept { this->signaled.store(false); } - bool Event::notifed() const noexcept - { + bool Event::notifed() const noexcept { return this->signaled.load(); } -}; +} diff --git a/src/utils/Event.h b/src/utils/Event.h index ddacbe4..b9d20ad 100644 --- a/src/utils/Event.h +++ b/src/utils/Event.h @@ -30,4 +30,4 @@ namespace Utils bool notifed() const noexcept; }; -}; +} diff --git a/src/utils/Utils.cpp b/src/utils/Utils.cpp index 9ef440e..aacd218 100644 --- a/src/utils/Utils.cpp +++ b/src/utils/Utils.cpp @@ -12,17 +12,13 @@ namespace Utils { - void toLower(std::string &str) noexcept - { + void toLower(std::string &str) noexcept { std::transform(str.begin(), str.end(), str.begin(), ::tolower); } - std::string getLowerString(const std::string &str) - { + std::string getLowerString(const std::string &str) { std::string copy = str; - toLower(copy); - return copy; } @@ -32,20 +28,20 @@ namespace Utils const size_t last = str.find_last_not_of(whitespace.data() ); - if (std::string::npos == last) - { + if (std::string::npos == last) { return str.clear(); } - str.assign(str.cbegin() + str.find_first_not_of(whitespace.data() ), str.cbegin() + last + 1); + str.assign( + str, + str.find_first_not_of(whitespace.data() ), + last + 1 + ); } - std::string getTrimmedString(const std::string &str) - { + std::string getTrimmedString(const std::string &str) { std::string copy = str; - trim(copy); - return copy; } @@ -64,8 +60,7 @@ namespace Utils pos = delimiter; - if (std::string::npos != pos) - { + if (std::string::npos != pos) { ++pos; } } @@ -78,8 +73,7 @@ namespace Utils std::string buf; buf.reserve(str.length() ); - for (size_t pos = 0; pos < str.length(); ++pos) - { + for (size_t pos = 0; pos < str.length(); ++pos) { switch (str[pos]) { case '&': buf.append("&"); break; @@ -102,8 +96,7 @@ namespace Utils static const std::array hexDigits { "0123456789abcdef" }; - for (size_t i = dataSize - 1; std::numeric_limits::max() != i; --i) - { + for (size_t i = dataSize - 1; std::numeric_limits::max() != i; --i) { str[i * 2 + 0] = hexDigits[bin[i] >> 4]; str[i * 2 + 1] = hexDigits[bin[i] & 0x0F]; } @@ -113,17 +106,14 @@ namespace Utils static unsigned char hexStringToBinEncodeSymbol(const char c) noexcept { - if (c >= '0' && c <= '9') - { - return c - 0x30; + if (c >= '0' && c <= '9') { + return static_cast(c - 0x30); } - else if (c >= 'a' && c <= 'f') - { - return c - 0x57; + else if (c >= 'a' && c <= 'f') { + return static_cast(c - 0x57); } - else if (c >= 'A' && c <= 'F') - { - return c - 0x37; + else if (c >= 'A' && c <= 'F') { + return static_cast(c - 0x37); } return 0; @@ -133,12 +123,11 @@ namespace Utils { std::string bin(hexStr.length() / 2, 0); - for (size_t i = 0; i < bin.length(); ++i) - { + for (size_t i = 0; i < bin.length(); ++i) { const char a = hexStr[i * 2 + 0]; const char b = hexStr[i * 2 + 1]; - bin[i] = ( + bin[i] = char( (hexStringToBinEncodeSymbol(a) << 4) | hexStringToBinEncodeSymbol(b) ); } @@ -161,14 +150,12 @@ namespace Utils unsigned char c[sizeof(uint64_t)]; } x; - if (endian == Endianness::INIT) - { + if (endian == Endianness::INIT) { x.ull = 0x01; endian = (x.c[7] == 0x01ULL) ? Endianness::BIGE : Endianness::LITE; } - if (endian == Endianness::BIGE) - { + if (endian == Endianness::BIGE) { return host64; } @@ -184,8 +171,7 @@ namespace Utils return x.ull; } - uint64_t ntoh64(const uint64_t net64) noexcept - { + uint64_t ntoh64(const uint64_t net64) noexcept { return hton64(net64); } @@ -198,20 +184,16 @@ namespace Utils uint8_t c[sizeof(uint32_t)]; } x; - if (endian == Endianness::INIT) - { + if (endian == Endianness::INIT) { x.ui = 0x01; endian = (x.c[3] == 0x01) ? Endianness::BIGE : Endianness::LITE; } x.ui = src; - if (endian == Endianness::BIGE) - { + if (endian == Endianness::BIGE) { x.ui <<= 8; - } - else - { + } else { uint8_t c = x.c[0]; x.c[0] = x.c[2]; x.c[2] = c; @@ -229,14 +211,12 @@ namespace Utils uint8_t c[sizeof(uint32_t)]; } x; - if (endian == Endianness::INIT) - { + if (endian == Endianness::INIT) { x.ui = 0x01; endian = (x.c[3] == 0x01) ? Endianness::BIGE : Endianness::LITE; } - if (endian == Endianness::BIGE) - { + if (endian == Endianness::BIGE) { return *reinterpret_cast(src24) >> 8; } @@ -248,59 +228,57 @@ namespace Utils x.c[1] = addr[1]; x.c[2] = addr[0]; - return x.ui;// *reinterpret_cast(x.c); + return x.ui; } - std::string getUniqueName() - { - size_t time = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + std::string getUniqueName() { + size_t time = size_t( + std::chrono::high_resolution_clock::now().time_since_epoch().count() + ); time = hton64(time); return binToHexString(&time, sizeof(time) ); } + constexpr uint8_t PACK_NUMBER_SIZE_BYTE = 252; + constexpr uint8_t PACK_NUMBER_SIZE_16 = 253; + constexpr uint8_t PACK_NUMBER_SIZE_32 = 254; + constexpr uint8_t PACK_NUMBER_SIZE_MAX = 255; + size_t getPackNumberSize(const size_t number) noexcept { - if (number <= 253) - { + if (number <= PACK_NUMBER_SIZE_BYTE) { return sizeof(uint8_t); } - else if (number <= std::numeric_limits::max() ) - { + else if (number <= std::numeric_limits::max() ) { return sizeof(uint8_t) + sizeof(uint16_t); } - else if (number <= std::numeric_limits::max() ) - { + else if (number <= std::numeric_limits::max() ) { return sizeof(uint8_t) + sizeof(uint32_t); } return sizeof(uint8_t) + sizeof(size_t); } - size_t getPackStringSize(const std::string &str) noexcept - { + size_t getPackStringSize(const std::string &str) noexcept { return getPackNumberSize(str.length() ) + str.length(); } - uint8_t *packPointer(uint8_t *dest, void *pointer) noexcept - { + uint8_t *packPointer(uint8_t *dest, void *pointer) noexcept { *reinterpret_cast(dest) = pointer; - return dest + sizeof(void *); } uint8_t *packNumber(uint8_t *dest, const size_t number) noexcept { - if (number <= 252) - { - *dest = number; + if (number <= PACK_NUMBER_SIZE_BYTE) { + *dest = static_cast(number); dest += sizeof(uint8_t); } - else if (number <= std::numeric_limits::max() ) - { - *dest = 253; + else if (number <= std::numeric_limits::max() ) { + *dest = PACK_NUMBER_SIZE_16; dest += sizeof(uint8_t); @@ -308,19 +286,16 @@ namespace Utils dest += sizeof(uint16_t); } - else if (number <= std::numeric_limits::max() ) - { - *dest = 254; + else if (number <= std::numeric_limits::max() ) { + *dest = PACK_NUMBER_SIZE_32; dest += sizeof(uint8_t); *reinterpret_cast(dest) = static_cast(number); dest += sizeof(uint32_t); - } - else - { - *dest = 255; + } else { + *dest = PACK_NUMBER_SIZE_MAX; dest += sizeof(uint8_t); @@ -332,17 +307,13 @@ namespace Utils return dest; } - uint8_t *packString(uint8_t *dest, const std::string &str) noexcept - { + uint8_t *packString(uint8_t *dest, const std::string &str) noexcept { dest = packNumber(dest, str.length() ); - std::memcpy(dest, str.data(), str.length() ); - return dest + str.length(); } - void packPointer(std::vector &buf, void *pointer) - { + void packPointer(std::vector &buf, void *pointer) { buf.resize(buf.size() + sizeof(void *) ); uint8_t *dest = reinterpret_cast(buf.data() + buf.size() - sizeof(void *) ); *reinterpret_cast(dest) = pointer; @@ -350,29 +321,24 @@ namespace Utils void packNumber(std::vector &buf, const size_t number) { - if (number <= 252) - { + if (number <= PACK_NUMBER_SIZE_BYTE) { buf.emplace_back(number); } - else if (number <= std::numeric_limits::max() ) - { - buf.emplace_back(253); + else if (number <= std::numeric_limits::max() ) { + buf.emplace_back(PACK_NUMBER_SIZE_16); buf.resize(buf.size() + sizeof(uint16_t) ); *reinterpret_cast(buf.data() + buf.size() - sizeof(uint16_t) ) = static_cast(number); } - else if (number <= std::numeric_limits::max() ) - { - buf.emplace_back(254); + else if (number <= std::numeric_limits::max() ) { + buf.emplace_back(PACK_NUMBER_SIZE_32); buf.resize(buf.size() + sizeof(uint32_t) ); *reinterpret_cast(buf.data() + buf.size() - sizeof(uint32_t) ) = static_cast(number); - } - else - { - buf.emplace_back(255); + } else { + buf.emplace_back(PACK_NUMBER_SIZE_MAX); buf.resize(buf.size() + sizeof(size_t) ); @@ -384,15 +350,21 @@ namespace Utils { packNumber(buf, str.length() ); - if (str.length() ) - { - std::copy(str.cbegin(), str.cend(), std::back_inserter(buf) ); + if (str.length() ) { + buf.insert( + buf.end(), + str.cbegin(), + str.cend() + ); } } - const uint8_t *unpackPointer(void **pointer, const uint8_t *src) noexcept - { - *pointer = *reinterpret_cast(const_cast(static_cast(src) ) ); + const uint8_t *unpackPointer(void **pointer, const uint8_t *src) noexcept { + *pointer = *reinterpret_cast( + const_cast( + static_cast(src) + ) + ); return src + sizeof(void *); } @@ -403,26 +375,18 @@ namespace Utils src += sizeof(uint8_t); - if (*number <= 252) - { + if (*number <= PACK_NUMBER_SIZE_BYTE) { } - else if (*number == 253) - { + else if (*number == PACK_NUMBER_SIZE_16) { *number = *reinterpret_cast(src); - src += sizeof(uint16_t); } - else if (*number == 254) - { + else if (*number == PACK_NUMBER_SIZE_32) { *number = *reinterpret_cast(src); - src += sizeof(uint32_t); - } - else - { + } else { *number = *reinterpret_cast(src); - src += sizeof(size_t); } @@ -456,8 +420,7 @@ namespace Utils /** * Parse RFC 882 (ddd, dd MMM yyyy HH:mm:ss K) */ - time_t rfc822DatetimeToTimestamp(const std::string &strTime) - { + time_t rfc822DatetimeToTimestamp(const std::string &strTime) { std::tm tc {}; // Parse RFC 882 (ddd, dd MMM yyyy HH:mm:ss K) @@ -465,8 +428,7 @@ namespace Utils size_t pos = strTime.find_first_not_of(' '); size_t delimiter = strTime.find(',', pos); - if (std::string::npos == delimiter || delimiter - pos != 3) - { + if (std::string::npos == delimiter || delimiter - pos != 3) { return ~0; } @@ -474,30 +436,25 @@ namespace Utils auto const it_day = map_days.find(day); - if (map_days.cend() != it_day) - { + if (map_days.cend() != it_day) { tc.tm_wday = it_day->second; - } - else - { + } else { return ~0; } pos = strTime.find_first_not_of(' ', delimiter + 1); delimiter = strTime.find_first_of(' ', pos); - if (std::string::npos == delimiter) - { + if (std::string::npos == delimiter) { return ~0; } - tc.tm_mday = std::strtoul(strTime.data() + pos, nullptr, 10); + tc.tm_mday = std::atoi(strTime.data() + pos); pos = strTime.find_first_not_of(' ', delimiter + 1); delimiter = strTime.find_first_of(' ', pos); - if (std::string::npos == delimiter || delimiter - pos != 3) - { + if (std::string::npos == delimiter || delimiter - pos != 3) { return ~0; } @@ -505,65 +462,56 @@ namespace Utils auto const it_mon = map_months.find(month); - if (map_months.cend() != it_mon) - { + if (map_months.cend() != it_mon) { tc.tm_mon = it_mon->second; - } - else - { + } else { return ~0; } pos = strTime.find_first_not_of(' ', delimiter + 1); delimiter = strTime.find_first_of(' ', pos); - if (std::string::npos == delimiter) - { + if (std::string::npos == delimiter) { return ~0; } - tc.tm_year = std::strtoul(strTime.data() + pos, nullptr, 10) - 1900; + tc.tm_year = std::atoi(strTime.data() + pos) - 1900; pos = strTime.find_first_not_of(' ', delimiter + 1); delimiter = strTime.find_first_of(':', pos); - if (std::string::npos == delimiter) - { + if (std::string::npos == delimiter) { return ~0; } - tc.tm_hour = std::strtoul(strTime.data() + pos, nullptr, 10); + tc.tm_hour = std::atoi(strTime.data() + pos); pos = strTime.find_first_not_of(' ', delimiter + 1); delimiter = strTime.find_first_of(':', pos); - if (std::string::npos == delimiter) - { + if (std::string::npos == delimiter) { return ~0; } - tc.tm_min = std::strtoul(strTime.data() + pos, nullptr, 10); + tc.tm_min = std::atoi(strTime.data() + pos); pos = strTime.find_first_not_of(' ', delimiter + 1); delimiter = strTime.find_first_of(' ', pos); - if (std::string::npos == delimiter) - { + if (std::string::npos == delimiter) { return ~0; } - tc.tm_sec = std::strtoul(strTime.data() + pos, nullptr, 10); + tc.tm_sec = std::atoi(strTime.data() + pos); pos = strTime.find_first_not_of(' ', delimiter + 1); delimiter = strTime.find_first_of(' ', pos); - if (std::string::npos == delimiter) - { + if (std::string::npos == delimiter) { delimiter = strTime.length(); } - if (std::string::npos == pos || delimiter - pos > 5) - { + if (std::string::npos == pos || delimiter - pos > 5) { return ~0; } @@ -573,8 +521,7 @@ namespace Utils int timezone = 0; - if (map_zones.cend() != it_zone) - { + if (map_zones.cend() != it_zone) { timezone = it_zone->second; } else if (zone.length() == 5 && ('+' == zone.front() || '-' == zone.front() ) ) @@ -585,16 +532,13 @@ namespace Utils zone.copy(hours.data(), 2, 1); zone.copy(minutes.data(), 2, 3); - timezone = std::strtoul(hours.data(), nullptr, 10) * 3600; - timezone += std::strtoul(minutes.data(), nullptr, 10) * 60; + timezone = std::atoi(hours.data()) * 3600; + timezone += std::atoi(minutes.data()) * 60; - if ('-' == zone.front() ) - { + if (zone.front() == '-') { timezone *= -1; } - } - else - { + } else { return ~0; } @@ -629,8 +573,7 @@ namespace Utils const char *ptrStr = std::strchr(strTime, ' '); - if (nullptr == ptrStr) - { + if (nullptr == ptrStr) { return ~0; } @@ -638,68 +581,60 @@ namespace Utils auto const it_mon = map_months.find(month); - if (map_months.cend() != it_mon) - { + if (map_months.cend() != it_mon) { tc.tm_mon = it_mon->second; - } - else - { + } else { return ~0; } ++ptrStr; // Fix for MS __DATE__ - if (' ' == *ptrStr) - { + if (' ' == *ptrStr) { ++ptrStr; } strTime = std::strchr(ptrStr, ' '); - if (nullptr == strTime) - { + if (nullptr == strTime) { return ~0; } - tc.tm_mday = std::strtoul(ptrStr, nullptr, 10); + tc.tm_mday = std::atoi(ptrStr); ++strTime; ptrStr = std::strchr(strTime, ' '); - if (nullptr == ptrStr) - { + if (nullptr == ptrStr) { return ~0; } - tc.tm_year = std::strtoul(strTime, nullptr, 10) - 1900; + tc.tm_year = std::atoi(strTime) - 1900; ++ptrStr; strTime = std::strchr(ptrStr, ':'); - if (nullptr == strTime) - { + if (nullptr == strTime) { return ~0; } - tc.tm_hour = std::strtoul(ptrStr, nullptr, 10); + tc.tm_hour = std::atoi(ptrStr); ++strTime; ptrStr = std::strchr(strTime, ':'); - if (nullptr == ptrStr) - { + if (nullptr == ptrStr) { return ~0; } - tc.tm_min = std::strtoul(strTime, nullptr, 10); + tc.tm_min = std::atoi(strTime); ++ptrStr; - tc.tm_sec = std::strtoul(ptrStr, nullptr, 10); + tc.tm_sec = std::atoi(ptrStr); return localToGmt(std::mktime(&tc) ); } @@ -711,36 +646,42 @@ namespace Utils { std::array buf; - if (tTime == ~0) - { + if (tTime == ~0) { std::time(&tTime); } #ifdef WIN32 std::tm stm {}; - isGmtTime ? - ::localtime_s(&stm, &tTime) : - ::gmtime_s(&stm, &tTime); + isGmtTime + ? ::localtime_s(&stm, &tTime) + : ::gmtime_s(&stm, &tTime); - // RFC 822 - auto const len = std::strftime(buf.data(), buf.size(), "%a, %d %b %Y %H:%M:%S GMT", &stm); + auto const len = std::strftime( + buf.data(), + buf.size(), + "%a, %d %b %Y %H:%M:%S GMT", // RFC 822 + &stm + ); #else std::tm stm {}; - isGmtTime ? - ::localtime_r(&tTime, &stm) : - ::gmtime_r(&tTime, &stm); + isGmtTime + ? ::localtime_r(&tTime, &stm) + : ::gmtime_r(&tTime, &stm); - // RFC 822 - auto const len = std::strftime(buf.data(), buf.size(), "%a, %d %b %G %H:%M:%S GMT", &stm); + auto const len = std::strftime( + buf.data(), + buf.size(), + "%a, %d %b %G %H:%M:%S GMT", // RFC 822 + &stm + ); #endif return std::string(buf.data(), buf.data() + len); } - std::string predefinedDatetimeToRfc822(const char *strTime) - { + std::string predefinedDatetimeToRfc822(const char *strTime) { const std::time_t time = predefinedDatetimeToTimestamp(strTime); return getDatetimeAsString(time, false); } @@ -749,8 +690,7 @@ namespace Utils { size_t length = 0; - do - { + do { ++length; number /= 10; } @@ -759,38 +699,53 @@ namespace Utils return length; } - bool parseCookies(const std::string &cookieHeader, std::unordered_multimap &cookies) - { - if (cookieHeader.empty() ) - { + bool parseCookies( + const std::string &cookieHeader, + std::unordered_multimap &cookies + ) { + if (cookieHeader.empty() ) { return true; } - for (size_t cur_pos = 0, next_value; std::string::npos != cur_pos; cur_pos = next_value) - { + for ( + size_t cur_pos = 0, next_value; + std::string::npos != cur_pos; + cur_pos = next_value + ) { next_value = cookieHeader.find(';', cur_pos); size_t delimiter = cookieHeader.find('=', cur_pos); - if (std::string::npos == delimiter || delimiter > next_value) - { + if (std::string::npos == delimiter || delimiter > next_value) { return false; } - std::string key = cookieHeader.substr(cur_pos, delimiter - cur_pos); + std::string key = cookieHeader.substr( + cur_pos, + delimiter - cur_pos + ); + trim(key); key = urlDecode(key); ++delimiter; - std::string value = cookieHeader.substr(delimiter, std::string::npos != next_value ? next_value - delimiter : next_value); + std::string value = cookieHeader.substr( + delimiter, + std::string::npos != next_value + ? next_value - delimiter + : next_value + ); + trim(value); value = urlDecode(value); - cookies.emplace(std::move(key), std::move(value) ); + cookies.emplace( + std::move(key), + std::move(value) + ); - if (std::string::npos != next_value) - { + if (std::string::npos != next_value) { ++next_value; } } @@ -798,8 +753,7 @@ namespace Utils return true; } - static inline bool isCharUrlAllowed(const char c) noexcept - { + static inline bool isCharUrlAllowed(const char c) noexcept { return c == '-' || c == '_' || c == '.' || c == '~'; } @@ -811,18 +765,14 @@ namespace Utils for (size_t i = 0; i < str.length(); ++i) { - const unsigned char c = str[i]; + const unsigned char c = static_cast(str[i]); - if (std::isalnum(c) || isCharUrlAllowed(c) ) - { - encoded.push_back(c); + if (std::isalnum(c) || isCharUrlAllowed(char(c) ) ) { + encoded.push_back(char(c) ); } - else if (' ' == c) - { + else if (' ' == c) { encoded.push_back('+'); - } - else - { + } else { const uint8_t a = c >> 4; const uint8_t b = c & 0x0F; @@ -841,26 +791,23 @@ namespace Utils for (size_t i = 0; i < str.length(); ++i) { - unsigned char c = str[i]; + unsigned char c = static_cast(str[i]); - if ('%' == c) - { - if (i + 2 < str.length() ) - { + if ('%' == c) { + if (i + 2 < str.length() ) { const char a = str[++i]; const char b = str[++i]; - c = ( + c = static_cast( (hexStringToBinEncodeSymbol(a) << 4) | hexStringToBinEncodeSymbol(b) ); } } - else if ('+' == c) - { + else if ('+' == c) { c = ' '; } - decoded.push_back(c); + decoded.push_back(char(c) ); } return decoded; diff --git a/src/utils/Utils.h b/src/utils/Utils.h index 9dce37a..551e975 100644 --- a/src/utils/Utils.h +++ b/src/utils/Utils.h @@ -36,8 +36,7 @@ namespace Utils { size_t full_size = getPackNumberSize(container.size() ); - for (auto const &pair : container) - { + for (auto const &pair : container) { full_size += getPackStringSize(pair.first); full_size += getPackStringSize(pair.second); } @@ -56,8 +55,7 @@ namespace Utils addr = packNumber(addr, container.size() ); - for (auto const &pair : container) - { + for (auto const &pair : container) { addr = packString(addr, pair.first); addr = packString(addr, pair.second); } @@ -74,8 +72,7 @@ namespace Utils { packNumber(buf, container.size() ); - for (auto const &pair : container) - { + for (auto const &pair : container) { packString(buf, pair.first); packString(buf, pair.second); } @@ -91,8 +88,7 @@ namespace Utils size_t count; src = unpackNumber(&count, src); - for (size_t i = 0; i < count; ++i) - { + for (size_t i = 0; i < count; ++i) { std::string key; src = unpackString(key, src); @@ -111,8 +107,7 @@ namespace Utils size_t count; src = unpackNumber(&count, src); - for (size_t i = 0; i < count; ++i) - { + for (size_t i = 0; i < count; ++i) { std::string key; src = unpackString(key, src); @@ -133,7 +128,10 @@ namespace Utils size_t getNumberLength(size_t number) noexcept; - bool parseCookies(const std::string &cookieHeader, std::unordered_multimap &cookies); + bool parseCookies( + const std::string &cookieHeader, + std::unordered_multimap &cookies + ); std::string urlEncode(const std::string &str); std::string urlDecode(const std::string &str);