From 845a585a2daf238d7ae6c90948d1eb06d0094268 Mon Sep 17 00:00:00 2001 From: awwit Date: Sat, 13 Jan 2018 18:04:55 +0300 Subject: [PATCH 1/7] Fixed bug in function `getPackNumberSize` (which caused the crash application in one case) --- Makefile | 2 +- src/utils/Utils.cpp | 29 +++++++++++++++++------------ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index c0e28ab..3e65d7d 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ $(BUILDDIR): $(MKDIR) $@ $(EXECUTABLE): $(OBJECTS) - $(CXX) $(OBJECTS) -o $@ $(LDFLAGS) + $(CXX) $(OBJECTS) -o $@ $(LDFLAGS) $(OBJECTS) : $(OBJDIR)/%.o : $(SOURCEDIR)/%.cpp @$(MKDIR) $(dir $@) diff --git a/src/utils/Utils.cpp b/src/utils/Utils.cpp index 77d8242..4ddc424 100644 --- a/src/utils/Utils.cpp +++ b/src/utils/Utils.cpp @@ -233,9 +233,14 @@ namespace Utils 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() ) { @@ -259,13 +264,13 @@ namespace Utils uint8_t *packNumber(uint8_t *dest, const size_t number) noexcept { - if (number <= 252) { + if (number <= PACK_NUMBER_SIZE_BYTE) { *dest = number; dest += sizeof(uint8_t); } else if (number <= std::numeric_limits::max() ) { - *dest = 253; + *dest = PACK_NUMBER_SIZE_16; dest += sizeof(uint8_t); @@ -274,7 +279,7 @@ namespace Utils dest += sizeof(uint16_t); } else if (number <= std::numeric_limits::max() ) { - *dest = 254; + *dest = PACK_NUMBER_SIZE_32; dest += sizeof(uint8_t); @@ -282,7 +287,7 @@ namespace Utils dest += sizeof(uint32_t); } else { - *dest = 255; + *dest = PACK_NUMBER_SIZE_MAX; dest += sizeof(uint8_t); @@ -308,24 +313,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); + 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); + 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); + buf.emplace_back(PACK_NUMBER_SIZE_MAX); buf.resize(buf.size() + sizeof(size_t) ); @@ -353,14 +358,14 @@ 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 { From 1796b812e837bd96cd2157bec93bd224e048d908 Mon Sep 17 00:00:00 2001 From: awwit Date: Sat, 20 Jan 2018 21:35:10 +0300 Subject: [PATCH 2/7] Fixed code of parsing configs. Started convert to state machine. Removed previous version of code. --- src/server/config/ConfigParser.cpp | 582 ++++++++++++----------------- src/server/config/ConfigParser.h | 19 +- 2 files changed, 240 insertions(+), 361 deletions(-) diff --git a/src/server/config/ConfigParser.cpp b/src/server/config/ConfigParser.cpp index fee0df6..20ed3e0 100644 --- a/src/server/config/ConfigParser.cpp +++ b/src/server/config/ConfigParser.cpp @@ -7,24 +7,31 @@ #include #include -const long FILESIZE = 1024 * 1024; - namespace HttpServer { + enum class ConfigMimeState { + NONE, + TYPE + }; + + enum class ConfigState { + NONE, + PARAM, + BLOCK + }; + + constexpr long FILESIZE = 2 * 1024 * 1024; + /** * Config - include file */ bool ConfigParser::includeConfigFile(const std::string &fileName, std::string &strBuf, const std::size_t offset) { - std:: cout << "config file name: " << fileName << std::endl; std::ifstream file(fileName); - if ( ! file) - { + if ( ! file) { file.close(); - std::cout << "Error: file " << fileName << " cannot be open;" << std::endl; - return false; } @@ -32,19 +39,15 @@ namespace HttpServer std::streamsize file_size = file.tellg(); file.seekg(0, std::ifstream::beg); - constexpr std::streamsize file_size_max = 2 * FILESIZE; + constexpr std::streamsize file_size_max = FILESIZE; - if (file_size_max < file_size) - { + if (file_size_max < file_size) { file.close(); - std::cout << "Error: file " << fileName << " is too large; max include file size = " << file_size_max << " bytes;" << std::endl; - return false; } - if (file_size) - { + if (file_size) { std::vector buf(file_size); file.read(buf.data(), file_size); @@ -68,8 +71,7 @@ namespace HttpServer { auto const it_name = app.find("server_name"); - if (app.cend() == it_name) - { + if (app.cend() == it_name) { std::cout << "Error: application parameter 'server_name' has not been specified;" << std::endl; return false; } @@ -121,14 +123,10 @@ namespace HttpServer { const int port = std::strtol(value.c_str(), nullptr, 10); - if (port) - { - if (is_tls) - { + if (port) { + if (is_tls) { tls_ports.emplace(port); - } - else - { + } else { ports.emplace(port); } } @@ -142,73 +140,61 @@ namespace HttpServer std::string stapling_file; std::string dh_file; - if (false == tls_ports.empty() ) + if (tls_ports.empty() == false) { auto const it_ca_file = app.find("tls_certificate_chain"); - if (app.cend() != it_ca_file) - { + if (app.cend() != it_ca_file) { chain_file = it_ca_file->second; } auto const it_crl_file = app.find("tls_certificate_crl"); - if (app.cend() != it_crl_file) - { + if (app.cend() != it_crl_file) { crl_file = it_crl_file->second; } auto const it_stapling_file = app.find("tls_stapling_file"); - if (app.cend() != it_stapling_file) - { + if (app.cend() != it_stapling_file) { stapling_file = it_stapling_file->second; } auto const it_dh_params_file = app.find("tls_dh_params_file"); - if (app.cend() != it_dh_params_file) - { + if (app.cend() != it_dh_params_file) { dh_file = it_dh_params_file->second; } auto const it_cert_file = app.find("tls_certificate"); - if (app.cend() == it_cert_file) - { + if (app.cend() == it_cert_file) { std::cout << "Error: tls certificate file \"CERT\" has not been specified in configuration file;" << std::endl; tls_ports.clear(); - } - else - { + } else { cert_file = it_cert_file->second; } auto const it_key_file = app.find("tls_certificate_key"); - if (app.cend() == it_key_file) - { + if (app.cend() == it_key_file) { std::cout << "Error: tls certificate key file \"KEY\" has not been specified in configuration file;" << std::endl; tls_ports.clear(); - } - else - { + } else { key_file = it_key_file->second; } } auto const it_root_dir = app.find("root_dir"); - if (app.cend() == it_root_dir || it_root_dir->second.empty() ) - { + if (app.cend() == it_root_dir || it_root_dir->second.empty() ) { std::cout << "Error: application parameter 'root_dir' has not been specified;" << std::endl; return false; } auto const it_module = app.find("server_module"); - if (app.cend() == it_module) - { + if (app.cend() == it_module) { std::cout << "Error: application parameter 'server_module' has not been specified;" << std::endl; return false; } @@ -217,30 +203,26 @@ namespace HttpServer System::Module module(it_module->second); - if (false == module.is_open() ) - { + if (module.is_open() == false) { std::cout << "Error: module '" << it_module->second << "' cannot be open;" << std::endl; return false; } void *(*addr)(void *) = nullptr; - if (false == module.find("application_call", &addr) ) - { + if (module.find("application_call", &addr) == false) { std::cout << "Error: function 'application_call' not found in module '" << it_module->second << "';" << std::endl; return false; } std::function app_call = reinterpret_cast(addr); - if ( ! app_call) - { + if ( ! app_call) { std::cout << "Error: invalid function 'application_call' in module '" << it_module->second << "';" << std::endl; return false; } - if (false == module.find("application_clear", &addr) ) - { + if (module.find("application_clear", &addr) == false) { std::cout << "Error: function 'application_clear' not found in module '" << it_module->second << "';" << std::endl; return false; } @@ -249,30 +231,26 @@ namespace HttpServer std::function app_init = std::function(); - if (module.find("application_init", &addr) ) - { + if (module.find("application_init", &addr) ) { app_init = reinterpret_cast(addr); } std::function app_final = std::function(); - if (module.find("application_final", &addr) ) - { + if (module.find("application_final", &addr) ) { app_final = reinterpret_cast(addr); } std::string root_dir = it_root_dir->second; #ifdef WIN32 - if ('\\' == root_dir.back() ) - { + if (root_dir.back() == '\\') { root_dir.pop_back(); } #endif // Remove back slash from root_dir - if ('/' == root_dir.back() ) - { + if (root_dir.back() == '/') { root_dir.pop_back(); } @@ -293,10 +271,8 @@ namespace HttpServer success = false; } - if (false == success) - { + if (false == success) { std::cout << "Warning: error when initializing application '" << it_module->second << "';" << std::endl; - return false; } @@ -324,8 +300,7 @@ namespace HttpServer } } - if (std::numeric_limits::max() == module_index) - { + if (std::numeric_limits::max() == module_index) { module_index = modules.size(); modules.emplace_back(std::move(module) ); } @@ -357,14 +332,10 @@ namespace HttpServer }; // Add application names in tree - if (names.empty() ) - { + if (names.empty() ) { apps_tree.addApplication(app_name, settings); - } - else - { - for (size_t i = 0; i < names.size(); ++i) - { + } else { + for (size_t i = 0; i < names.size(); ++i) { apps_tree.addApplication(names[i], settings); } } @@ -382,12 +353,9 @@ namespace HttpServer { std::ifstream file(fileName); - if ( ! file) - { + if ( ! file) { file.close(); - std::cout << "Error: " << fileName << " - cannot be open;" << std::endl; - return false; } @@ -395,14 +363,11 @@ namespace HttpServer std::streamsize file_size = file.tellg(); file.seekg(0, std::ifstream::beg); - const std::streamsize file_size_max = 2048 * 1024; + const std::streamsize file_size_max = FILESIZE; - if (file_size_max < file_size) - { + if (file_size_max < file_size) { file.close(); - std::cout << "Error: " << fileName << " - is too large; max file size = " << file_size_max << " bytes;" << std::endl; - return false; } @@ -414,94 +379,90 @@ namespace HttpServer const std::string str_buf(buf.cbegin(), buf.cend() ); + size_t delimiter = 0; size_t cur_pos = 0; + size_t end_pos = str_buf.find('\n', cur_pos); - ConfigFileDataState dataState = CONFIGFILEDATASNONE; + ConfigMimeState state = ConfigMimeState::NONE; - while (std::string::npos != cur_pos) + while (std::string::npos != end_pos) { - //std::cout << "parse Mine dataState: " << dataState << std::endl; - switch(dataState) + switch (state) { - case CONFIGFILEDATASNONE: + case ConfigMimeState::NONE: + { + cur_pos = str_buf.find_first_not_of(whitespace, cur_pos); + delimiter = str_buf.find_first_of(whitespace, cur_pos); - case CONFIGFILEDATASNOTE: - - { - cur_pos = str_buf.find_first_not_of(whitespace, cur_pos); - if (cur_pos == std::string::npos) - { - return true; - } + if (delimiter >= end_pos) { + cur_pos = end_pos + 1; + end_pos = str_buf.find('\n', cur_pos); + break; + } - //start from next line - if ('#' == buf[cur_pos]) - { - //last line - cur_pos = str_buf.find_first_of("\n", cur_pos); - if (cur_pos == std::string::npos) - { - return true; - } + if ('#' != str_buf[cur_pos]) { + state = ConfigMimeState::TYPE; + } - cur_pos += 1; + break; + } - dataState = CONFIGFILEDATASNOTE; - } - else if ('\n' == buf[cur_pos]) - { - cur_pos += 1; - dataState = CONFIGFILEDATASNONE; - } - else - { - dataState = CONFIGFILEDATASTYPE; - } + case ConfigMimeState::TYPE: + { + state = ConfigMimeState::NONE; + + std::string mime_type = str_buf.substr(cur_pos, delimiter - cur_pos); + + delimiter = str_buf.find_first_not_of(whitespace, delimiter); + + if (delimiter >= end_pos) { + cur_pos = end_pos + 1; + end_pos = str_buf.find('\n', cur_pos); + break; } - break; - case CONFIGFILEDATASTYPE: + + std::string ext = str_buf.substr(delimiter, end_pos - delimiter); + + delimiter = ext.find_first_of(whitespace); + + if (std::string::npos != delimiter) { - size_t delimiter = str_buf.find_first_of("\n", cur_pos); - std::string strLine = str_buf.substr(cur_pos, delimiter - cur_pos); - - //get mimetypes + for (size_t ext_pos = 0; std::string::npos != ext_pos; ) { - size_t ext_pos = strLine.find_first_of(whitespace, 0); - if (ext_pos == std::string::npos) - { - return false; + std::string ext_unit = ext.substr(ext_pos, + std::string::npos == delimiter + ? std::string::npos + : delimiter - ext_pos + ); + + if (ext_unit.empty() == false) { + mimes_types.emplace(std::move(ext_unit), mime_type); } - std::string strExt = strLine.substr(0, ext_pos); - size_t extUnitPos = strLine.find_first_not_of(whitespace, ext_pos); - std::string strExtUnit = strLine.substr(extUnitPos, strLine.length() - extUnitPos); - mimes_types.emplace(std::move(strExt), std::move(strExtUnit)); + ext_pos = ext.find_first_not_of(whitespace, delimiter); - //std::cout << strExt << " " << strExtUnit << std::endl; - } - - //change line - cur_pos = str_buf.find_first_of("\n", cur_pos); - if (cur_pos == std::string::npos) - { - return true; + delimiter = ext.find_first_of(whitespace, ext_pos); } + } + else + { + mimes_types.emplace(std::move(ext), std::move(mime_type) ); + } - cur_pos += 1; + cur_pos = end_pos + 1; + end_pos = str_buf.find('\n', cur_pos); - dataState = CONFIGFILEDATASNONE; - - } break; + } + default: break; } } - + return true; } - static size_t findBlockEnd(const std::string &str_buf, size_t str_pos) { size_t pos = str_buf.find('}', str_pos); @@ -510,22 +471,18 @@ namespace HttpServer { size_t begin_line = str_buf.rfind('\n', pos); - if (std::string::npos == begin_line) - { + if (std::string::npos == begin_line) { begin_line = 0; } begin_line = str_buf.find_first_not_of("\r\n", begin_line); - if ('#' == str_buf[begin_line]) - { - str_pos = str_buf.find_first_of("\r\n", pos); - } - else - { + if ('#' != str_buf[begin_line]) { break; } + str_pos = str_buf.find_first_of("\r\n", pos); + pos = str_buf.find('}', str_pos); } @@ -537,11 +494,9 @@ namespace HttpServer */ bool ConfigParser::loadConfig(const std::string &conf_file_name, ServerSettings &settings, std::vector &modules) { - //std::cout << "enter loadCofig" << std::endl; std::string str_buf; - if (false == includeConfigFile(conf_file_name, str_buf) ) - { + if (includeConfigFile(conf_file_name, str_buf) == false) { return false; } @@ -554,238 +509,181 @@ namespace HttpServer const std::string whitespace(" \t\n\v\f\r"); size_t cur_pos = 0; + size_t end_pos = 0; + size_t block_pos = 0; - ConfigFileDataState dataState = CONFIGFILEDATASNONE; - InBlockDataState inBlockState = INBLOCKNONE; - - std::unordered_multimap app; + ConfigState state = ConfigState::NONE; - int iStatus = 0; - while (std::string::npos != cur_pos) + while (std::string::npos != end_pos) { - //std::cout << "parse Mine dataState: " << dataState << std::endl; - if (iStatus == 1 || iStatus == 2) + switch (state) { - break; - } + case ConfigState::NONE: + { + end_pos = str_buf.find(';', cur_pos); + block_pos = str_buf.find('{', cur_pos); - switch (dataState) - { - case CONFIGFILEDATASNONE: + if (end_pos < block_pos) { + state = ConfigState::PARAM; + } + else if (std::string::npos != block_pos) { + state = ConfigState::BLOCK; + } - case CONFIGFILEDATASNOTE: - { - cur_pos = str_buf.find_first_not_of(whitespace, cur_pos); - if (cur_pos == std::string::npos) - { - iStatus = 1; - } + break; + } - //start from next line - if ('#' == str_buf[cur_pos]) - { - //last line - cur_pos = str_buf.find_first_of("\n", cur_pos); - if (cur_pos == std::string::npos) - { - iStatus = 1; - } + case ConfigState::PARAM: + { + state = ConfigState::NONE; - cur_pos += 1; + cur_pos = str_buf.find_first_not_of(whitespace, cur_pos); + end_pos = str_buf.find(';', cur_pos); + size_t delimiter = str_buf.find_first_of(whitespace, cur_pos); - dataState = CONFIGFILEDATASNOTE; - } - else if ('\n' == str_buf[cur_pos]) - { - cur_pos += 1; - dataState = CONFIGFILEDATASNONE; - } - else - { - dataState = CONFIGFILEDATASTYPE; - } - } - break; - case CONFIGFILEDATASTYPE: + if (delimiter < end_pos) { - //in app and main config file "; and \n " has different meaning - size_t delimiter = str_buf.find_first_of("\n", cur_pos); - //std:: cout << "str_buf.length()" << str_buf.length() << " delimiter " << delimiter - // << " cur_pos " << cur_pos << std::endl; - //std::cout << "npos: " << std::string::npos << std::endl; - if (delimiter == std::string::npos) + std::string param_name = str_buf.substr(cur_pos, delimiter - cur_pos); + + if ('#' != param_name.front() ) { - iStatus = 1; - } + cur_pos = str_buf.find_first_not_of(whitespace, delimiter + 1); + delimiter = str_buf.find_last_not_of(whitespace, end_pos); - std::string strLine = str_buf.substr(cur_pos, delimiter - cur_pos); - //std::cout << "strLine: " << strLine << std::endl; - do { - size_t ext_pos = strLine.find_first_of(whitespace, 0); - if (ext_pos == std::string::npos) - { - iStatus = 2; - } - std::string param_name = strLine.substr(0, ext_pos); - size_t extUnitPos = strLine.find_first_not_of(whitespace, ext_pos); + std::string param_value = str_buf.substr(cur_pos, delimiter - cur_pos); - //mines the last ";" - std::string param_value; - if (strLine[strLine.length() - 1] == ';') + if ("include" == param_name) { - param_value = strLine.substr(extUnitPos, strLine.length() - extUnitPos - 1); - } - else - { - param_value = strLine.substr(extUnitPos, strLine.length() - extUnitPos); - } - - //std::cout << param_name << " " << param_value << std::endl; - if (param_name == "server" && param_value == "{") - { - dataState = CONFIGFILEDATAINBLOCK; - inBlockState = INBLOCKNONE; - } - else if(param_name == "include") - { - this->loadConfig(param_value, settings, modules); - dataState = CONFIGFILEDATASNONE; + this->includeConfigFile(param_value, str_buf, end_pos + 1); } else { global.emplace(std::move(param_name), std::move(param_value) ); - dataState = CONFIGFILEDATASNONE; } - break; - } while (1); - - //change line - cur_pos = str_buf.find_first_of("\n", cur_pos); - if (cur_pos == std::string::npos) + } + else // if comment line { - iStatus = 1; + end_pos = str_buf.find_first_of("\r\n", cur_pos); } - - cur_pos += 1; } + + cur_pos = std::string::npos == end_pos + ? std::string::npos + : end_pos + 1; + break; - case CONFIGFILEDATAINBLOCK: + } + + case ConfigState::BLOCK: + { + state = ConfigState::NONE; + + cur_pos = str_buf.find_first_not_of(whitespace, cur_pos); + end_pos = str_buf.find(';', cur_pos); + size_t delimiter = str_buf.find_first_of(whitespace, cur_pos); + + const std::string block_type_name = str_buf.substr(cur_pos, delimiter - cur_pos); + + if ('#' != block_type_name.front() ) { - switch(inBlockState) + delimiter = str_buf.find_first_not_of(whitespace, delimiter); + + cur_pos = block_pos + 1; + size_t block_end = findBlockEnd(str_buf, cur_pos); + + if (std::string::npos == block_end) + { + std::cout << "Error: symbol '}' after '" << block_type_name << "' has not been found;" << std::endl + << "Parsing config aborted;" << std::endl; + + return false; + } + else if (delimiter == block_pos) { - case INBLOCKNONE: - case INBLOCKNOTE: + if ("server" == block_type_name) + { + std::unordered_multimap app; + + end_pos = str_buf.find(';', cur_pos); + + while (block_end > end_pos) { cur_pos = str_buf.find_first_not_of(whitespace, cur_pos); - if (cur_pos == std::string::npos) - { - iStatus = 1; - } + delimiter = str_buf.find_first_of(whitespace, cur_pos); - //start from next line - if ('#' == str_buf[cur_pos]) + if (delimiter < end_pos) { - //last line - cur_pos = str_buf.find_first_of("\n", cur_pos); - if (cur_pos == std::string::npos) - { - iStatus = 1; - } - - cur_pos += 1; + std::string param_name = str_buf.substr(cur_pos, delimiter - cur_pos); - inBlockState = INBLOCKNOTE; - } - else if ('\n' == str_buf[cur_pos]) - { - cur_pos += 1; - inBlockState = INBLOCKNONE; - } - else - { - inBlockState = INBLOCKTPYE; - } - } - break; - case INBLOCKTPYE: - { - size_t delimiter = str_buf.find_first_of("\n", cur_pos); - std::string strLine = str_buf.substr(cur_pos, delimiter - cur_pos); - - //std::cout << "inblockLineStr: " << strLine << std::endl; - - do { - if ("}" == strLine) + if ('#' != param_name.front() ) { - dataState = CONFIGFILEDATASNOTE; - applications.push_back(app); - app.clear(); - break; + cur_pos = str_buf.find_first_not_of(whitespace, delimiter + 1); + delimiter = str_buf.find_last_not_of(whitespace, end_pos); + + std::string param_value = str_buf.substr(cur_pos, delimiter - cur_pos); + + if ("include" == param_name) + { + cur_pos = end_pos + 1; + this->includeConfigFile(param_value, str_buf, cur_pos); + block_end = findBlockEnd(str_buf, cur_pos); + } + else + { + app.emplace(std::move(param_name), std::move(param_value) ); + } } - - size_t ext_pos = strLine.find_first_of(whitespace, 0); - if (ext_pos == std::string::npos) + else // if comment line { - iStatus = 2; + end_pos = str_buf.find_first_of("\r\n", cur_pos); } - std::string strExt = strLine.substr(0, ext_pos); - size_t extUnitPos = strLine.find_first_not_of(whitespace, ext_pos); - std::string strExtUnit = strLine.substr(extUnitPos, strLine.length() - extUnitPos - 1); - - //std::cout << "inblockLine " << strExt << " " << strExtUnit << std::endl; - app.emplace(std::move(strExt), std::move(strExtUnit)); - - break; - - } while(1); - - //change line - cur_pos = str_buf.find_first_of("\n", cur_pos); - if (cur_pos == std::string::npos) - { - iStatus = 2; } - cur_pos += 1; + cur_pos = std::string::npos == end_pos + ? std::string::npos + : end_pos + 1; - inBlockState = INBLOCKNONE; + end_pos = str_buf.find(';', cur_pos); } - break; - default: - break; + + applications.emplace_back(std::move(app) ); + } + else + { + std::cout << "Warning: " << block_type_name << " - unknown block type;" << std::endl; + } } + else + { + std::cout << "Warning: after " << block_type_name << " expected '{' ;" << std::endl; + } + + cur_pos = std::string::npos == block_end + ? std::string::npos + : block_end + 1; + } + else // if comment line + { + cur_pos = str_buf.find_first_of("\r\n", cur_pos); } + break; + } + default: break; } } - // std::cout << "app value start" << std::endl; - // for (size_t i = 0; i < applications.size(); ++i) - // { - // std::unordered_multimap sa = applications[i]; - // for (auto iter = sa.begin(); iter != sa.end(); iter++) - // { - // std::cout << iter->first << " " << iter->second << std::endl; - // } - - // } - // std::cout << "app value end" << std::endl; - auto const it_mimes = global.find("mimes"); - if (global.cend() != it_mimes) - { + if (global.cend() != it_mimes) { this->parseMimes(it_mimes->second, mimes_types); - //std::cout << "parse mimes end" << std::endl; - } - else - { + } else { std::cout << "Warning: mime types file is not set in configuration;" << std::endl; } - if (!applications.empty()) + if (applications.empty() == false) { auto const it_default_temp_dir = global.find("default_temp_dir"); @@ -800,19 +698,15 @@ namespace HttpServer default_request_max_size }; - for (auto const &app : applications) - { + for (auto const &app : applications) { this->addApplication(app, defaults, modules, apps_tree); - std::cout << "addApplication end" << std::endl; } } - if (apps_tree.empty() ) - { + if (apps_tree.empty() ) { std::cout << "Notice: server does not contain applications;" << std::endl; } - //std::cout << "out loadCofig" << std::endl; - return iStatus == 1; + return true; } -}; +} diff --git a/src/server/config/ConfigParser.h b/src/server/config/ConfigParser.h index c501d5d..f7805dc 100644 --- a/src/server/config/ConfigParser.h +++ b/src/server/config/ConfigParser.h @@ -6,22 +6,7 @@ #include namespace HttpServer -{ - enum ConfigFileDataState - { - CONFIGFILEDATASNONE = 0, - CONFIGFILEDATASNOTE, //comment - CONFIGFILEDATASTYPE, - //CONFIGFILEDATAGLOBAL, - CONFIGFILEDATAINBLOCK, //in block - }; - enum InBlockDataState - { - INBLOCKNONE, //in block none - INBLOCKNOTE, //in block note - INBLOCKTPYE, //in block type - }; - +{ class ConfigParser { private: @@ -45,4 +30,4 @@ namespace HttpServer public: bool loadConfig(const std::string &conf, ServerSettings &settings, std::vector &modules); }; -}; +} From b04b1a7e74b0116b32112b9c8eb308973b49ae07 Mon Sep 17 00:00:00 2001 From: awwit Date: Sat, 31 Mar 2018 22:31:40 +0300 Subject: [PATCH 3/7] Fixed endless looping when TLS-handshake. Added http/1.1 as default protocol for non-ALPN tls connections. Fixed many warnings in code. Changed code style. --- projects/qt-creator/httpserver.qbs | 4 +- src/Main.cpp | 21 +- src/SignalHandlers.cpp | 30 +- src/server/Request.cpp | 2 +- src/server/Request.h | 8 +- src/server/Server.cpp | 239 +++++++---- src/server/Server.h | 34 +- src/server/ServerApplicationSettings.h | 2 +- src/server/ServerApplicationsTree.cpp | 58 +-- src/server/ServerApplicationsTree.h | 2 +- src/server/ServerControls.cpp | 39 +- src/server/ServerControls.h | 2 +- src/server/ServerSettings.cpp | 26 +- src/server/ServerSettings.h | 2 +- src/server/ServerStructuresArguments.h | 2 +- src/server/SocketsQueue.h | 2 +- src/server/config/ConfigParser.cpp | 160 ++++--- src/server/config/ConfigParser.h | 20 +- src/server/data-variant/Abstract.cpp | 16 +- src/server/data-variant/Abstract.h | 14 +- src/server/data-variant/FormUrlencoded.cpp | 57 ++- src/server/data-variant/FormUrlencoded.h | 2 +- src/server/data-variant/MultipartFormData.cpp | 194 +++++---- src/server/data-variant/MultipartFormData.h | 13 +- src/server/data-variant/TextPlain.cpp | 50 ++- src/server/data-variant/TextPlain.h | 2 +- src/server/protocol/ServerHttp1.cpp | 390 ++++++++++------- src/server/protocol/ServerHttp1.h | 53 ++- src/server/protocol/ServerHttp2.cpp | 400 ++++++++++++------ src/server/protocol/ServerHttp2.h | 7 +- src/server/protocol/ServerHttp2Protocol.cpp | 130 ++++-- src/server/protocol/ServerHttp2Protocol.h | 35 +- src/server/protocol/ServerHttp2Stream.cpp | 52 ++- src/server/protocol/ServerHttp2Stream.h | 9 +- src/server/protocol/ServerProtocol.cpp | 115 +++-- src/server/protocol/ServerProtocol.h | 48 ++- src/server/protocol/ServerWebSocket.cpp | 45 +- src/server/protocol/ServerWebSocket.h | 36 +- src/server/protocol/extensions/Sendfile.cpp | 249 +++++++---- src/server/protocol/extensions/Sendfile.h | 2 +- src/socket/Adapter.cpp | 22 +- src/socket/Adapter.h | 26 +- src/socket/AdapterDefault.cpp | 16 +- src/socket/AdapterDefault.h | 13 +- src/socket/AdapterTls.cpp | 42 +- src/socket/AdapterTls.h | 28 +- src/socket/List.cpp | 114 +++-- src/socket/List.h | 18 +- src/socket/Socket.cpp | 272 ++++++++---- src/socket/Socket.h | 43 +- src/system/GlobalMutex.cpp | 57 +-- src/system/GlobalMutex.h | 4 +- src/system/Module.cpp | 94 ++-- src/system/Module.h | 15 +- src/system/SharedMemory.cpp | 109 +++-- src/system/SharedMemory.h | 23 +- src/system/System.cpp | 53 ++- src/system/System.h | 40 +- src/transfer/AppRequest.h | 6 +- src/transfer/AppResponse.h | 3 +- src/transfer/FileIncoming.cpp | 47 +- src/transfer/FileIncoming.h | 19 +- src/transfer/HttpStatusCode.h | 3 +- src/transfer/ProtocolVariant.h | 3 +- src/transfer/http2/HPack.cpp | 258 +++++++---- src/transfer/http2/HPack.h | 12 +- src/transfer/http2/Http2.cpp | 115 +++-- src/transfer/http2/Http2.h | 79 ++-- src/utils/Event.cpp | 9 +- src/utils/Utils.cpp | 136 ++++-- src/utils/Utils.h | 5 +- 71 files changed, 2803 insertions(+), 1453 deletions(-) diff --git a/projects/qt-creator/httpserver.qbs b/projects/qt-creator/httpserver.qbs index 464d956..20d1f24 100644 --- a/projects/qt-creator/httpserver.qbs +++ b/projects/qt-creator/httpserver.qbs @@ -12,12 +12,12 @@ Project { Properties { condition: qbs.targetOS.contains("linux") - cpp.platformDefines: outer.concat(["POSIX"]) + cpp.defines: outer.concat(["POSIX"]) cpp.dynamicLibraries: outer.concat(["dl", "pthread", "rt"]) } Properties { condition: qbs.targetOS.contains("windows") - cpp.platformDefines: outer.concat(["WIN32", "NOMINMAX"]) + cpp.defines: outer.concat(["WIN32", "NOMINMAX"]) } files: [ diff --git a/src/Main.cpp b/src/Main.cpp index d3d341d..8aa2a4b 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -17,32 +17,23 @@ int main(const int argc, const char *argv[]) int exitcode = EXIT_FAILURE; - if (1 < argc) - { + if (1 < argc) { auto const command = commands.find(argv[1]); - if (commands.cend() != command) - { + if (commands.cend() != command) { HttpServer::Server server; - if (bindSignalHandlers(&server) ) - { + if (bindSignalHandlers(&server) ) { exitcode = command->second(&server, argc, argv); - stopSignalHandlers(); } - } - else - { + } else { std::cout << "Unknown parameter, see --help" << std::endl; } } - else if (1 == argc) - { + else if (1 == argc) { std::cout << "Try to run with the parameter --help" << std::endl; - } - else - { + } else { std::cout << "The number of arguments cannot be equal to zero. Enter the parameter --help" << std::endl; } diff --git a/src/SignalHandlers.cpp b/src/SignalHandlers.cpp index 80bbc7d..cad0155 100644 --- a/src/SignalHandlers.cpp +++ b/src/SignalHandlers.cpp @@ -56,8 +56,12 @@ static void handlerSigUsr2(const int) noexcept { * It doesn't work in case the program was launched and was * attempted to finish under different remote sessions. */ -static ::LRESULT CALLBACK WndProc(const ::HWND hWnd, const ::UINT message, const ::WPARAM wParam, const ::LPARAM lParam) noexcept -{ +static ::LRESULT CALLBACK WndProc( + const ::HWND hWnd, + const ::UINT message, + const ::WPARAM wParam, + const ::LPARAM lParam +) noexcept { switch (message) { case SIGTERM: { @@ -105,9 +109,23 @@ static ::LRESULT CALLBACK WndProc(const ::HWND hWnd, const ::UINT message, const return 0; } -static ::WPARAM mainMessageLoop(const ::HINSTANCE hInstance, Utils::Event * const eventWindowCreation) noexcept -{ - const ::HWND hWnd = ::CreateWindow(myWndClassName, nullptr, 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, nullptr, nullptr, hInstance, nullptr); +static ::WPARAM mainMessageLoop( + const ::HINSTANCE hInstance, + Utils::Event * const eventWindowCreation +) noexcept { + const ::HWND hWnd = ::CreateWindow( + myWndClassName, + nullptr, + 0, + CW_USEDEFAULT, + CW_USEDEFAULT, + 0, + 0, + nullptr, + nullptr, + hInstance, + nullptr + ); eventWindowCreation->notify(); // After this action, eventWindowCreation will be destroyed (in the other thread) @@ -207,7 +225,7 @@ bool bindSignalHandlers(HttpServer::Server *server) noexcept ::signal(SIGPIPE, SIG_IGN); #else - #error "Undefine platform" + #error "Undefined platform" #endif return true; diff --git a/src/server/Request.cpp b/src/server/Request.cpp index f8bfcea..17ca269 100644 --- a/src/server/Request.cpp +++ b/src/server/Request.cpp @@ -17,4 +17,4 @@ namespace HttpServer // timeout = std::chrono::milliseconds::zero(); } -}; +} diff --git a/src/server/Request.h b/src/server/Request.h index dd2b5d5..abc8de0 100644 --- a/src/server/Request.h +++ b/src/server/Request.h @@ -8,8 +8,7 @@ namespace HttpServer { - enum ConnectionParams - { + enum ConnectionParams { CONNECTION_CLOSE = 0, CONNECTION_REUSE = 1, CONNECTION_LEAVE_OPEN = 2 @@ -36,9 +35,8 @@ namespace HttpServer void clear() noexcept; }; - struct DataTransfer - { + struct DataTransfer { size_t full_size; size_t send_total; }; -}; +} diff --git a/src/server/Server.cpp b/src/server/Server.cpp index 3f87c92..df464eb 100644 --- a/src/server/Server.cpp +++ b/src/server/Server.cpp @@ -33,8 +33,7 @@ namespace HttpServer ServerControls &controls, SocketsQueue &sockets, Http2::IncStream *stream - ) - { + ) { std::unique_ptr prot; // If request is HTTP/2 Stream @@ -43,11 +42,13 @@ namespace HttpServer return prot; } - if (sock.get_tls_session() ) + if (sock.get_tls_session() != nullptr) { ::gnutls_datum_t datum; - if (0 == ::gnutls_alpn_get_selected_protocol(sock.get_tls_session(), &datum) ) + const int ret = ::gnutls_alpn_get_selected_protocol(sock.get_tls_session(), &datum); + + if (GNUTLS_E_SUCCESS == ret) { const std::string protocol(reinterpret_cast(datum.data), datum.size); @@ -58,6 +59,9 @@ namespace HttpServer prot.reset(new ServerHttp1(sock, settings, controls) ); } } + else if (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE == ret) { + prot.reset(new ServerHttp1(sock, settings, controls) ); + } return prot; } @@ -70,9 +74,18 @@ namespace HttpServer /** * Метод для обработки запроса */ - void Server::threadRequestProc(Socket::Adapter &sock, SocketsQueue &sockets, Http2::IncStream *stream) const - { - std::unique_ptr prot = getProtocolVariant(sock, this->settings, this->controls, sockets, stream); + void Server::threadRequestProc( + Socket::Adapter &sock, + SocketsQueue &sockets, + Http2::IncStream *stream + ) const { + std::unique_ptr prot = getProtocolVariant( + sock, + this->settings, + this->controls, + sockets, + stream + ); if (prot) { // Check if switching protocol @@ -94,8 +107,10 @@ namespace HttpServer * Метод для обработки запросов (запускается в отдельном потоке) * извлекает сокет клиенты из очереди и передаёт его на обслуживание */ - void Server::threadRequestCycle(SocketsQueue &sockets, Utils::Event &eventThreadCycle) const - { + void Server::threadRequestCycle( + SocketsQueue &sockets, + Utils::Event &eventThreadCycle + ) const { while (true) { Socket::Socket sock; @@ -114,7 +129,11 @@ namespace HttpServer /* sockaddr_in addr {}; socklen_t addr_size = sizeof(sockaddr_in); - ::getpeername(sock.get_handle(), reinterpret_cast(&addr), &addr_size); + ::getpeername( + sock.get_handle(), + reinterpret_cast(&addr), + &addr_size + ); */ sockets.pop(); } @@ -133,7 +152,11 @@ namespace HttpServer ::sockaddr_in sock_addr {}; ::socklen_t sock_addr_len = sizeof(sock_addr); - ::getsockname(sock.get_handle(), reinterpret_cast(&sock_addr), &sock_addr_len); + ::getsockname( + sock.get_handle(), + reinterpret_cast(&sock_addr), + &sock_addr_len + ); const int port = ntohs(sock_addr.sin_port); @@ -141,14 +164,17 @@ namespace HttpServer if (this->tls_data.cend() != it) // if TLS connection { - if (stream) - { - Socket::AdapterTls socket_adapter(reinterpret_cast(stream->reserved) ); + if (stream) { + Socket::AdapterTls socket_adapter( + reinterpret_cast(stream->reserved) + ); - this->threadRequestProc(socket_adapter, sockets, stream); - } - else - { + this->threadRequestProc( + socket_adapter, + sockets, + stream + ); + } else { const std::tuple &data = it->second; Socket::AdapterTls socket_adapter( @@ -158,15 +184,21 @@ namespace HttpServer ); if (socket_adapter.handshake() ) { - this->threadRequestProc(socket_adapter, sockets, nullptr); + this->threadRequestProc( + socket_adapter, + sockets, + nullptr + ); } } - } - else - { + } else { Socket::AdapterDefault socket_adapter(sock); - this->threadRequestProc(socket_adapter, sockets, stream); + this->threadRequestProc( + socket_adapter, + sockets, + stream + ); } --this->threads_working_count; @@ -202,8 +234,9 @@ namespace HttpServer Utils::Event eventThreadCycle(false, true); - std::function serverThreadRequestCycle - = std::mem_fn(&Server::threadRequestCycle); + std::function serverThreadRequestCycle = std::mem_fn(&Server::threadRequestCycle); std::vector active_threads; active_threads.reserve(threads_max_count); @@ -216,9 +249,17 @@ namespace HttpServer // Cycle creation threads applications requests do { - while (this->threads_working_count == active_threads.size() && active_threads.size() < threads_max_count && sockets.empty() == false) - { - active_threads.emplace_back(serverThreadRequestCycle, this, std::ref(sockets), std::ref(eventThreadCycle) ); + while ( + this->threads_working_count == active_threads.size() && + active_threads.size() < threads_max_count && + sockets.empty() == false + ) { + active_threads.emplace_back( + serverThreadRequestCycle, + this, + std::ref(sockets), + std::ref(eventThreadCycle) + ); } size_t notify_count = active_threads.size() - this->threads_working_count; @@ -253,8 +294,11 @@ namespace HttpServer return 0; } - bool Server::updateModule(System::Module &module, std::unordered_set &applications, const size_t moduleIndex) - { + bool Server::updateModule( + System::Module &module, + std::unordered_set &applications, + const size_t moduleIndex + ) { std::unordered_set same; for (auto &app : applications) @@ -270,7 +314,8 @@ namespace HttpServer } } catch (std::exception &exc) { - std::cout << "Warning: an exception was thrown when the application '" << app->server_module << "' was finishes: " << exc.what() << std::endl; + std::cout << "Warning: an exception was thrown when the application '" + << app->server_module << "' was finishes: " << exc.what() << std::endl; } app->application_call = std::function(); @@ -347,12 +392,12 @@ namespace HttpServer // Open updated module module.open(module_name_temp); - if (0 != std::remove(module_name.c_str() ) ) { + if (std::remove(module_name.c_str() ) != 0) { std::cout << "Error: file '" << module_name << "' could not be removed;" << std::endl; return false; } - if (0 != std::rename(module_name_temp.c_str(), module_name.c_str() ) ) { + if (std::rename(module_name_temp.c_str(), module_name.c_str() ) != 0) { std::cout << "Error: file '" << module_name_temp << "' could not be renamed;" << std::endl; return false; } @@ -372,7 +417,11 @@ namespace HttpServer return false; } - std::function app_call = reinterpret_cast(addr); + std::function app_call = reinterpret_cast(addr); if ( ! app_call) { std::cout << "Error: invalid function 'application_call' is in the module '" << module_name << "';" << std::endl; @@ -511,48 +560,67 @@ namespace HttpServer Socket::Socket::Cleanup(); } - static bool tlsInit(const ServerApplicationSettings &app, std::tuple &data) - { + static bool tlsInit( + const ServerApplicationSettings &app, + std::tuple &data + ) { ::gnutls_certificate_credentials_t x509_cred; int ret = ::gnutls_certificate_allocate_credentials(&x509_cred); if (ret < 0) { - std::cout << "Error [tls]: certificate credentials has not been allocated;" << std::endl; + std::cout << "Error [tls]: certificate credentials has not been allocated; code: " << ret << std::endl; return false; } if (app.chain_file.empty() == false) { - ret = ::gnutls_certificate_set_x509_trust_file(x509_cred, app.chain_file.c_str(), GNUTLS_X509_FMT_PEM); + ret = ::gnutls_certificate_set_x509_trust_file( + x509_cred, + app.chain_file.c_str(), + GNUTLS_X509_FMT_PEM + ); if (ret < 0) { - std::cout << "Warning [tls]: (CA) chain file has not been accepted;" << std::endl; + std::cout << "Warning [tls]: (CA) chain file has not been accepted; code: " << ret << std::endl; } } if (app.crl_file.empty() == false) { - ret = ::gnutls_certificate_set_x509_crl_file(x509_cred, app.crl_file.c_str(), GNUTLS_X509_FMT_PEM); + ret = ::gnutls_certificate_set_x509_crl_file( + x509_cred, + app.crl_file.c_str(), + GNUTLS_X509_FMT_PEM + ); if (ret < 0) { - std::cout << "Warning [tls]: (CLR) clr file has not been accepted;" << std::endl; + std::cout << "Warning [tls]: (CLR) clr file has not been accepted; code: " << ret << std::endl; } } - ret = ::gnutls_certificate_set_x509_key_file(x509_cred, app.cert_file.c_str(), app.key_file.c_str(), GNUTLS_X509_FMT_PEM); + ret = ::gnutls_certificate_set_x509_key_file( + x509_cred, + app.cert_file.c_str(), + app.key_file.c_str(), + GNUTLS_X509_FMT_PEM + ); if (ret < 0) { - std::cout << "Error [tls]: (CERT) cert file or/and (KEY) key file has not been accepted;" << std::endl; + std::cout << "Error [tls]: (CERT) cert file or/and (KEY) key file has not been accepted; code: " << ret << std::endl; return false; } if (app.stapling_file.empty() == false) { - ret = ::gnutls_certificate_set_ocsp_status_request_file(x509_cred, app.stapling_file.c_str(), 0); + ret = ::gnutls_certificate_set_ocsp_status_request_file( + x509_cred, + app.stapling_file.c_str(), + 0 + ); if (ret < 0) { - std::cout << "Warning [tls]: (OCSP) stapling file has not been accepted;" << std::endl; + std::cout << "Warning [tls]: (OCSP) stapling file has not been accepted; code: " << ret << std::endl; } } @@ -560,35 +628,40 @@ namespace HttpServer ::gnutls_dh_params_init(&dh_params); - if (app.dh_file.empty() ) - { - const unsigned int bits = ::gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_HIGH); + if (app.dh_file.empty() ) { + const unsigned int bits = ::gnutls_sec_param_to_pk_bits( + GNUTLS_PK_DH, GNUTLS_SEC_PARAM_HIGH + ); - ret = ::gnutls_dh_params_generate2(dh_params, bits); - } - else - { + ret = ::gnutls_dh_params_generate2( + dh_params, + bits + ); + } else { std::ifstream dh_file(app.dh_file); - if (dh_file) - { + if (dh_file) { const size_t max_file_size = 1024 * 1024; std::vector buf(max_file_size); - dh_file.read(buf.data(), buf.size() ); + dh_file.read( + buf.data(), + std::streamsize(buf.size()) + ); gnutls_datum_t datum { reinterpret_cast(buf.data() ), static_cast(dh_file.gcount() ) }; - ret = ::gnutls_dh_params_import_pkcs3(dh_params, &datum, GNUTLS_X509_FMT_PEM); - } - else - { + ret = ::gnutls_dh_params_import_pkcs3( + dh_params, + &datum, + GNUTLS_X509_FMT_PEM + ); + } else { ret = -1; - std::cout << "Error [tls]: DH params file has not been opened;" << std::endl;; } @@ -597,7 +670,7 @@ namespace HttpServer if (ret < 0) { ::gnutls_certificate_free_credentials(x509_cred); - std::cout << "Error [tls]: DH params were not loaded;" << std::endl; + std::cout << "Error [tls]: DH params were not loaded; code: " << ret << std::endl; return false; } @@ -609,17 +682,22 @@ namespace HttpServer if (ret < 0) { ::gnutls_certificate_free_credentials(x509_cred); - std::cout << "Error [tls]: priority cache cannot be init;" << std::endl; + std::cout << "Error [tls]: priority cache cannot be init; code: " << ret << std::endl; return false; } - data = std::tuple { x509_cred, priority_cache }; + data = std::tuple { + x509_cred, + priority_cache + }; return true; } - bool Server::tryBindPort(const int port, std::unordered_set &ports) - { + bool Server::tryBindPort( + const int port, + std::unordered_set &ports + ) { // Only unique ports if (ports.cend() != ports.find(port) ) { return false; @@ -726,16 +804,13 @@ namespace HttpServer // Cycle for receiving new connections do { - if (sockets_list.accept(accept_sockets) ) - { + if (sockets_list.accept(accept_sockets) ) { sockets.lock(); - for (size_t i = 0; i < accept_sockets.size(); ++i) - { + for (size_t i = 0; i < accept_sockets.size(); ++i) { const Socket::Socket &sock = accept_sockets[i]; - if (sock.is_open() ) - { + if (sock.is_open() ) { sock.nonblock(true); sock.tcp_nodelay(true); @@ -784,8 +859,11 @@ namespace HttpServer return EXIT_SUCCESS; } - bool Server::get_start_args(const int argc, const char *argv[], struct server_start_args *st) - { + bool Server::get_start_args( + const int argc, + const char *argv[], + struct server_start_args *st + ) { for (int i = 1; i < argc; ++i) { if (0 == ::strcmp(argv[i], "--start") ) { @@ -904,30 +982,26 @@ namespace HttpServer return code; } - static void close_liseners(std::vector &liseners) - { + static void close_liseners(std::vector &liseners) { for (auto &sock : liseners) { sock.close(); } } - void Server::stop() - { + void Server::stop() { this->controls.stopProcess(); close_liseners(this->liseners); } - void Server::restart() - { + void Server::restart() { this->controls.setRestart(); this->controls.stopProcess(); close_liseners(this->liseners); } - void Server::update() - { + void Server::update() { this->controls.setUpdateModule(); this->controls.setProcess(false); this->controls.setProcessQueue(); @@ -939,8 +1013,7 @@ namespace HttpServer System::GlobalMutex glob_mtx; - if (glob_mtx.open(serverName) ) - { + if (glob_mtx.open(serverName) ) { System::SharedMemory glob_mem; glob_mtx.lock(); diff --git a/src/server/Server.h b/src/server/Server.h index e09984a..f8ca243 100644 --- a/src/server/Server.h +++ b/src/server/Server.h @@ -31,11 +31,22 @@ namespace HttpServer protected: int cycleQueue(SocketsQueue &sockets); - void threadRequestProc(Socket::Adapter &sock, SocketsQueue &sockets, Http2::IncStream *stream) const; + void threadRequestProc( + Socket::Adapter &sock, + SocketsQueue &sockets, + Http2::IncStream *stream + ) const; + + void threadRequestCycle( + SocketsQueue &sockets, + Utils::Event &eventThreadCycle + ) const; + + bool tryBindPort( + const int port, + std::unordered_set &ports + ); - void threadRequestCycle(SocketsQueue &sockets, Utils::Event &eventThreadCycle) const; - - bool tryBindPort(const int port, std::unordered_set &ports); void initAppsPorts(); bool init(); @@ -45,10 +56,19 @@ namespace HttpServer static System::native_processid_type getServerProcessId(const std::string &serverName); void updateModules(); - bool updateModule(System::Module &module, std::unordered_set &applications, const size_t moduleIndex); + + bool updateModule( + System::Module &module, + std::unordered_set &applications, + const size_t moduleIndex + ); private: - static bool get_start_args(const int argc, const char *argv[], struct server_start_args *st); + static bool get_start_args( + const int argc, + const char *argv[], + struct server_start_args *st + ); public: Server() = default; @@ -63,4 +83,4 @@ namespace HttpServer int command_terminate(const int argc, const char *argv[]) const; int command_update_module(const int argc, const char *argv[]) const; }; -}; +} diff --git a/src/server/ServerApplicationSettings.h b/src/server/ServerApplicationSettings.h index b1bd9d6..ca70896 100644 --- a/src/server/ServerApplicationSettings.h +++ b/src/server/ServerApplicationSettings.h @@ -34,4 +34,4 @@ namespace HttpServer std::function application_init; std::function application_final; }; -}; +} diff --git a/src/server/ServerApplicationsTree.cpp b/src/server/ServerApplicationsTree.cpp index 250e432..3e73586 100644 --- a/src/server/ServerApplicationsTree.cpp +++ b/src/server/ServerApplicationsTree.cpp @@ -8,13 +8,11 @@ namespace HttpServer } - ServerApplicationsTree::~ServerApplicationsTree() noexcept - { + ServerApplicationsTree::~ServerApplicationsTree() noexcept { this->clear(); } - bool ServerApplicationsTree::empty() const noexcept - { + bool ServerApplicationsTree::empty() const noexcept { return this->list.empty(); } @@ -32,8 +30,7 @@ namespace HttpServer { std::string part = name.substr(cur_pos, delimiter - cur_pos); - if ("" == part) - { + if (part.empty() ) { part = "*"; } @@ -45,9 +42,7 @@ namespace HttpServer // Emplace last part std::string part = name.substr(cur_pos); name_parts.emplace_back(std::move(part) ); - } - else - { + } else { name_parts.emplace_back(name); } @@ -56,24 +51,18 @@ namespace HttpServer void ServerApplicationsTree::addApplication(std::vector &nameParts, ServerApplicationSettings *sets) { - if (nameParts.empty() ) - { + if (nameParts.empty() ) { this->app_sets = sets; - } - else - { + } else { std::string &part = nameParts.back(); auto it = this->list.find(part); ServerApplicationsTree *sub; - if (this->list.cend() != it) - { + if (this->list.cend() != it) { sub = it->second; - } - else - { + } else { sub = new ServerApplicationsTree(); this->list.emplace(std::move(part), sub); } @@ -104,9 +93,7 @@ namespace HttpServer std::string part = name.substr(cur_pos); name_parts.emplace_back(std::move(part) ); - } - else - { + } else { name_parts.emplace_back(name); } @@ -115,29 +102,22 @@ namespace HttpServer const ServerApplicationSettings *ServerApplicationsTree::find(std::vector &nameParts) const { - if (nameParts.empty() ) - { + if (nameParts.empty() ) { return this->app_sets; - } - else - { + } else { const std::string part = std::move(nameParts.back() ); nameParts.pop_back(); auto it = this->list.find(part); - if (this->list.cend() == it) - { + if (this->list.cend() == it) { it = this->list.find("*"); - if (this->list.end() != it) - { + if (this->list.end() != it) { return this->app_sets; } - } - else - { + } else { return it->second->find(nameParts); } @@ -151,8 +131,7 @@ namespace HttpServer { const ServerApplicationsTree *tree = node.second; - if (nullptr != tree->app_sets) - { + if (nullptr != tree->app_sets) { set.emplace(tree->app_sets); } @@ -162,14 +141,13 @@ namespace HttpServer void ServerApplicationsTree::clear() noexcept { - if (false == this->list.empty() ) + if (this->list.empty() == false) { - for (auto &it : this->list) - { + for (auto &it : this->list) { delete it.second; } this->list.clear(); } } -}; +} diff --git a/src/server/ServerApplicationsTree.h b/src/server/ServerApplicationsTree.h index 6fe2b24..6f4b54f 100644 --- a/src/server/ServerApplicationsTree.h +++ b/src/server/ServerApplicationsTree.h @@ -31,4 +31,4 @@ namespace HttpServer void clear() noexcept; }; -}; +} diff --git a/src/server/ServerControls.cpp b/src/server/ServerControls.cpp index 6bc57ed..23fd576 100644 --- a/src/server/ServerControls.cpp +++ b/src/server/ServerControls.cpp @@ -4,39 +4,36 @@ namespace HttpServer { ServerControls::ServerControls() - : eventProcessQueue(nullptr), eventNotFullQueue(nullptr), eventUpdateModule(nullptr) + : eventProcessQueue(nullptr), + eventNotFullQueue(nullptr), + eventUpdateModule(nullptr) { } - ServerControls::~ServerControls() - { + ServerControls::~ServerControls() { this->clear(); } void ServerControls::clear() { - if (this->eventNotFullQueue) - { + if (this->eventNotFullQueue) { delete this->eventNotFullQueue; this->eventNotFullQueue = nullptr; } - if (this->eventProcessQueue) - { + if (this->eventProcessQueue) { delete this->eventProcessQueue; this->eventProcessQueue = nullptr; } - if (this->eventUpdateModule) - { + if (this->eventUpdateModule) { delete this->eventUpdateModule; this->eventUpdateModule = nullptr; } } - void ServerControls::setProcess(const bool flag) - { + void ServerControls::setProcess(const bool flag) { this->process_flag = flag; } @@ -44,32 +41,26 @@ namespace HttpServer { this->process_flag = false; - if (this->eventNotFullQueue) - { + if (this->eventNotFullQueue) { this->eventNotFullQueue->notify(); } this->setProcessQueue(); } - void ServerControls::setRestart(const bool flag) - { + void ServerControls::setRestart(const bool flag) { this->restart_flag = flag; } - void ServerControls::setUpdateModule() - { - if (this->eventUpdateModule) - { + void ServerControls::setUpdateModule() { + if (this->eventUpdateModule) { this->eventUpdateModule->notify(); } } - void ServerControls::setProcessQueue() - { - if (this->eventProcessQueue) - { + void ServerControls::setProcessQueue() { + if (this->eventProcessQueue) { this->eventProcessQueue->notify(); } } -}; +} diff --git a/src/server/ServerControls.h b/src/server/ServerControls.h index ab811f0..b438111 100644 --- a/src/server/ServerControls.h +++ b/src/server/ServerControls.h @@ -34,4 +34,4 @@ namespace HttpServer void setUpdateModule(); void setProcessQueue(); }; -}; +} diff --git a/src/server/ServerSettings.cpp b/src/server/ServerSettings.cpp index 166f2dc..3677a62 100644 --- a/src/server/ServerSettings.cpp +++ b/src/server/ServerSettings.cpp @@ -5,29 +5,29 @@ namespace HttpServer { - ServerSettings::~ServerSettings() - { + ServerSettings::~ServerSettings() { this->clear(); } - void ServerSettings::addDataVariant(DataVariant::Abstract *dataVariant) - { - this->variants.emplace(dataVariant->getName(), dataVariant); + void ServerSettings::addDataVariant(DataVariant::Abstract *dataVariant) { + this->variants.emplace( + dataVariant->getName(), + dataVariant + ); } void ServerSettings::clear() { - if (false == this->variants.empty() ) + if (this->variants.empty() == false) { - for (auto &variant : this->variants) - { + for (auto &variant : this->variants) { delete variant.second; } this->variants.clear(); } - if (false == this->apps_tree.empty() ) + if (this->apps_tree.empty() == false) { std::unordered_set applications; this->apps_tree.collectApplicationSettings(applications); @@ -36,8 +36,7 @@ namespace HttpServer { try { - if (app->application_final) - { + if (app->application_final) { const std::string root = app->root_dir; app->application_final(root.data() ); } @@ -54,9 +53,8 @@ namespace HttpServer this->apps_tree.clear(); } - if (false == this->global.empty() ) - { + if (this->global.empty() == false) { this->global.clear(); } } -}; +} diff --git a/src/server/ServerSettings.h b/src/server/ServerSettings.h index 2ef64a2..221a466 100644 --- a/src/server/ServerSettings.h +++ b/src/server/ServerSettings.h @@ -22,4 +22,4 @@ namespace HttpServer void clear(); }; -}; +} diff --git a/src/server/ServerStructuresArguments.h b/src/server/ServerStructuresArguments.h index 0e10b8b..d00e8be 100644 --- a/src/server/ServerStructuresArguments.h +++ b/src/server/ServerStructuresArguments.h @@ -10,4 +10,4 @@ namespace HttpServer std::string config_path; bool force; }; -}; +} diff --git a/src/server/SocketsQueue.h b/src/server/SocketsQueue.h index ff6ec83..2473ee4 100644 --- a/src/server/SocketsQueue.h +++ b/src/server/SocketsQueue.h @@ -17,4 +17,4 @@ namespace HttpServer { }; -}; +} diff --git a/src/server/config/ConfigParser.cpp b/src/server/config/ConfigParser.cpp index 20ed3e0..1bbb42a 100644 --- a/src/server/config/ConfigParser.cpp +++ b/src/server/config/ConfigParser.cpp @@ -25,8 +25,11 @@ namespace HttpServer /** * Config - include file */ - bool ConfigParser::includeConfigFile(const std::string &fileName, std::string &strBuf, const std::size_t offset) - { + bool ConfigParser::includeConfigFile( + const std::string &fileName, + std::string &strBuf, + const std::size_t offset + ) { std::ifstream file(fileName); if ( ! file) { @@ -51,7 +54,11 @@ namespace HttpServer std::vector buf(file_size); file.read(buf.data(), file_size); - strBuf.insert(strBuf.begin() + offset, buf.cbegin(), buf.cend() ); + strBuf.insert( + strBuf.begin() + long(offset), + buf.cbegin(), + buf.cend() + ); } file.close(); @@ -63,12 +70,11 @@ namespace HttpServer * Config - add application */ bool ConfigParser::addApplication( - const std::unordered_multimap &app, - const ServerApplicationDefaultSettings &defaults, - std::vector &modules, - ServerApplicationsTree &apps_tree - ) - { + const std::unordered_multimap &app, + const ServerApplicationDefaultSettings &defaults, + std::vector &modules, + ServerApplicationsTree &apps_tree + ) { auto const it_name = app.find("server_name"); if (app.cend() == it_name) { @@ -84,16 +90,26 @@ namespace HttpServer size_t delimiter = app_name.find_first_of(whitespace); - if (delimiter) - { + if (delimiter) { size_t cur_pos = 0; - while (std::string::npos != delimiter) - { - std::string name = app_name.substr(cur_pos, delimiter - cur_pos); + while (std::string::npos != delimiter) { + std::string name = app_name.substr( + cur_pos, + delimiter - cur_pos + ); + names.emplace_back(std::move(name) ); - cur_pos = app_name.find_first_not_of(whitespace, delimiter + 1); - delimiter = app_name.find_first_of(whitespace, cur_pos); + + cur_pos = app_name.find_first_not_of( + whitespace, + delimiter + 1 + ); + + delimiter = app_name.find_first_of( + whitespace, + cur_pos + ); } std::string name = app_name.substr(cur_pos); @@ -102,8 +118,7 @@ namespace HttpServer auto const range_port = app.equal_range("listen"); - if (range_port.first == range_port.second) - { + if (range_port.first == range_port.second) { std::cout << "Error: application port is not set;" << std::endl; return false; } @@ -121,7 +136,7 @@ namespace HttpServer for (auto const &value : list) { - const int port = std::strtol(value.c_str(), nullptr, 10); + const int port = std::atoi(value.c_str()); if (port) { if (is_tls) { @@ -215,7 +230,13 @@ namespace HttpServer return false; } - std::function app_call = reinterpret_cast(addr); + std::function app_call = reinterpret_cast(addr); if ( ! app_call) { std::cout << "Error: invalid function 'application_call' in module '" << it_module->second << "';" << std::endl; @@ -256,18 +277,14 @@ namespace HttpServer bool success = true; - try - { - if (app_init) - { + try { + if (app_init) { const std::string root = root_dir; success = app_init(root.data() ); } } - catch (std::exception &exc) - { + catch (std::exception &exc) { std::cout << "Warning: an exception was thrown when the application '" << it_module->second << "' was initialized: " << exc.what() << std::endl; - success = false; } @@ -278,23 +295,27 @@ namespace HttpServer auto const it_temp_dir = app.find("temp_dir"); - std::string temp_dir = app.cend() != it_temp_dir ? it_temp_dir->second : defaults.temp_dir; + std::string temp_dir = app.cend() != it_temp_dir + ? it_temp_dir->second + : defaults.temp_dir; auto const it_request_max_size = app.find("request_max_size"); - const size_t request_max_size = app.cend() != it_request_max_size ? std::strtoull(it_request_max_size->second.c_str(), nullptr, 10) : defaults.request_max_size; + const size_t request_max_size = app.cend() != it_request_max_size + ? std::strtoull(it_request_max_size->second.c_str(), nullptr, 10) + : defaults.request_max_size; auto const it_module_update = app.find("server_module_update"); - std::string module_update = app.cend() != it_module_update ? it_module_update->second : ""; + std::string module_update = app.cend() != it_module_update + ? it_module_update->second + : std::string(); // Calculate module index size_t module_index = std::numeric_limits::max(); - for (size_t i = 0; i < modules.size(); ++i) - { - if (modules[i] == module) - { + for (size_t i = 0; i < modules.size(); ++i) { + if (modules[i] == module) { module_index = i; break; } @@ -349,8 +370,10 @@ namespace HttpServer * @param mimes_types * @return bool */ - bool ConfigParser::parseMimes(const std::string &fileName, std::unordered_map &mimes_types) - { + bool ConfigParser::parseMimes( + const std::string &fileName, + std::unordered_map &mimes_types + ) { std::ifstream file(fileName); if ( ! file) { @@ -436,7 +459,10 @@ namespace HttpServer ); if (ext_unit.empty() == false) { - mimes_types.emplace(std::move(ext_unit), mime_type); + mimes_types.emplace( + std::move(ext_unit), + mime_type + ); } ext_pos = ext.find_first_not_of(whitespace, delimiter); @@ -446,7 +472,10 @@ namespace HttpServer } else { - mimes_types.emplace(std::move(ext), std::move(mime_type) ); + mimes_types.emplace( + std::move(ext), + std::move(mime_type) + ); } cur_pos = end_pos + 1; @@ -492,8 +521,11 @@ namespace HttpServer /** * Config - parse */ - bool ConfigParser::loadConfig(const std::string &conf_file_name, ServerSettings &settings, std::vector &modules) - { + bool ConfigParser::loadConfig( + const std::string &conf_file_name, + ServerSettings &settings, + std::vector &modules + ) { std::string str_buf; if (includeConfigFile(conf_file_name, str_buf) == false) { @@ -552,17 +584,20 @@ namespace HttpServer std::string param_value = str_buf.substr(cur_pos, delimiter - cur_pos); - if ("include" == param_name) - { - this->includeConfigFile(param_value, str_buf, end_pos + 1); - } - else - { - global.emplace(std::move(param_name), std::move(param_value) ); + if ("include" == param_name) { + this->includeConfigFile( + param_value, + str_buf, + end_pos + 1 + ); + } else { + global.emplace( + std::move(param_name), + std::move(param_value) + ); } - } - else // if comment line - { + } else { + // if comment line end_pos = str_buf.find_first_of("\r\n", cur_pos); } } @@ -622,19 +657,18 @@ namespace HttpServer std::string param_value = str_buf.substr(cur_pos, delimiter - cur_pos); - if ("include" == param_name) - { + if ("include" == param_name) { cur_pos = end_pos + 1; this->includeConfigFile(param_value, str_buf, cur_pos); block_end = findBlockEnd(str_buf, cur_pos); + } else { + app.emplace( + std::move(param_name), + std::move(param_value) + ); } - else - { - app.emplace(std::move(param_name), std::move(param_value) ); - } - } - else // if comment line - { + } else { + // if comment line end_pos = str_buf.find_first_of("\r\n", cur_pos); } } @@ -687,11 +721,15 @@ namespace HttpServer { auto const it_default_temp_dir = global.find("default_temp_dir"); - const std::string default_temp_dir = global.cend() != it_default_temp_dir ? it_default_temp_dir->second : System::getTempDir(); + const std::string default_temp_dir = global.cend() != it_default_temp_dir + ? it_default_temp_dir->second + : System::getTempDir(); auto const it_default_request_max_size = global.find("request_max_size"); - const size_t default_request_max_size = global.cend() != it_default_request_max_size ? std::strtoull(it_default_request_max_size->second.c_str(), nullptr, 10) : 0; + const size_t default_request_max_size = global.cend() != it_default_request_max_size + ? std::strtoull(it_default_request_max_size->second.c_str(), nullptr, 10) + : 0; ServerApplicationDefaultSettings defaults { default_temp_dir, diff --git a/src/server/config/ConfigParser.h b/src/server/config/ConfigParser.h index f7805dc..f994a00 100644 --- a/src/server/config/ConfigParser.h +++ b/src/server/config/ConfigParser.h @@ -10,13 +10,16 @@ namespace HttpServer class ConfigParser { private: - struct ServerApplicationDefaultSettings - { + struct ServerApplicationDefaultSettings { std::string temp_dir; size_t request_max_size; }; - static bool includeConfigFile(const std::string &fileName, std::string &strBuf, const size_t offset = 0); + static bool includeConfigFile( + const std::string &fileName, + std::string &strBuf, + const size_t offset = 0 + ); static bool addApplication( const std::unordered_multimap &app, @@ -25,9 +28,16 @@ namespace HttpServer ServerApplicationsTree &apps_tree ); - static bool parseMimes(const std::string &fileName, std::unordered_map &mimes_types); + static bool parseMimes( + const std::string &fileName, + std::unordered_map &mimes_types + ); public: - bool loadConfig(const std::string &conf, ServerSettings &settings, std::vector &modules); + bool loadConfig( + const std::string &conf, + ServerSettings &settings, + std::vector &modules + ); }; } diff --git a/src/server/data-variant/Abstract.cpp b/src/server/data-variant/Abstract.cpp index 5a13e4a..37d9744 100644 --- a/src/server/data-variant/Abstract.cpp +++ b/src/server/data-variant/Abstract.cpp @@ -3,18 +3,16 @@ namespace DataVariant { - const std::string &Abstract::getName() const noexcept - { + const std::string &Abstract::getName() const noexcept { return this->data_variant_name; } - void *Abstract::createStateStruct(const Transfer::request_data *rd, const std::unordered_map &contentParams) const - { + void *Abstract::createStateStruct( + const Transfer::request_data *rd, + const std::unordered_map &contentParams + ) const { return nullptr; } - void Abstract::destroyStateStruct(void *st) const noexcept - { - - } -}; + void Abstract::destroyStateStruct(void *st) const noexcept {} +} diff --git a/src/server/data-variant/Abstract.h b/src/server/data-variant/Abstract.h index 0ec2e0a..f9f239c 100644 --- a/src/server/data-variant/Abstract.h +++ b/src/server/data-variant/Abstract.h @@ -17,13 +17,19 @@ namespace DataVariant public: /** - * virtual destructor + * Virtual destructor */ virtual ~Abstract() noexcept = default; - virtual void *createStateStruct(const Transfer::request_data *rd, const std::unordered_map &contentParams) const; + virtual void *createStateStruct( + const Transfer::request_data *rd, + const std::unordered_map &contentParams + ) const; - virtual bool parse(const std::string &buf, Transfer::request_data *rd, DataReceiver *dr) const = 0; + virtual bool parse( + const std::string &buf, + Transfer::request_data *rd, DataReceiver *dr + ) const = 0; virtual void destroyStateStruct(void *st) const noexcept; }; @@ -37,4 +43,4 @@ namespace DataVariant size_t left; void *reserved; }; -}; +} diff --git a/src/server/data-variant/FormUrlencoded.cpp b/src/server/data-variant/FormUrlencoded.cpp index 5535b14..08f8180 100644 --- a/src/server/data-variant/FormUrlencoded.cpp +++ b/src/server/data-variant/FormUrlencoded.cpp @@ -5,29 +5,27 @@ namespace DataVariant { - FormUrlencoded::FormUrlencoded() noexcept - { + FormUrlencoded::FormUrlencoded() noexcept { this->data_variant_name = "application/x-www-form-urlencoded"; } bool FormUrlencoded::parse(const std::string &buf, Transfer::request_data *rd, DataReceiver *dr) const { - if (buf.empty() ) - { + if (buf.empty() ) { return 0 == dr->full_size || dr->full_size != dr->recv_total; } - for (size_t var_pos = 0, var_end = 0; std::string::npos != var_end; var_pos = var_end + 1) - { + for ( + size_t var_pos = 0, var_end = 0; + std::string::npos != var_end; + var_pos = var_end + 1 + ) { // Поиск следующего параметра var_end = buf.find('&', var_pos); - if (std::string::npos == var_end) - { - if (dr->full_size != dr->recv_total) - { + if (std::string::npos == var_end) { + if (dr->full_size != dr->recv_total) { dr->left = buf.size() - var_pos; - return true; } } @@ -38,26 +36,51 @@ namespace DataVariant if (delimiter >= var_end) { // Получить имя параметра - std::string var_name = Utils::urlDecode(buf.substr(var_pos, std::string::npos != var_end ? var_end - var_pos : std::string::npos) ); + std::string var_name = Utils::urlDecode( + buf.substr( + var_pos, + std::string::npos != var_end + ? var_end - var_pos + : std::string::npos + ) + ); // Сохранить параметр с пустым значением - rd->incoming_data.emplace(std::move(var_name), std::string() ); + rd->incoming_data.emplace( + std::move(var_name), + std::string() + ); } else { // Получить имя параметра - std::string var_name = Utils::urlDecode(buf.substr(var_pos, delimiter - var_pos) ); + std::string var_name = Utils::urlDecode( + buf.substr( + var_pos, + delimiter - var_pos + ) + ); ++delimiter; // Получить значение параметра - std::string var_value = Utils::urlDecode(buf.substr(delimiter, std::string::npos != var_end ? var_end - delimiter : std::string::npos) ); + std::string var_value = Utils::urlDecode( + buf.substr( + delimiter, + std::string::npos != var_end + ? var_end - delimiter + : std::string::npos + ) + ); // Сохранить параметр и значение - rd->incoming_data.emplace(std::move(var_name), std::move(var_value) ); + rd->incoming_data.emplace( + std::move(var_name), + std::move(var_value) + ); } } return true; } -}; +} diff --git a/src/server/data-variant/FormUrlencoded.h b/src/server/data-variant/FormUrlencoded.h index c52b575..141c525 100644 --- a/src/server/data-variant/FormUrlencoded.h +++ b/src/server/data-variant/FormUrlencoded.h @@ -12,4 +12,4 @@ namespace DataVariant public: virtual bool parse(const std::string &buf, Transfer::request_data *rd, DataReceiver *dr) const override; }; -}; +} diff --git a/src/server/data-variant/MultipartFormData.cpp b/src/server/data-variant/MultipartFormData.cpp index 2c24504..56ec8cc 100644 --- a/src/server/data-variant/MultipartFormData.cpp +++ b/src/server/data-variant/MultipartFormData.cpp @@ -6,13 +6,11 @@ namespace DataVariant { - MultipartFormData::MultipartFormData() noexcept - { + MultipartFormData::MultipartFormData() noexcept { this->data_variant_name = "multipart/form-data"; } - enum class ParsingState : uint8_t - { + enum class ParsingState : uint8_t { INITIALIZATION = 0, FIND_DATA_BLOCK, GET_DATA_BLOCK_TYPE, @@ -20,15 +18,13 @@ namespace DataVariant SAVE_DATA_BLOCK, }; - enum class BlockType : uint8_t - { + enum class BlockType : uint8_t { UNKNOWN = 0, DATA, FILE, }; - struct StateMultipartFormData - { + struct StateMultipartFormData { std::string block_name; std::string block_value; std::string file_tmp_name; @@ -40,14 +36,15 @@ namespace DataVariant BlockType block_type; }; - void *MultipartFormData::createStateStruct(const Transfer::request_data *rd, const std::unordered_map &contentParams) const - { + void *MultipartFormData::createStateStruct( + const Transfer::request_data *rd, + const std::unordered_map &contentParams + ) const { std::string boundary; auto const it = contentParams.find("boundary"); - if (contentParams.cend() != it) - { + if (contentParams.cend() != it) { boundary = it->second; } @@ -57,8 +54,7 @@ namespace DataVariant }; } - void MultipartFormData::destroyStateStruct(void *st) const noexcept - { + void MultipartFormData::destroyStateStruct(void *st) const noexcept { delete reinterpret_cast(st); } @@ -68,8 +64,11 @@ namespace DataVariant std::unordered_map headers; - for (size_t line_end = buf.find(nl.data(), cur); cur < end; line_end = buf.find(nl.data(), cur) ) - { + for ( + size_t line_end = buf.find(nl.data(), cur); + cur < end; + line_end = buf.find(nl.data(), cur) + ) { size_t delimiter = buf.find(':', cur); if (std::string::npos == delimiter || delimiter > line_end) @@ -77,10 +76,12 @@ namespace DataVariant std::string header_name = buf.substr(cur, line_end - cur); Utils::trim(header_name); Utils::toLower(header_name); - headers.emplace(std::move(header_name), std::string() ); - } - else - { + + headers.emplace( + std::move(header_name), + std::string() + ); + } else { std::string header_name = buf.substr(cur, delimiter - cur); Utils::trim(header_name); Utils::toLower(header_name); @@ -90,7 +91,10 @@ namespace DataVariant std::string header_value = buf.substr(delimiter, line_end - delimiter); Utils::trim(header_value); - headers.emplace(std::move(header_name), std::move(header_value) ); + headers.emplace( + std::move(header_name), + std::move(header_value) + ); } // Перейти к следующему заголовку @@ -107,8 +111,7 @@ namespace DataVariant size_t delimiter = header.find(';'); - if (std::string::npos == delimiter) - { + if (std::string::npos == delimiter) { return header_params; } @@ -116,8 +119,7 @@ namespace DataVariant Utils::trim(content_disposition); // Проверить соответствие указанного формата - if ("form-data" != content_disposition) - { + if ("form-data" != content_disposition) { return header_params; } @@ -129,13 +131,21 @@ namespace DataVariant if (std::string::npos == delimiter || delimiter > end) { - std::string param_name = header.substr(cur, (std::string::npos != end) ? end - cur: std::string::npos); + std::string param_name = header.substr( + cur, + std::string::npos != end + ? end - cur + : std::string::npos + ); + Utils::trim(param_name); Utils::toLower(param_name); - header_params.emplace(std::move(param_name), std::string() ); - } - else - { + + header_params.emplace( + std::move(param_name), + std::string() + ); + } else { std::string param_name = header.substr(cur, delimiter - cur); Utils::trim(param_name); Utils::toLower(param_name); @@ -148,26 +158,40 @@ namespace DataVariant { end = header.find(';', cur); - std::string param_value = header.substr(delimiter, (std::string::npos != end) ? end - delimiter : std::string::npos); + std::string param_value = header.substr( + delimiter, + std::string::npos != end + ? end - delimiter + : std::string::npos + ); + Utils::trim(param_value); - header_params.emplace(std::move(param_name), std::move(param_value) ); - } - else - { + header_params.emplace( + std::move(param_name), + std::move(param_value) + ); + } else { ++delimiter; cur = header.find('"', delimiter); end = header.find(';', cur); - std::string param_value = header.substr(delimiter, (std::string::npos != cur) ? cur - delimiter : std::string::npos); - - header_params.emplace(std::move(param_name), std::move(param_value) ); + std::string param_value = header.substr( + delimiter, + std::string::npos != cur + ? cur - delimiter + : std::string::npos + ); + + header_params.emplace( + std::move(param_name), + std::move(param_value) + ); } } - if (std::string::npos != end) - { + if (std::string::npos != end) { ++end; } } @@ -175,8 +199,11 @@ namespace DataVariant return header_params; } - bool MultipartFormData::parse(const std::string &buf, Transfer::request_data *rd, DataReceiver *dr) const - { + bool MultipartFormData::parse( + const std::string &buf, + Transfer::request_data *rd, + DataReceiver *dr + ) const { StateMultipartFormData *ss = reinterpret_cast(dr->ss); size_t cur = 0; @@ -187,22 +214,18 @@ namespace DataVariant { case ParsingState::INITIALIZATION: { - if (ss->boundary.empty() ) - { + if (ss->boundary.empty() ) { return false; } const std::string data_end("--" + ss->boundary + "--\r\n"); - if (buf.size() < data_end.length() ) - { + if (buf.size() < data_end.length() ) { dr->left = buf.size(); - return dr->full_size != dr->recv_total; } - if (0 == buf.find(data_end) ) - { + if (0 == buf.find(data_end) ) { return dr->full_size == data_end.length() && dr->full_size == dr->recv_total; } @@ -210,8 +233,7 @@ namespace DataVariant cur = buf.find(first_block); - if (0 != cur) - { + if (0 != cur) { return false; } @@ -228,17 +250,14 @@ namespace DataVariant const std::string data_end("\r\n--" + ss->boundary + "--\r\n"); - if (data_end.length() > dr->left) - { + if (data_end.length() > dr->left) { return dr->full_size != dr->recv_total; } const size_t end = buf.find(data_end, cur); - if (end == cur) - { + if (end == cur) { dr->left -= data_end.length(); - return dr->full_size == dr->recv_total; } @@ -246,8 +265,7 @@ namespace DataVariant cur = buf.find(block_delimiter, cur); - if (std::string::npos == cur) - { + if (std::string::npos == cur) { return dr->full_size != dr->recv_total; } @@ -262,10 +280,8 @@ namespace DataVariant { const size_t end = buf.find("\r\n\r\n", cur); - if (std::string::npos == end) - { + if (std::string::npos == end) { dr->left = buf.size() - cur; - return dr->full_size != dr->recv_total; } @@ -276,8 +292,7 @@ namespace DataVariant auto const it = headers.find("content-disposition"); // Если заголовок не определён - if (headers.cend() == it) - { + if (headers.cend() == it) { return false; } @@ -286,8 +301,7 @@ namespace DataVariant // Поиск имени блока данных auto const it_name = header_params.find("name"); - if (header_params.cend() == it_name) - { + if (header_params.cend() == it_name) { return false; } @@ -304,8 +318,7 @@ namespace DataVariant // Найти тип файла auto const it_filetype = headers.find("content-type"); - if (headers.cend() != it_filetype) - { + if (headers.cend() != it_filetype) { ss->file_type = it_filetype->second; } @@ -315,8 +328,7 @@ namespace DataVariant // Создать файл ss->file.open(ss->file_tmp_name, std::ofstream::trunc | std::ofstream::binary); - if (false == ss->file.is_open() ) - { + if (ss->file.is_open() == false) { return false; } } @@ -340,16 +352,20 @@ namespace DataVariant switch (ss->block_type) { - case BlockType::DATA: - { - ss->block_value.append(buf.cbegin() + cur, buf.cbegin() + end); + case BlockType::DATA: { + ss->block_value.append( + buf.cbegin() + long(cur), + buf.cbegin() + long(end) + ); break; } - case BlockType::FILE: - { - ss->file.write(&buf[cur], end - cur); + case BlockType::FILE: { + ss->file.write( + &buf[cur], + std::streamsize(end - cur) + ); break; } @@ -358,10 +374,8 @@ namespace DataVariant return false; } - if (std::string::npos == block_end) - { + if (std::string::npos == block_end) { dr->left = buf.size() - end; - return dr->full_size != dr->recv_total; } @@ -376,19 +390,27 @@ namespace DataVariant { switch (ss->block_type) { - case BlockType::DATA: - { - rd->incoming_data.emplace(std::move(ss->block_name), std::move(ss->block_value) ); + case BlockType::DATA: { + rd->incoming_data.emplace( + std::move(ss->block_name), + std::move(ss->block_value) + ); break; } - case BlockType::FILE: - { - rd->incoming_files.emplace(std::move(ss->block_name), Transfer::FileIncoming(std::move(ss->file_tmp_name), std::move(ss->file_name), std::move(ss->file_type), ss->file.tellp() ) ); + case BlockType::FILE: { + rd->incoming_files.emplace( + std::move(ss->block_name), + Transfer::FileIncoming( + std::move(ss->file_tmp_name), + std::move(ss->file_name), + std::move(ss->file_type), + size_t(ss->file.tellp()) + ) + ); ss->file.close(); - break; } @@ -408,4 +430,4 @@ namespace DataVariant return dr->full_size != dr->recv_total; } -}; +} diff --git a/src/server/data-variant/MultipartFormData.h b/src/server/data-variant/MultipartFormData.h index 65e9071..1a45fc0 100644 --- a/src/server/data-variant/MultipartFormData.h +++ b/src/server/data-variant/MultipartFormData.h @@ -10,10 +10,17 @@ namespace DataVariant MultipartFormData() noexcept; public: - virtual void *createStateStruct(const Transfer::request_data *rd, const std::unordered_map &contentParams) const override; + virtual void *createStateStruct( + const Transfer::request_data *rd, + const std::unordered_map &contentParams + ) const override; - virtual bool parse(const std::string &buf, Transfer::request_data *rd, DataReceiver *dr) const override; + virtual bool parse( + const std::string &buf, + Transfer::request_data *rd, + DataReceiver *dr + ) const override; virtual void destroyStateStruct(void *st) const noexcept override; }; -}; +} diff --git a/src/server/data-variant/TextPlain.cpp b/src/server/data-variant/TextPlain.cpp index 1f4333c..ecb5efa 100644 --- a/src/server/data-variant/TextPlain.cpp +++ b/src/server/data-variant/TextPlain.cpp @@ -3,29 +3,27 @@ namespace DataVariant { - TextPlain::TextPlain() noexcept - { + TextPlain::TextPlain() noexcept { this->data_variant_name = "text/plain"; } bool TextPlain::parse(const std::string &buf, Transfer::request_data *rd, DataReceiver *dr) const { - if (buf.empty() ) - { + if (buf.empty() ) { return 0 == dr->full_size || dr->full_size != dr->recv_total; } - for (size_t var_pos = 0, var_end = 0; std::string::npos != var_end; var_pos = var_end + 1) - { + for ( + size_t var_pos = 0, var_end = 0; + std::string::npos != var_end; + var_pos = var_end + 1 + ) { // Поиск следующего параметра var_end = buf.find('&', var_pos); - if (std::string::npos == var_end) - { - if (dr->full_size != dr->recv_total) - { + if (std::string::npos == var_end) { + if (dr->full_size != dr->recv_total) { dr->left = buf.size() - var_pos; - return true; } } @@ -36,26 +34,40 @@ namespace DataVariant if (delimiter >= var_end) { // Получить имя параметра - std::string var_name = buf.substr(var_pos, std::string::npos != var_end ? var_end - var_pos : std::string::npos); + std::string var_name = buf.substr( + var_pos, + std::string::npos != var_end + ? var_end - var_pos + : std::string::npos + ); // Сохранить параметр с пустым значением - rd->incoming_data.emplace(std::move(var_name), std::string() ); - } - else - { + rd->incoming_data.emplace( + std::move(var_name), + std::string() + ); + } else { // Получить имя параметра std::string var_name = buf.substr(var_pos, delimiter - var_pos); ++delimiter; // Получить значение параметра - std::string var_value = buf.substr(delimiter, std::string::npos != var_end ? var_end - delimiter : std::string::npos); + std::string var_value = buf.substr( + delimiter, + std::string::npos != var_end + ? var_end - delimiter + : std::string::npos + ); // Сохранить параметр и значение - rd->incoming_data.emplace(std::move(var_name), std::move(var_value) ); + rd->incoming_data.emplace( + std::move(var_name), + std::move(var_value) + ); } } return true; } -}; +} diff --git a/src/server/data-variant/TextPlain.h b/src/server/data-variant/TextPlain.h index 8d98766..d6ba101 100644 --- a/src/server/data-variant/TextPlain.h +++ b/src/server/data-variant/TextPlain.h @@ -12,4 +12,4 @@ namespace DataVariant public: virtual bool parse(const std::string &buf, Transfer::request_data *rd, DataReceiver *dr) const override; }; -}; +} diff --git a/src/server/protocol/ServerHttp1.cpp b/src/server/protocol/ServerHttp1.cpp index 290ae9b..8bb5f17 100644 --- a/src/server/protocol/ServerHttp1.cpp +++ b/src/server/protocol/ServerHttp1.cpp @@ -10,14 +10,22 @@ namespace HttpServer { - ServerHttp1::ServerHttp1(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls) noexcept + ServerHttp1::ServerHttp1( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls + ) noexcept : ServerProtocol(sock, settings, controls) { } - bool ServerHttp1::sendHeaders(const Http::StatusCode status, std::vector > &headers, const std::chrono::milliseconds &timeout, const bool endStream) const - { + bool ServerHttp1::sendHeaders( + const Http::StatusCode status, + std::vector > &headers, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const { static const std::unordered_map status_list { { 200, "OK" }, { 206, "Partial Content" }, @@ -33,17 +41,14 @@ namespace HttpServer auto const it = status_list.find(static_cast(status) ); - if (status_list.cend() != it) - { + if (status_list.cend() != it) { const std::string &status = it->second; - str += ' ' + status; } str += "\r\n"; - for (auto const &header : headers) - { + for (auto const &header : headers) { str += header.first + ": " + header.second + "\r\n"; } @@ -52,25 +57,34 @@ namespace HttpServer return this->sock.nonblock_send(str, timeout) > 0; // >= 0 } - long ServerHttp1::sendData(const void *src, size_t size, const std::chrono::milliseconds &timeout, DataTransfer *dt) const - { - const long send_size = this->sock.nonblock_send(src, size, timeout); + long ServerHttp1::sendData( + const void *src, + size_t size, + const std::chrono::milliseconds &timeout, + DataTransfer *dt + ) const { + const long send_size = this->sock.nonblock_send( + src, + size, + timeout + ); - if (send_size > 0) - { - dt->send_total += send_size; + if (send_size > 0) { + dt->send_total += static_cast(send_size); } return send_size; } - void ServerHttp1::close() - { + void ServerHttp1::close() { this->sock.close(); } - bool ServerHttp1::packRequestParameters(std::vector &buf, const struct Request &req, const std::string &rootDir) const - { + bool ServerHttp1::packRequestParameters( + std::vector &buf, + const struct Request &req, + const std::string &rootDir + ) const { Utils::packNumber(buf, static_cast(Transfer::ProtocolVariant::HTTP_1) ); Utils::packString(buf, rootDir); Utils::packString(buf, req.host); @@ -83,34 +97,48 @@ namespace HttpServer return true; } - void ServerHttp1::unpackResponseParameters(struct Request &req, const void *src) const - { - Utils::unpackContainer(req.outgoing_headers, reinterpret_cast(src) ); + void ServerHttp1::unpackResponseParameters( + struct Request &req, + const void *src + ) const { + Utils::unpackContainer( + req.outgoing_headers, + reinterpret_cast(src) + ); } - static bool getRequest(const Socket::Adapter &sock, struct Request &req, std::vector &buf, std::string &str_buf) - { + static bool getRequest( + const Socket::Adapter &sock, + struct Request &req, + std::vector &buf, + std::string &str_buf + ) { // Получить данные запроса от клиента - const long recv_size = sock.nonblock_recv(buf, req.timeout); + const long recv_size = sock.nonblock_recv( + buf, + req.timeout + ); - if (recv_size < 0 && str_buf.empty() ) - { + if (recv_size < 0 && str_buf.empty() ) { return false; } - if (recv_size > 0) // Если данные были получены - { - str_buf.append(buf.cbegin(), buf.cbegin() + recv_size); + if (recv_size > 0) { // Если данные были получены + str_buf.append( + buf.cbegin(), + buf.cbegin() + recv_size + ); } return true; } - static Http::StatusCode getRequestHeaders(struct Request &req, std::string &str_buf) - { + static Http::StatusCode getRequestHeaders( + struct Request &req, + std::string &str_buf + ) { // Если запрос пустой - if (str_buf.empty() ) - { + if (str_buf.empty() ) { return Http::StatusCode::BAD_REQUEST; } @@ -118,8 +146,7 @@ namespace HttpServer size_t headers_end = str_buf.find("\r\n\r\n"); // Если найден конец заголовков - if (std::string::npos == headers_end) - { + if (std::string::npos == headers_end) { return Http::StatusCode::BAD_REQUEST; } @@ -130,8 +157,7 @@ namespace HttpServer size_t str_end = str_buf.find("\r\n"); // Если не найден конец заголовка - if (std::string::npos == str_end) - { + if (std::string::npos == str_end) { return Http::StatusCode::BAD_REQUEST; } @@ -142,7 +168,11 @@ namespace HttpServer size_t delimiter = str_buf.find(' ', str_cur); // Получить метод запроса (GET, POST, PUT, DELETE, ...) - req.method = str_buf.substr(str_cur, delimiter - str_cur); + req.method = str_buf.substr( + str_cur, + delimiter - str_cur + ); + Utils::toLower(req.method); // Сохранить метод и параметры запроса @@ -153,19 +183,16 @@ namespace HttpServer size_t uri_end = str_buf.find(' ', delimiter); // Если окончание не найдено - if (std::string::npos == uri_end) - { + if (std::string::npos == uri_end) { uri_end = str_end; // то версия протокола HTTP - 0.9 // const std::string version = "0.9"; - } - else // Если окончание найдено - { + } else { + // Если окончание найдено str_buf[uri_end] = '\0'; const size_t ver_beg = uri_end + 6; // Пропустить "HTTP/" - if (ver_beg < str_end) - { + if (ver_beg < str_end) { // Получить версию протокола HTTP // const std::string version = str_buf.substr(ver_beg, str_end - ver_beg); } @@ -182,36 +209,53 @@ namespace HttpServer str_buf[str_end] = '\0'; // Цикл извлечения заголовков запроса - for (; str_cur != headers_end; str_end = str_buf.find("\r\n", str_cur), str_buf[str_end] = '\0') - { + for ( + ; + str_cur != headers_end; + str_end = str_buf.find("\r\n", str_cur), str_buf[str_end] = '\0' + ) { // Поиск разделителя названия заголовка и его значения delimiter = str_buf.find(':', str_cur); // Если разделитель найден в текущей строке if (delimiter < str_end) { - std::string header_name = str_buf.substr(str_cur, delimiter - str_cur); + std::string header_name = str_buf.substr( + str_cur, + delimiter - str_cur + ); + Utils::toLower(header_name); - std::string header_value = str_buf.substr(delimiter + 1, str_end - delimiter - 1); + std::string header_value = str_buf.substr( + delimiter + 1, + str_end - delimiter - 1 + ); + // Удалить лишние пробелы в начале и в конце строки Utils::trim(header_value); // Сохранить заголовок и его значение - req.incoming_headers.emplace(std::move(header_name), std::move(header_value) ); + req.incoming_headers.emplace( + std::move(header_name), + std::move(header_value) + ); } // Перейти к следующей строке str_cur = str_end + 2; } - str_buf.erase(str_buf.begin(), str_buf.begin() + headers_end + 2); + str_buf.erase(0, headers_end + 2); return Http::StatusCode::EMPTY; } - const ServerApplicationSettings *ServerHttp1::getApplicationSettings(struct Request &req, const bool isSecureConnection) const - { + const ServerApplicationSettings * + ServerHttp1::getApplicationSettings( + struct Request &req, + const bool isSecureConnection + ) const { // Получить доменное имя (или адрес) назначения запроса auto const it_host = req.incoming_headers.find("host"); @@ -229,14 +273,19 @@ namespace HttpServer const int default_port = isSecureConnection ? 443 : 80; // Получить номер порта - const int port = (std::string::npos != delimiter) ? std::strtol(host_header.substr(delimiter + 1).c_str(), nullptr, 10) : default_port; + const int port = (std::string::npos != delimiter) + ? std::atoi(host_header.substr(delimiter + 1).c_str()) + : default_port; // Поиск настроек приложения по имени const ServerApplicationSettings *app_sets = this->settings.apps_tree.find(req.host); // Если приложение найдено - if (app_sets && (app_sets->ports.cend() != app_sets->ports.find(port) || app_sets->tls_ports.cend() != app_sets->tls_ports.find(port) ) ) - { + if (app_sets && ( + app_sets->ports.cend() != app_sets->ports.find(port) || + app_sets->tls_ports.cend() != app_sets->tls_ports.find(port) + ) + ) { return app_sets; } } @@ -244,13 +293,15 @@ namespace HttpServer return nullptr; } - Http::StatusCode ServerHttp1::getRequestData(struct Request &req, std::string &str_buf, const ServerApplicationSettings &appSets) const - { + Http::StatusCode ServerHttp1::getRequestData( + struct Request &req, + std::string &str_buf, + const ServerApplicationSettings &appSets + ) const { // Определить вариант данных запроса (заодно проверить, есть ли данные) auto const it = req.incoming_headers.find("content-type"); - if (req.incoming_headers.cend() == it) - { + if (req.incoming_headers.cend() == it) { return Http::StatusCode::EMPTY; } @@ -270,33 +321,57 @@ namespace HttpServer data_variant_name = header_value.substr(0, delimiter); Utils::trim(data_variant_name); - for (size_t str_param_cur = delimiter + 1, str_param_end = 0; std::string::npos != str_param_end; str_param_cur = str_param_end + 1) - { + for ( + size_t str_param_cur = delimiter + 1, str_param_end = 0; + std::string::npos != str_param_end; + str_param_cur = str_param_end + 1 + ) { str_param_end = header_value.find(';', str_param_cur); delimiter = header_value.find('=', str_param_cur); if (delimiter >= str_param_end) { - std::string param_name = header_value.substr(str_param_cur, std::string::npos != str_param_end ? str_param_end - str_param_cur : std::string::npos); + std::string param_name = header_value.substr( + str_param_cur, + std::string::npos != str_param_end + ? str_param_end - str_param_cur + : std::string::npos + ); + Utils::trim(param_name); - content_params.emplace(std::move(param_name), std::string() ); + + content_params.emplace( + std::move(param_name), + std::string() + ); } else { - std::string param_name = header_value.substr(str_param_cur, delimiter - str_param_cur); + std::string param_name = header_value.substr( + str_param_cur, + delimiter - str_param_cur + ); + Utils::trim(param_name); ++delimiter; - std::string param_value = header_value.substr(delimiter, std::string::npos != str_param_end ? str_param_end - delimiter : std::string::npos); + std::string param_value = header_value.substr( + delimiter, + std::string::npos != str_param_end + ? str_param_end - delimiter + : std::string::npos + ); + Utils::trim(param_value); - content_params.emplace(std::move(param_name), std::move(param_value) ); + content_params.emplace( + std::move(param_name), + std::move(param_value) + ); } } - } - else - { + } else { data_variant_name = header_value; } @@ -304,8 +379,7 @@ namespace HttpServer auto const variant = this->settings.variants.find(data_variant_name); // Если сервер не поддерживает формат полученных данных - if (this->settings.variants.cend() == variant) - { + if (this->settings.variants.cend() == variant) { return Http::StatusCode::BAD_REQUEST; } @@ -316,14 +390,16 @@ namespace HttpServer auto const it_len = req.incoming_headers.find("content-length"); - if (req.incoming_headers.cend() != it_len) - { - data_length = std::strtoull(it_len->second.c_str(), nullptr, 10); + if (req.incoming_headers.cend() != it_len) { + data_length = std::strtoull( + it_len->second.c_str(), + nullptr, + 10 + ); } // Если размер запроса превышает лимит (если лимит был установлен) - if (data_length > appSets.request_max_size && 0 != appSets.request_max_size) - { + if (data_length > appSets.request_max_size && 0 != appSets.request_max_size) { return Http::StatusCode::REQUEST_ENTITY_TOO_LARGE; } @@ -338,16 +414,15 @@ namespace HttpServer std::string data_buf; - if (data_length >= str_buf.length() ) - { + if (str_buf.length() <= data_length) { dr.recv_total = str_buf.length(); - data_buf.swap(str_buf); - } - else - { - data_buf.assign(str_buf.cbegin(), str_buf.cbegin() + data_length); - str_buf.erase(str_buf.begin(), str_buf.begin() + data_length); + } else { + data_buf.assign( + str_buf, 0, data_length + ); + + str_buf.erase(0, data_length); dr.recv_total = data_buf.size(); } @@ -356,21 +431,33 @@ namespace HttpServer while (result && dr.full_size > dr.recv_total) { - std::vector buf(dr.full_size - dr.recv_total >= 512 * 1024 ? 512 * 1024 : dr.full_size - dr.recv_total); + std::vector buf( + dr.full_size - dr.recv_total >= 512 * 1024 + ? 512 * 1024 + : dr.full_size - dr.recv_total + ); - long recv_size = this->sock.nonblock_recv(buf.data(), buf.size(), req.timeout); + long recv_size = this->sock.nonblock_recv( + buf.data(), + buf.size(), + req.timeout + ); - if (recv_size <= 0) - { + if (recv_size <= 0) { result = false; - break; } - dr.recv_total += recv_size; + dr.recv_total += static_cast(recv_size); - data_buf.erase(data_buf.begin(), data_buf.end() - dr.left); - data_buf.append(buf.cbegin(), buf.cbegin() + recv_size); + data_buf.erase( + 0, data_buf.length() - dr.left + ); + + data_buf.append( + buf.data(), + 0, static_cast(recv_size) + ); dr.left = 0; @@ -379,27 +466,30 @@ namespace HttpServer data_variant->destroyStateStruct(dr.ss); - // Разобрать данные на составляющие - if (false == result) - { - for (auto const &it : req.incoming_files) - { + if (false == result) { + for (auto const &it : req.incoming_files) { std::remove(it.second.getTmpName().c_str() ); } return Http::StatusCode::BAD_REQUEST; } - if (dr.left) - { - str_buf.assign(data_buf.cend() - dr.left, data_buf.cend() ); + if (dr.left) { + str_buf.assign( + data_buf, + data_buf.length() - dr.left, + data_buf.length() + ); } return Http::StatusCode::EMPTY; } - static void sendStatus(const Socket::Adapter &sock, const struct Request &req, const Http::StatusCode statusCode) - { + static void sendStatus( + const Socket::Adapter &sock, + const struct Request &req, + const Http::StatusCode statusCode + ) { static const std::unordered_map status_list { { 400, "Bad Request" }, { 404, "Not Found" }, @@ -408,8 +498,7 @@ namespace HttpServer auto const it = status_list.find(static_cast(statusCode) ); - if (status_list.cend() != it) - { + if (status_list.cend() != it) { const std::string &status = it->second; std::string headers("HTTP/1.1 " + std::to_string(static_cast(statusCode) ) + ' ' + status + "\r\n\r\n"); @@ -418,19 +507,27 @@ namespace HttpServer } } - static void getConnectionParams(struct Request &req, const bool isSecureConnection) - { + static void getConnectionParams( + struct Request &req, + const bool isSecureConnection + ) { auto const it_in_connection = req.incoming_headers.find("connection"); auto const it_out_connection = req.outgoing_headers.find("connection"); - if (req.incoming_headers.cend() != it_in_connection && req.outgoing_headers.cend() != it_out_connection) - { + if ( + req.incoming_headers.cend() != it_in_connection && + req.outgoing_headers.cend() != it_out_connection + ) { const std::string connection_in = Utils::getLowerString(it_in_connection->second); const std::string connection_out = Utils::getLowerString(it_out_connection->second); auto const incoming_params = Utils::explode(connection_in, ','); - auto const it = std::find(incoming_params.cbegin(), incoming_params.cend(), connection_out); + auto const it = std::find( + incoming_params.cbegin(), + incoming_params.cend(), + connection_out + ); if (incoming_params.cend() != it) { @@ -440,8 +537,7 @@ namespace HttpServer { --req.keep_alive_count; - if (0 < req.keep_alive_count) - { + if (0 < req.keep_alive_count) { req.connection_params |= ConnectionParams::CONNECTION_REUSE; } } @@ -453,24 +549,19 @@ namespace HttpServer { const std::string upgrade = Utils::getLowerString(it_out_upgrade->second); - if ("h2" == upgrade) - { - if (isSecureConnection) - { + if ("h2" == upgrade) { + if (isSecureConnection) { req.protocol_variant = Transfer::ProtocolVariant::HTTP_2; req.connection_params |= ConnectionParams::CONNECTION_REUSE; } } - else if ("h2c" == upgrade) - { - if (false == isSecureConnection) - { + else if ("h2c" == upgrade) { + if (false == isSecureConnection) { req.protocol_variant = Transfer::ProtocolVariant::HTTP_2; req.connection_params |= ConnectionParams::CONNECTION_REUSE; } } - else if ("websocket" == upgrade) - { + else if ("websocket" == upgrade) { req.connection_params |= ConnectionParams::CONNECTION_LEAVE_OPEN; } } @@ -479,58 +570,61 @@ namespace HttpServer } } - void ServerHttp1::useHttp1Protocol(struct Request &req, std::vector &buf, std::string &str_buf) const - { - if (false == getRequest(this->sock, req, buf, str_buf) ) - { + void ServerHttp1::useHttp1Protocol( + struct Request &req, + std::vector &buf, + std::string &str_buf + ) const { + if (getRequest(this->sock, req, buf, str_buf) == false) { return; } Http::StatusCode error_code = getRequestHeaders(req, str_buf); - if (error_code != Http::StatusCode::EMPTY) - { + if (error_code != Http::StatusCode::EMPTY) { sendStatus(this->sock, req, error_code); - return; } - const ServerApplicationSettings *app_sets = this->getApplicationSettings(req, this->sock.get_tls_session() != 0); + const ServerApplicationSettings *app_sets = this->getApplicationSettings( + req, + this->sock.get_tls_session() != nullptr + ); // Если приложение не найдено - if (nullptr == app_sets) - { + if (nullptr == app_sets) { sendStatus(this->sock, req, Http::StatusCode::NOT_FOUND); - return; } error_code = this->getRequestData(req, str_buf, *app_sets); - if (error_code != Http::StatusCode::EMPTY) - { + if (error_code != Http::StatusCode::EMPTY) { sendStatus(this->sock, req, error_code); - return; } this->runApplication(req, *app_sets); - for (auto const &it : req.incoming_files) - { + for (auto const &it : req.incoming_files) { std::remove(it.second.getTmpName().c_str() ); } - if (EXIT_SUCCESS == req.app_exit_code) - { - getConnectionParams(req, this->sock.get_tls_session() != 0); + if (EXIT_SUCCESS == req.app_exit_code) { + getConnectionParams( + req, + this->sock.get_tls_session() != nullptr + ); - Sendfile::xSendfile(std::ref(*this), req, this->settings.mimes_types); + Sendfile::xSendfile( + std::ref(*this), + req, + this->settings.mimes_types + ); } } - static bool isConnectionLeaveOpen(const struct Request &req) - { + static bool isConnectionLeaveOpen(const struct Request &req) { return (req.connection_params & ConnectionParams::CONNECTION_LEAVE_OPEN) == ConnectionParams::CONNECTION_LEAVE_OPEN; } @@ -544,8 +638,7 @@ namespace HttpServer std::vector buf(4096); std::string str_buf; - do - { + do { // Подготовить параметры для получения данных req.connection_params = ConnectionParams::CONNECTION_CLOSE; req.app_exit_code = EXIT_FAILURE; @@ -556,11 +649,10 @@ namespace HttpServer } while (Sendfile::isConnectionReuse(req) ); - if (isConnectionLeaveOpen(req) ) - { + if (isConnectionLeaveOpen(req) ) { return new ServerWebSocket(*this); } return this; } -}; +} diff --git a/src/server/protocol/ServerHttp1.h b/src/server/protocol/ServerHttp1.h index cc7f2c3..258e2c8 100644 --- a/src/server/protocol/ServerHttp1.h +++ b/src/server/protocol/ServerHttp1.h @@ -8,22 +8,57 @@ namespace HttpServer class ServerHttp1 : public ServerProtocol { private: - const ServerApplicationSettings *getApplicationSettings(struct Request &rp, const bool isSecureConnection) const; - Http::StatusCode getRequestData(struct Request &rp, std::string &str_buf, const ServerApplicationSettings &appSets) const; + const ServerApplicationSettings *getApplicationSettings( + struct Request &rp, + const bool isSecureConnection + ) const; + + Http::StatusCode getRequestData( + struct Request &rp, + std::string &str_buf, + const ServerApplicationSettings &appSets + ) const; protected: - void useHttp1Protocol(struct Request &rp, std::vector &buf, std::string &str_buf) const; + void useHttp1Protocol( + struct Request &rp, + std::vector &buf, + std::string &str_buf + ) const; public: - ServerHttp1(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls) noexcept; + ServerHttp1( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls + ) noexcept; + + virtual bool sendHeaders( + const Http::StatusCode status, + std::vector > &headers, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const override; + + virtual long sendData( + const void *src, + size_t size, + const std::chrono::milliseconds &timeout, + DataTransfer *dt + ) const override; - virtual bool sendHeaders(const Http::StatusCode status, std::vector > &headers, const std::chrono::milliseconds &timeout, const bool endStream) const override; - virtual long sendData(const void *src, size_t size, const std::chrono::milliseconds &timeout, DataTransfer *dt) const override; + virtual bool packRequestParameters( + std::vector &buf, + const struct Request &rp, + const std::string &rootDir + ) const override; - virtual bool packRequestParameters(std::vector &buf, const struct Request &rp, const std::string &rootDir) const override; - virtual void unpackResponseParameters(struct Request &req, const void *src) const override; + virtual void unpackResponseParameters( + struct Request &req, + const void *src + ) const override; virtual ServerProtocol *process() override; virtual void close() override; }; -}; +} diff --git a/src/server/protocol/ServerHttp2.cpp b/src/server/protocol/ServerHttp2.cpp index 5ef4991..12ae2be 100644 --- a/src/server/protocol/ServerHttp2.cpp +++ b/src/server/protocol/ServerHttp2.cpp @@ -7,7 +7,12 @@ namespace HttpServer { - ServerHttp2::ServerHttp2(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls, SocketsQueue &sockets) noexcept + ServerHttp2::ServerHttp2( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls, + SocketsQueue &sockets + ) noexcept : ServerHttp2Protocol(sock, settings, controls, nullptr), sockets(sockets) { @@ -17,8 +22,13 @@ namespace HttpServer this->sock.close(); } - static uint8_t *setHttp2FrameHeader(uint8_t *addr, const uint32_t frameSize, const Http2::FrameType frameType, const Http2::FrameFlag frameFlags, const uint32_t streamId) noexcept - { + static uint8_t *setHttp2FrameHeader( + uint8_t *addr, + const uint32_t frameSize, + const Http2::FrameType frameType, + const Http2::FrameFlag frameFlags, + const uint32_t streamId + ) noexcept { Utils::hton24(addr, frameSize); *(addr + 3) = static_cast(frameType); *(addr + 4) = static_cast(frameFlags); @@ -27,8 +37,11 @@ namespace HttpServer return (addr + Http2::FRAME_HEADER_SIZE); } - static Http2::IncStream &getStreamData(std::unordered_map &streams, const uint32_t streamId, Http2::ConnectionData &conn) noexcept - { + static Http2::IncStream &getStreamData( + std::unordered_map &streams, + const uint32_t streamId, + Http2::ConnectionData &conn + ) noexcept { auto it = streams.find(streamId); if (streams.end() != it) { @@ -38,12 +51,22 @@ namespace HttpServer return streams.emplace(streamId, Http2::IncStream(streamId, conn) ).first->second; } - static void sendWindowUpdate(const Socket::Adapter &sock, const std::chrono::milliseconds &timeout, const Http2::IncStream &stream, const uint32_t size) noexcept - { + static void sendWindowUpdate( + const Socket::Adapter &sock, + const std::chrono::milliseconds &timeout, + const Http2::IncStream &stream, + const uint32_t size + ) noexcept { std::array buf; uint8_t *addr = buf.data(); - addr = setHttp2FrameHeader(addr, sizeof(uint32_t), Http2::FrameType::WINDOW_UPDATE, Http2::FrameFlag::EMPTY, stream.stream_id); + addr = setHttp2FrameHeader( + addr, + sizeof(uint32_t), + Http2::FrameType::WINDOW_UPDATE, + Http2::FrameFlag::EMPTY, + stream.stream_id + ); *reinterpret_cast(addr) = ::htonl(size); @@ -52,8 +75,12 @@ namespace HttpServer sock.nonblock_send(buf.data(), buf.size(), timeout); } - static Http2::ErrorCode parseHttp2Data(Http2::FrameMeta &meta, Http2::IncStream &stream, const uint8_t *src, const uint8_t *end) - { + static Http2::ErrorCode parseHttp2Data( + Http2::FrameMeta &meta, + Http2::IncStream &stream, + const uint8_t *src, + const uint8_t *end + ) { if (0 == meta.stream_id) { return Http2::ErrorCode::PROTOCOL_ERROR; } @@ -91,24 +118,20 @@ namespace HttpServer buf.append(src, end - padding); - dr->recv_total += end - padding - src; + dr->recv_total += size_t(end - src) - padding; - if (dr->data_variant->parse(buf, rd, dr) ) - { - buf.erase(buf.begin(), buf.end() - dr->left); - } - else - { + if (dr->data_variant->parse(buf, rd, dr) ) { + buf.erase( + 0, buf.length() - dr->left + ); + } else { error_code = Http2::ErrorCode::PROTOCOL_ERROR; } - } - else - { + } else { error_code = Http2::ErrorCode::PROTOCOL_ERROR; } - if (meta.flags & Http2::FrameFlag::END_STREAM) - { + if (meta.flags & Http2::FrameFlag::END_STREAM) { stream.state = Http2::StreamState::HALF_CLOSED; ServerProtocol::destroyDataReceiver(stream.reserved); @@ -118,9 +141,15 @@ namespace HttpServer return error_code; } - static Http2::ErrorCode parseHttp2Headers(Http2::FrameMeta &meta, Http2::IncStream &stream, const uint8_t *src, const uint8_t *end) - { - stream.state = (meta.flags & Http2::FrameFlag::END_STREAM) ? Http2::StreamState::HALF_CLOSED : Http2::StreamState::OPEN; + static Http2::ErrorCode parseHttp2Headers( + Http2::FrameMeta &meta, + Http2::IncStream &stream, + const uint8_t *src, + const uint8_t *end + ) { + stream.state = (meta.flags & Http2::FrameFlag::END_STREAM) + ? Http2::StreamState::HALF_CLOSED + : Http2::StreamState::OPEN; uint8_t padding = 0; @@ -138,7 +167,9 @@ namespace HttpServer if (meta.flags & Http2::FrameFlag::PRIORITY) { // Stream id - const uint32_t depend_stream_id = ::ntohl(*reinterpret_cast(src) ) & ~(1 << 31); + const uint32_t depend_stream_id = ::ntohl( + *reinterpret_cast(src) + ) & ~(uint32_t(1) << 31); src += sizeof(uint32_t); @@ -148,15 +179,19 @@ namespace HttpServer src += sizeof(uint8_t); } - if (HPack::unpack(src, end - src - padding, stream) == false) { + if (HPack::unpack(src, size_t(end - src) - padding, stream) == false) { return Http2::ErrorCode::COMPRESSION_ERROR; } return Http2::ErrorCode::NO_ERROR; } - static Http2::ErrorCode parseHttp2rstStream(Http2::FrameMeta &meta, Http2::IncStream &stream, const uint8_t *src, const uint8_t *end) - { + static Http2::ErrorCode parseHttp2rstStream( + Http2::FrameMeta &meta, + Http2::IncStream &stream, + const uint8_t *src, + const uint8_t *end + ) { if (Http2::StreamState::IDLE == stream.state) { return Http2::ErrorCode::PROTOCOL_ERROR; } @@ -171,7 +206,9 @@ namespace HttpServer return Http2::ErrorCode::FRAME_SIZE_ERROR; } - const Http2::ErrorCode error_code = static_cast(::ntohl(*reinterpret_cast(src) ) ); + const Http2::ErrorCode error_code = static_cast( + ::ntohl(*reinterpret_cast(src) ) + ); if (Http2::ErrorCode::NO_ERROR != error_code) { // DEBUG @@ -180,8 +217,12 @@ namespace HttpServer return Http2::ErrorCode::NO_ERROR; } - static Http2::ErrorCode parseHttp2Settings(Http2::FrameMeta &meta, Http2::IncStream &stream, const uint8_t *src, const uint8_t *end) - { + static Http2::ErrorCode parseHttp2Settings( + Http2::FrameMeta &meta, + Http2::IncStream &stream, + const uint8_t *src, + const uint8_t *end + ) { if (0 != meta.stream_id) { return Http2::ErrorCode::PROTOCOL_ERROR; } @@ -198,7 +239,9 @@ namespace HttpServer while (src != end) { - const Http2::ConnectionSetting setting = static_cast(ntohs(*reinterpret_cast(src) ) ); + const Http2::ConnectionSetting setting = static_cast( + ntohs(*reinterpret_cast(src) ) + ); src += sizeof(uint16_t); @@ -208,68 +251,74 @@ namespace HttpServer switch (setting) { - case Http2::ConnectionSetting::SETTINGS_HEADER_TABLE_SIZE: - settings.header_table_size = value; - break; - - case Http2::ConnectionSetting::SETTINGS_ENABLE_PUSH: - { - if (value > 1) { - return Http2::ErrorCode::PROTOCOL_ERROR; + case Http2::ConnectionSetting::SETTINGS_HEADER_TABLE_SIZE: { + settings.header_table_size = value; + break; } - settings.enable_push = value; + case Http2::ConnectionSetting::SETTINGS_ENABLE_PUSH: { + if (value > 1) { + return Http2::ErrorCode::PROTOCOL_ERROR; + } - break; - } + settings.enable_push = value; - case Http2::ConnectionSetting::SETTINGS_MAX_CONCURRENT_STREAMS: - settings.max_concurrent_streams = value; - break; + break; + } - case Http2::ConnectionSetting::SETTINGS_INITIAL_WINDOW_SIZE: - { - if (value >= uint32_t(1 << 31) ) { - return Http2::ErrorCode::FLOW_CONTROL_ERROR; + case Http2::ConnectionSetting::SETTINGS_MAX_CONCURRENT_STREAMS: { + settings.max_concurrent_streams = value; + break; } - settings.initial_window_size = value; + case Http2::ConnectionSetting::SETTINGS_INITIAL_WINDOW_SIZE: { + if (value >= uint32_t(1) << 31) { + return Http2::ErrorCode::FLOW_CONTROL_ERROR; + } - break; - } + settings.initial_window_size = value; - case Http2::ConnectionSetting::SETTINGS_MAX_FRAME_SIZE: - { - if (value < (1 << 14) || value >= (1 << 24) ) { - return Http2::ErrorCode::PROTOCOL_ERROR; + break; } - settings.max_frame_size = value; + case Http2::ConnectionSetting::SETTINGS_MAX_FRAME_SIZE: { + if (value < (1 << 14) || value >= (1 << 24) ) { + return Http2::ErrorCode::PROTOCOL_ERROR; + } - break; - } + settings.max_frame_size = value; - case Http2::ConnectionSetting::SETTINGS_MAX_HEADER_LIST_SIZE: - settings.max_header_list_size = value; - break; + break; + } - default: - break; + case Http2::ConnectionSetting::SETTINGS_MAX_HEADER_LIST_SIZE: { + settings.max_header_list_size = value; + break; + } + + default: + break; } } return Http2::ErrorCode::NO_ERROR; } - static Http2::ErrorCode parseHttp2GoAway(Http2::FrameMeta &meta, Http2::IncStream &stream, const uint8_t *src, const uint8_t *end) - { + static Http2::ErrorCode parseHttp2GoAway( + Http2::FrameMeta &meta, + Http2::IncStream &stream, + const uint8_t *src, + const uint8_t *end + ) { if (0 != meta.stream_id) { return Http2::ErrorCode::PROTOCOL_ERROR; } stream.state = Http2::StreamState::CLOSED; - const uint32_t last_stream_id = ::ntohl(*reinterpret_cast(src) ); + const uint32_t last_stream_id = ::ntohl( + *reinterpret_cast(src) + ); if (last_stream_id > 0) { @@ -277,7 +326,9 @@ namespace HttpServer src += sizeof(uint32_t); - const Http2::ErrorCode error_code = static_cast(::ntohl(*reinterpret_cast(src) ) ); + const Http2::ErrorCode error_code = static_cast( + ::ntohl(*reinterpret_cast(src) ) + ); if (Http2::ErrorCode::NO_ERROR != error_code) { @@ -286,8 +337,12 @@ namespace HttpServer return Http2::ErrorCode::NO_ERROR; } - static void ping(const Socket::Adapter &sock, const std::chrono::milliseconds &timeout, Http2::ConnectionData &conn, const uint64_t pingData) - { + static void ping( + const Socket::Adapter &sock, + const std::chrono::milliseconds &timeout, + Http2::ConnectionData &conn, + const uint64_t pingData + ) { constexpr uint32_t frame_size = sizeof(uint64_t); std::array buf; @@ -295,7 +350,13 @@ namespace HttpServer constexpr uint32_t stream_id = 0; - addr = setHttp2FrameHeader(addr, frame_size, Http2::FrameType::PING, Http2::FrameFlag::ACK, stream_id); + addr = setHttp2FrameHeader( + addr, + frame_size, + Http2::FrameType::PING, + Http2::FrameFlag::ACK, + stream_id + ); *reinterpret_cast(addr) = pingData; @@ -304,8 +365,9 @@ namespace HttpServer sock.nonblock_send(buf.data(), buf.size(), timeout); } - static Http2::ErrorCode parseHttp2Ping(Http2::FrameMeta &meta) - { + static Http2::ErrorCode parseHttp2Ping( + Http2::FrameMeta &meta + ) { if (0 != meta.stream_id) { return Http2::ErrorCode::PROTOCOL_ERROR; } @@ -317,8 +379,12 @@ namespace HttpServer return Http2::ErrorCode::NO_ERROR; } - static Http2::ErrorCode parseHttp2WindowUpdate(Http2::FrameMeta &meta, Http2::IncStream &stream, const uint8_t *src, const uint8_t *end) - { + static Http2::ErrorCode parseHttp2WindowUpdate( + Http2::FrameMeta &meta, + Http2::IncStream &stream, + const uint8_t *src, + const uint8_t *end + ) { if (Http2::StreamState::RESERVED == stream.state) { return Http2::ErrorCode::PROTOCOL_ERROR; } @@ -330,12 +396,14 @@ namespace HttpServer return Http2::ErrorCode::FRAME_SIZE_ERROR; } - const uint32_t window_size_increment = ::ntohl(*reinterpret_cast(src) ); + const uint32_t window_size_increment = ::ntohl( + *reinterpret_cast(src) + ); if (0 == window_size_increment) { return Http2::ErrorCode::PROTOCOL_ERROR; } - else if (window_size_increment >= uint32_t(1 << 31) ) { + else if (window_size_increment >= uint32_t(1) << 31) { return Http2::ErrorCode::FLOW_CONTROL_ERROR; } @@ -349,25 +417,42 @@ namespace HttpServer return Http2::ErrorCode::NO_ERROR; } - static void rstStream(const Socket::Adapter &sock, const std::chrono::milliseconds &timeout, Http2::IncStream &stream, const Http2::ErrorCode errorCode) - { + static void rstStream( + const Socket::Adapter &sock, + const std::chrono::milliseconds &timeout, + Http2::IncStream &stream, + const Http2::ErrorCode errorCode + ) { constexpr uint32_t frame_size = sizeof(uint32_t); std::array buf; uint8_t *addr = buf.data(); - addr = setHttp2FrameHeader(addr, frame_size, Http2::FrameType::RST_STREAM, Http2::FrameFlag::EMPTY, stream.stream_id); + addr = setHttp2FrameHeader( + addr, + frame_size, + Http2::FrameType::RST_STREAM, + Http2::FrameFlag::EMPTY, + stream.stream_id + ); - *reinterpret_cast(addr) = ::htonl(static_cast(errorCode) ); + *reinterpret_cast(addr) = ::htonl( + static_cast(errorCode) + ); const std::unique_lock lock(stream.conn.sync.mtx); sock.nonblock_send(buf.data(), buf.size(), timeout); } - static void sendSettings(const Socket::Adapter &sock, const std::chrono::milliseconds &timeout, Http2::ConnectionData &conn, const uint8_t *src, const uint8_t *end) - { - const uint32_t frame_size = end - src; + static void sendSettings( + const Socket::Adapter &sock, + const std::chrono::milliseconds &timeout, + Http2::ConnectionData &conn, + const uint8_t *src, + const uint8_t *end + ) { + const uint32_t frame_size = uint32_t(end - src); std::vector buf(Http2::FRAME_HEADER_SIZE + frame_size); @@ -375,7 +460,13 @@ namespace HttpServer constexpr uint32_t stream_id = 0; - addr = setHttp2FrameHeader(addr, frame_size, Http2::FrameType::SETTINGS, Http2::FrameFlag::EMPTY, stream_id); + addr = setHttp2FrameHeader( + addr, + frame_size, + Http2::FrameType::SETTINGS, + Http2::FrameFlag::EMPTY, + stream_id + ); std::copy(src, end, addr); @@ -384,31 +475,51 @@ namespace HttpServer sock.nonblock_send(buf.data(), buf.size(), timeout); } - static void goAway(const Socket::Adapter &sock, const std::chrono::milliseconds &timeout, Http2::ConnectionData &conn, const uint32_t lastStreamId, const Http2::ErrorCode errorCode) - { + static void goAway( + const Socket::Adapter &sock, + const std::chrono::milliseconds &timeout, + Http2::ConnectionData &conn, + const uint32_t lastStreamId, + const Http2::ErrorCode errorCode + ) { constexpr uint32_t frame_size = sizeof(uint32_t) * 2; std::array buf; uint8_t *addr = buf.data(); - addr = setHttp2FrameHeader(addr, frame_size, Http2::FrameType::RST_STREAM, Http2::FrameFlag::EMPTY, 0); + addr = setHttp2FrameHeader( + addr, + frame_size, + Http2::FrameType::RST_STREAM, + Http2::FrameFlag::EMPTY, + 0 + ); - *reinterpret_cast(addr) = ::htonl(static_cast(lastStreamId) ); - *reinterpret_cast(addr + sizeof(uint32_t) ) = ::htonl(static_cast(errorCode) ); + *reinterpret_cast(addr) = ::htonl(lastStreamId); + + *reinterpret_cast(addr + sizeof(uint32_t) ) = ::htonl( + static_cast(errorCode) + ); const std::unique_lock lock(conn.sync.mtx); sock.nonblock_send(buf.data(), buf.size(), timeout); } - static bool getClientPreface(const Socket::Adapter &sock, const std::chrono::milliseconds &timeout) - { + static bool getClientPreface( + const Socket::Adapter &sock, + const std::chrono::milliseconds &timeout + ) { std::array buf; - const long read_size = sock.nonblock_recv(buf.data(), buf.size(), timeout); + const long read_size = sock.nonblock_recv( + buf.data(), + buf.size(), + timeout + ); - if (read_size != buf.size() ) { + if (buf.size() != read_size) { return false; } @@ -426,8 +537,12 @@ namespace HttpServer return 0 == compare; } - static void sendEmptySettings(const Socket::Adapter &sock, const std::chrono::milliseconds &timeout, Http2::ConnectionData &conn, const Http2::FrameFlag flags) - { + static void sendEmptySettings( + const Socket::Adapter &sock, + const std::chrono::milliseconds &timeout, + Http2::ConnectionData &conn, + const Http2::FrameFlag flags + ) { constexpr uint32_t frame_size = 0; std::array buf; @@ -435,32 +550,52 @@ namespace HttpServer constexpr uint32_t stream_id = 0; - addr = setHttp2FrameHeader(addr, frame_size, Http2::FrameType::SETTINGS, flags, stream_id); + addr = setHttp2FrameHeader( + addr, + frame_size, + Http2::FrameType::SETTINGS, + flags, + stream_id + ); const std::unique_lock lock(conn.sync.mtx); sock.nonblock_send(buf.data(), buf.size(), timeout); } - static bool getNextHttp2FrameMeta(const Socket::Adapter &sock, const std::chrono::milliseconds &timeout, std::vector &buf, Http2::FrameMeta &meta, long &read_size) - { - if (read_size <= static_cast(meta.length + Http2::FRAME_HEADER_SIZE) ) - { - if (read_size == static_cast(meta.length + Http2::FRAME_HEADER_SIZE) ) { + static bool getNextHttp2FrameMeta( + const Socket::Adapter &sock, + const std::chrono::milliseconds &timeout, + std::vector &buf, + Http2::FrameMeta &meta, + long &read_size + ) { + const long length = long( + meta.length + Http2::FRAME_HEADER_SIZE + ); + + if (read_size <= length) { + if (read_size == length) { read_size = 0; } - read_size = sock.nonblock_recv(buf.data() + read_size, buf.size() - read_size, timeout); + read_size = sock.nonblock_recv( + buf.data() + read_size, + buf.size() - size_t(read_size), + timeout + ); - if (read_size < static_cast(Http2::FRAME_HEADER_SIZE) ) { + if (read_size < long(Http2::FRAME_HEADER_SIZE) ) { return false; } - } - else - { - std::copy(buf.cbegin() + meta.length + Http2::FRAME_HEADER_SIZE, buf.cbegin() + read_size, buf.begin() ); + } else { + std::copy( + buf.cbegin() + length, + buf.cbegin() + read_size, + buf.begin() + ); - read_size -= static_cast(meta.length + Http2::FRAME_HEADER_SIZE); + read_size -= length; } const uint8_t *addr = reinterpret_cast(buf.data() ); @@ -481,11 +616,24 @@ namespace HttpServer Http2::ConnectionData conn; - sendEmptySettings(this->sock, req.timeout, conn, Http2::FrameFlag::EMPTY); + sendEmptySettings( + this->sock, + req.timeout, + conn, + Http2::FrameFlag::EMPTY + ); if (getClientPreface(this->sock, req.timeout) == false) { constexpr uint32_t last_stream_id = 0; - goAway(this->sock, req.timeout, conn, last_stream_id, Http2::ErrorCode::PROTOCOL_ERROR); + + goAway( + this->sock, + req.timeout, + conn, + last_stream_id, + Http2::ErrorCode::PROTOCOL_ERROR + ); + return this; } @@ -512,7 +660,10 @@ namespace HttpServer break; } - const uint8_t *addr = reinterpret_cast(buf.data() ) + Http2::FRAME_HEADER_SIZE; + const uint8_t *addr = reinterpret_cast( + buf.data() + ) + Http2::FRAME_HEADER_SIZE; + const uint8_t *end = addr + meta.length; if (meta.stream_id > last_stream_id) { @@ -544,16 +695,17 @@ namespace HttpServer { DataVariant::DataReceiver *dr = reinterpret_cast(stream.reserved); - if (static_cast(stream.window_size_inc - conn.server_settings.max_frame_size) <= 0) + if (stream.window_size_inc - long(conn.server_settings.max_frame_size) <= 0) { - size_t update_size = conn.server_settings.initial_window_size + (dr->full_size - dr->recv_total) - stream.window_size_inc; + size_t update_size = conn.server_settings.initial_window_size + + (dr->full_size - dr->recv_total) - size_t(stream.window_size_inc); if (update_size > Http2::MAX_WINDOW_UPDATE) { update_size = Http2::MAX_WINDOW_UPDATE; } - sendWindowUpdate(this->sock, req.timeout, stream, static_cast(update_size) ); - sendWindowUpdate(this->sock, req.timeout, primary, static_cast(update_size) ); + sendWindowUpdate(this->sock, req.timeout, stream, uint32_t(update_size) ); + sendWindowUpdate(this->sock, req.timeout, primary, uint32_t(update_size) ); stream.window_size_inc += update_size; } @@ -593,7 +745,7 @@ namespace HttpServer { result = parseHttp2Settings(meta, stream, addr, end); - if (Http2::ErrorCode::NO_ERROR == result && false == (meta.flags & Http2::FrameFlag::ACK) ) + if (Http2::ErrorCode::NO_ERROR == result && (meta.flags & Http2::FrameFlag::ACK) == false) { conn.decoding_dynamic_table.changeHeaderTableSize(conn.client_settings.header_table_size); conn.decoding_dynamic_table.changeMaxHeaderListSize(conn.client_settings.max_header_list_size); @@ -612,7 +764,7 @@ namespace HttpServer { result = parseHttp2Ping(meta); - if (Http2::ErrorCode::NO_ERROR == result && false == (meta.flags & Http2::FrameFlag::ACK) ) + if (Http2::ErrorCode::NO_ERROR == result && (meta.flags & Http2::FrameFlag::ACK) == false) { const uint64_t ping_data = *reinterpret_cast(addr); ping(this->sock, req.timeout, conn, ping_data); @@ -668,7 +820,13 @@ namespace HttpServer conn.sync.event.wait(); } - goAway(this->sock, req.timeout, conn, last_stream_id, Http2::ErrorCode::NO_ERROR); + goAway( + this->sock, + req.timeout, + conn, + last_stream_id, + Http2::ErrorCode::NO_ERROR + ); for (auto &pair : streams) { destroyDataReceiver(pair.second.reserved); diff --git a/src/server/protocol/ServerHttp2.h b/src/server/protocol/ServerHttp2.h index 6910788..7871d3e 100644 --- a/src/server/protocol/ServerHttp2.h +++ b/src/server/protocol/ServerHttp2.h @@ -13,7 +13,12 @@ namespace HttpServer SocketsQueue &sockets; public: - ServerHttp2(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls, SocketsQueue &sockets) noexcept; + ServerHttp2( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls, + SocketsQueue &sockets + ) noexcept; virtual ServerProtocol *process() override; virtual void close() override; diff --git a/src/server/protocol/ServerHttp2Protocol.cpp b/src/server/protocol/ServerHttp2Protocol.cpp index df18c00..fd4ed10 100644 --- a/src/server/protocol/ServerHttp2Protocol.cpp +++ b/src/server/protocol/ServerHttp2Protocol.cpp @@ -7,7 +7,12 @@ namespace HttpServer { - ServerHttp2Protocol::ServerHttp2Protocol(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls, Http2::IncStream *stream) noexcept + ServerHttp2Protocol::ServerHttp2Protocol( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls, + Http2::IncStream *stream + ) noexcept : ServerProtocol(sock, settings, controls), stream(stream) { @@ -15,26 +20,33 @@ namespace HttpServer uint8_t ServerHttp2Protocol::getPaddingSize(const size_t dataSize) { - if (0 == dataSize) - { + if (0 == dataSize) { return 0; } std::random_device rd; + std::uniform_int_distribution dist; - uint8_t padding = rd(); + uint8_t padding = dist(rd); - while (dataSize <= padding) - { + while (dataSize <= padding) { padding /= 2; } return padding; } - bool ServerHttp2Protocol::sendHeaders(const Http::StatusCode status, std::vector > &headers, const std::chrono::milliseconds &timeout, const bool endStream) const - { - headers.emplace(headers.begin(), ":status", std::to_string(static_cast(status) ) ); + bool ServerHttp2Protocol::sendHeaders( + const Http::StatusCode status, + std::vector > &headers, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const { + headers.emplace( + headers.begin(), + ":status", + std::to_string(static_cast(status)) + ); std::vector buf; buf.reserve(4096); @@ -42,24 +54,34 @@ namespace HttpServer HPack::pack(buf, headers, this->stream->conn.encoding_dynamic_table); - const uint32_t frame_size = buf.size() - Http2::FRAME_HEADER_SIZE; + const uint32_t frame_size = uint32_t( + buf.size() - Http2::FRAME_HEADER_SIZE + ); Http2::FrameFlag flags = Http2::FrameFlag::END_HEADERS; - if (endStream) - { + if (endStream) { flags |= Http2::FrameFlag::END_STREAM; } - this->stream->setHttp2FrameHeader(reinterpret_cast(buf.data() ), frame_size, Http2::FrameType::HEADERS, flags); + this->stream->setHttp2FrameHeader( + reinterpret_cast(buf.data() ), + frame_size, + Http2::FrameType::HEADERS, + flags + ); const std::unique_lock lock(this->stream->conn.sync.mtx); - return this->sock.nonblock_send(buf.data(), buf.size(), timeout) > 0; // >= 0; + return this->sock.nonblock_send(buf.data(), buf.size(), timeout) > 0; } - long ServerHttp2Protocol::sendData(const void *src, size_t size, const std::chrono::milliseconds &timeout, DataTransfer *dt) const - { + long ServerHttp2Protocol::sendData( + const void *src, + size_t size, + const std::chrono::milliseconds &timeout, + DataTransfer *dt + ) const { const uint8_t *data = reinterpret_cast(src); const Http2::ConnectionSettings &setting = this->stream->conn.client_settings; @@ -72,15 +94,15 @@ namespace HttpServer while (size != 0) { // TODO: test with data_size == 1 (padding length == 0) - size_t data_size = setting.max_frame_size < size ? setting.max_frame_size : size; + size_t data_size = setting.max_frame_size < size + ? setting.max_frame_size + : size; const uint8_t padding = getPaddingSize(data_size); const uint16_t padding_size = padding + sizeof(uint8_t); - if (padding_size) - { - if (data_size + padding_size > setting.max_frame_size) - { + if (padding_size) { + if (data_size + padding_size > setting.max_frame_size) { data_size = setting.max_frame_size - padding_size; } } @@ -93,27 +115,24 @@ namespace HttpServer { size_t update_size = (dt->full_size - dt->send_total) - this->stream->window_size_out; - if (update_size > Http2::MAX_WINDOW_UPDATE) - { + if (update_size > Http2::MAX_WINDOW_UPDATE) { update_size = Http2::MAX_WINDOW_UPDATE; } - sendWindowUpdate(this->sock, rp, static_cast(update_size) ); + sendWindowUpdate(this->sock, rp, uint32_t(update_size) ); this->stream->window_size_out += update_size; }*/ Http2::FrameFlag flags = Http2::FrameFlag::EMPTY; - if (dt->send_total + data_size >= dt->full_size) - { + if (dt->send_total + data_size >= dt->full_size) { flags |= Http2::FrameFlag::END_STREAM; } size_t cur = Http2::FRAME_HEADER_SIZE; - if (padding_size) - { + if (padding_size) { flags |= Http2::FrameFlag::PADDED; buf[cur] = padding; @@ -121,23 +140,38 @@ namespace HttpServer ++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->setHttp2FrameHeader( + buf.data(), + static_cast(frame_size), + Http2::FrameType::DATA, + flags + ); + + std::copy( + data, + data + data_size, + buf.begin() + long(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); + const long sended = this->sock.nonblock_send( + buf.data(), + buf.size(), + timeout + ); this->stream->unlock(); - if (sended <= 0) - { + if (sended <= 0) { send_size = sended; break; } @@ -153,8 +187,11 @@ namespace HttpServer return send_size; } - bool ServerHttp2Protocol::packRequestParameters(std::vector &buf, const struct Request &req, const std::string &rootDir) const - { + bool ServerHttp2Protocol::packRequestParameters( + std::vector &buf, + const struct Request &req, + const std::string &rootDir + ) const { Utils::packNumber(buf, static_cast(Transfer::ProtocolVariant::HTTP_2) ); Utils::packString(buf, rootDir); Utils::packString(buf, req.host); @@ -177,8 +214,13 @@ namespace HttpServer return true; } - void ServerHttp2Protocol::unpackResponseParameters(struct Request &req, const void *src) const - { - Utils::unpackContainer(req.outgoing_headers, reinterpret_cast(src) ); + void ServerHttp2Protocol::unpackResponseParameters( + struct Request &req, + const void *src + ) const { + Utils::unpackContainer( + req.outgoing_headers, + reinterpret_cast(src) + ); } -}; +} diff --git a/src/server/protocol/ServerHttp2Protocol.h b/src/server/protocol/ServerHttp2Protocol.h index 7c84ba4..99adc42 100644 --- a/src/server/protocol/ServerHttp2Protocol.h +++ b/src/server/protocol/ServerHttp2Protocol.h @@ -14,12 +14,35 @@ namespace HttpServer static uint8_t getPaddingSize(const size_t dataSize); public: - ServerHttp2Protocol(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls, Http2::IncStream *stream) noexcept; + ServerHttp2Protocol( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls, Http2::IncStream *stream + ) noexcept; - virtual bool sendHeaders(const Http::StatusCode status, std::vector > &headers, const std::chrono::milliseconds &timeout, const bool endStream) const override; - virtual long sendData(const void *src, size_t size, const std::chrono::milliseconds &timeout, DataTransfer *dt) const override; + virtual bool sendHeaders( + const Http::StatusCode status, + std::vector > &headers, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const override; - virtual bool packRequestParameters(std::vector &buf, const struct Request &rp, const std::string &rootDir) const override; - virtual void unpackResponseParameters(struct Request &rp, const void *src) const override; + virtual long sendData( + const void *src, + size_t size, + const std::chrono::milliseconds &timeout, + DataTransfer *dt + ) const override; + + virtual bool packRequestParameters( + std::vector &buf, + const struct Request &rp, + const std::string &rootDir + ) const override; + + virtual void unpackResponseParameters( + struct Request &rp, + const void *src + ) const override; }; -}; +} diff --git a/src/server/protocol/ServerHttp2Stream.cpp b/src/server/protocol/ServerHttp2Stream.cpp index 8a20c8a..346e0f1 100644 --- a/src/server/protocol/ServerHttp2Stream.cpp +++ b/src/server/protocol/ServerHttp2Stream.cpp @@ -5,14 +5,18 @@ namespace HttpServer { - ServerHttp2Stream::ServerHttp2Stream(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls, Http2::IncStream *stream) noexcept + ServerHttp2Stream::ServerHttp2Stream( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls, + Http2::IncStream *stream + ) noexcept : ServerHttp2Protocol(sock, settings, controls, stream) { } - void ServerHttp2Stream::close() - { + void ServerHttp2Stream::close() { this->stream->close(); } @@ -31,19 +35,20 @@ namespace HttpServer auto const it_scheme = headers.find(":scheme"); - if (headers.cend() == it_scheme) - { + if (headers.cend() == it_scheme) { return this; } const std::string &scheme = it_scheme->second; - const int default_port = (scheme == "https") ? 443 : (scheme == "http") ? 80 : 0; + const int default_port = (scheme == "https") + ? 443 + : (scheme == "http") + ? 80 : 0; auto const it_host = headers.find(":authority"); - if (headers.cend() == it_host) - { + if (headers.cend() == it_host) { return this; } @@ -56,20 +61,24 @@ namespace HttpServer req.host = host_header.substr(0, delimiter); // Получить номер порта - const int port = (std::string::npos != delimiter) ? std::strtol(host_header.substr(delimiter + 1).c_str(), nullptr, 10) : default_port; + const int port = std::string::npos != delimiter + ? std::atoi(host_header.substr(delimiter + 1).c_str()) + : default_port; const ServerApplicationSettings *app_sets = this->settings.apps_tree.find(req.host); // Если приложение найдено - if (nullptr == app_sets || (app_sets->ports.cend() == app_sets->ports.find(port) && app_sets->tls_ports.cend() == app_sets->tls_ports.find(port) ) ) - { + if (nullptr == app_sets || ( + app_sets->ports.cend() == app_sets->ports.find(port) && + app_sets->tls_ports.cend() == app_sets->tls_ports.find(port) + ) + ) { return this; } auto const it_method = headers.find(":method"); - if (headers.cend() == it_method) - { + if (headers.cend() == it_method) { return this; } @@ -77,8 +86,7 @@ namespace HttpServer auto const it_path = headers.find(":path"); - if (headers.cend() == it_path) - { + if (headers.cend() == it_path) { return this; } @@ -88,23 +96,25 @@ namespace HttpServer this->runApplication(req, *app_sets); - for (auto const &it : req.incoming_files) - { + for (auto const &it : req.incoming_files) { std::remove(it.second.getTmpName().c_str() ); } - if (EXIT_SUCCESS == req.app_exit_code) - { + if (EXIT_SUCCESS == req.app_exit_code) { // Http2::OutStream out(*stream); // auto tmp = req.protocol_data; // req.protocol_data = &out; - Sendfile::xSendfile(std::ref(*this), req, this->settings.mimes_types); + Sendfile::xSendfile( + std::ref(*this), + req, + this->settings.mimes_types + ); // req.protocol_data = tmp; } return this; } -}; +} diff --git a/src/server/protocol/ServerHttp2Stream.h b/src/server/protocol/ServerHttp2Stream.h index a4c18c1..1181983 100644 --- a/src/server/protocol/ServerHttp2Stream.h +++ b/src/server/protocol/ServerHttp2Stream.h @@ -8,9 +8,14 @@ namespace HttpServer class ServerHttp2Stream : public ServerHttp2Protocol { public: - ServerHttp2Stream(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls, Http2::IncStream *stream) noexcept; + ServerHttp2Stream( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls, + Http2::IncStream *stream + ) noexcept; virtual ServerProtocol *process() override; virtual void close() override; }; -}; +} diff --git a/src/server/protocol/ServerProtocol.cpp b/src/server/protocol/ServerProtocol.cpp index 9adc151..42628eb 100644 --- a/src/server/protocol/ServerProtocol.cpp +++ b/src/server/protocol/ServerProtocol.cpp @@ -4,7 +4,11 @@ namespace HttpServer { - ServerProtocol::ServerProtocol(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls) noexcept + ServerProtocol::ServerProtocol( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls + ) noexcept : sock(sock), settings(settings), controls(controls) { @@ -16,12 +20,15 @@ namespace HttpServer } - DataVariant::DataReceiver *ServerProtocol::createDataReceiver(const Transfer::request_data *rd, const std::unordered_map &variants) - { + DataVariant::DataReceiver * + ServerProtocol::createDataReceiver( + const Transfer::request_data *rd, + const std::unordered_map &variants + ) { auto const it = rd->incoming_headers.find("content-type"); - if (rd->incoming_headers.cend() == it) - { + if (rd->incoming_headers.cend() == it) { return nullptr; } @@ -36,45 +43,64 @@ namespace HttpServer size_t delimiter = header_value.find(';'); // Если есть дополнительные параметры - извлекаем их - if (std::string::npos != delimiter) - { + if (std::string::npos != delimiter) { data_variant_name = header_value.substr(0, delimiter); Utils::trim(data_variant_name); - for (size_t str_param_cur = delimiter + 1, str_param_end = 0; std::string::npos != str_param_end; str_param_cur = str_param_end + 1) - { + for ( + size_t str_param_cur = delimiter + 1, str_param_end = 0; + std::string::npos != str_param_end; + str_param_cur = str_param_end + 1 + ) { str_param_end = header_value.find(';', str_param_cur); delimiter = header_value.find('=', str_param_cur); - if (delimiter >= str_param_end) - { - std::string param_name = header_value.substr(str_param_cur, std::string::npos != str_param_end ? str_param_end - str_param_cur : std::string::npos); + if (delimiter >= str_param_end) { + std::string param_name = header_value.substr( + str_param_cur, + std::string::npos != str_param_end + ? str_param_end - str_param_cur + : std::string::npos + ); + Utils::trim(param_name); - content_params.emplace(std::move(param_name), std::string() ); - } - else - { - std::string param_name = header_value.substr(str_param_cur, delimiter - str_param_cur); + + content_params.emplace( + std::move(param_name), + std::string() + ); + } else { + std::string param_name = header_value.substr( + str_param_cur, + delimiter - str_param_cur + ); + Utils::trim(param_name); ++delimiter; - std::string param_value = header_value.substr(delimiter, std::string::npos != str_param_end ? str_param_end - delimiter : std::string::npos); + std::string param_value = header_value.substr( + delimiter, + std::string::npos != str_param_end + ? str_param_end - delimiter + : std::string::npos + ); + Utils::trim(param_value); - content_params.emplace(std::move(param_name), std::move(param_value) ); + content_params.emplace( + std::move(param_name), + std::move(param_value) + ); } } - } - else - { + } else { data_variant_name = header_value; } auto const variant = variants.find(data_variant_name); - if (variants.cend() == variant) - { + if (variants.cend() == variant) { return nullptr; } @@ -84,9 +110,12 @@ namespace HttpServer auto const it_len = rd->incoming_headers.find("content-length"); - if (rd->incoming_headers.cend() != it_len) - { - data_length = std::strtoull(it_len->second.c_str(), nullptr, 10); + if (rd->incoming_headers.cend() != it_len) { + data_length = std::strtoull( + it_len->second.c_str(), + nullptr, + 10 + ); } return new DataVariant::DataReceiver { @@ -101,12 +130,10 @@ namespace HttpServer { DataVariant::DataReceiver *dr = reinterpret_cast(src); - if (dr) - { + if (dr) { dr->data_variant->destroyStateStruct(dr->ss); - if (dr->reserved) - { + if (dr->reserved) { delete reinterpret_cast(dr->reserved); dr->reserved = nullptr; } @@ -115,13 +142,14 @@ namespace HttpServer delete dr; } - void ServerProtocol::runApplication(struct Request &req, const ServerApplicationSettings &appSets) const - { + void ServerProtocol::runApplication( + struct Request &req, + const ServerApplicationSettings &appSets + ) const { std::vector buf; buf.reserve(4096); - if (false == this->packRequestParameters(buf, req, appSets.root_dir) ) - { + if (this->packRequestParameters(buf, req, appSets.root_dir) == false) { return; } @@ -135,32 +163,27 @@ namespace HttpServer nullptr, 0 }; - try - { + try { // Launch application req.app_exit_code = appSets.application_call(&request, &response); } - catch (std::exception &exc) - { + catch (std::exception &exc) { // TODO: exception output } if (response.response_data && response.data_size) { - if (EXIT_SUCCESS == req.app_exit_code) - { + if (EXIT_SUCCESS == req.app_exit_code) { this->unpackResponseParameters(req, response.response_data); } // Clear outgoing data of application - try - { + try { appSets.application_clear(response.response_data, response.data_size); } - catch (std::exception &exc) - { + catch (std::exception &exc) { // TODO: exception output } } } -}; +} diff --git a/src/server/protocol/ServerProtocol.h b/src/server/protocol/ServerProtocol.h index 91f5b3a..e53fea6 100644 --- a/src/server/protocol/ServerProtocol.h +++ b/src/server/protocol/ServerProtocol.h @@ -16,24 +16,56 @@ namespace HttpServer ServerControls &controls; public: - ServerProtocol(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls) noexcept; + ServerProtocol( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls + ) noexcept; + ServerProtocol(const ServerProtocol &prot) noexcept; virtual ~ServerProtocol() noexcept = default; - static DataVariant::DataReceiver *createDataReceiver(const Transfer::request_data *rd, const std::unordered_map &variants); + static DataVariant::DataReceiver * + createDataReceiver( + const Transfer::request_data *rd, + const std::unordered_map &variants + ); + static void destroyDataReceiver(void *src); protected: - void runApplication(struct Request &req, const ServerApplicationSettings &appSets) const; + void runApplication( + struct Request &req, + const ServerApplicationSettings &appSets + ) const; public: - 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, size_t size, const std::chrono::milliseconds &timeout, DataTransfer *dt) const = 0; + 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, + size_t size, + const std::chrono::milliseconds &timeout, + DataTransfer *dt + ) const = 0; + + virtual bool packRequestParameters( + std::vector &buf, + const struct Request &req, + const std::string &rootDir + ) const = 0; - virtual bool packRequestParameters(std::vector &buf, const struct Request &req, const std::string &rootDir) const = 0; - virtual void unpackResponseParameters(struct Request &req, const void *src) const = 0; + virtual void unpackResponseParameters( + struct Request &req, + const void *src + ) const = 0; virtual ServerProtocol *process() = 0; virtual void close() = 0; }; -}; +} diff --git a/src/server/protocol/ServerWebSocket.cpp b/src/server/protocol/ServerWebSocket.cpp index 5c03f1a..2951e73 100644 --- a/src/server/protocol/ServerWebSocket.cpp +++ b/src/server/protocol/ServerWebSocket.cpp @@ -3,7 +3,11 @@ namespace HttpServer { - ServerWebSocket::ServerWebSocket(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls) noexcept + ServerWebSocket::ServerWebSocket( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls + ) noexcept : ServerProtocol(sock, settings, controls) { @@ -15,33 +19,42 @@ namespace HttpServer } - bool ServerWebSocket::sendHeaders(const Http::StatusCode status, std::vector > &headers, const std::chrono::milliseconds &timeout, const bool endStream) const - { + bool ServerWebSocket::sendHeaders( + const Http::StatusCode status, + std::vector > &headers, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const { return false; } - long ServerWebSocket::sendData(const void *src, size_t size, const std::chrono::milliseconds &timeout, DataTransfer *dt) const - { + long ServerWebSocket::sendData( + const void *src, + size_t size, + const std::chrono::milliseconds &timeout, + DataTransfer *dt + ) const { return 0; } - bool ServerWebSocket::packRequestParameters(std::vector &buf, const struct Request &rp, const std::string &rootDir) const - { + bool ServerWebSocket::packRequestParameters( + std::vector &buf, + const struct Request &rp, + const std::string &rootDir + ) const { return false; } - void ServerWebSocket::unpackResponseParameters(struct Request &req, const void *src) const - { + void ServerWebSocket::unpackResponseParameters( + struct Request &req, + const void *src + ) const { } - ServerProtocol *ServerWebSocket::process() - { + ServerProtocol *ServerWebSocket::process() { return this; } - void ServerWebSocket::close() - { - - } -}; + void ServerWebSocket::close() {} +} diff --git a/src/server/protocol/ServerWebSocket.h b/src/server/protocol/ServerWebSocket.h index 094293f..5745f7e 100644 --- a/src/server/protocol/ServerWebSocket.h +++ b/src/server/protocol/ServerWebSocket.h @@ -7,16 +7,40 @@ namespace HttpServer class ServerWebSocket : public ServerProtocol { public: - ServerWebSocket(Socket::Adapter &sock, const ServerSettings &settings, ServerControls &controls) noexcept; + ServerWebSocket( + Socket::Adapter &sock, + const ServerSettings &settings, + ServerControls &controls + ) noexcept; + ServerWebSocket(const ServerProtocol &prot) noexcept; - virtual bool sendHeaders(const Http::StatusCode status, std::vector > &headers, const std::chrono::milliseconds &timeout, const bool endStream) const override; - virtual long sendData(const void *src, size_t size, const std::chrono::milliseconds &timeout, DataTransfer *dt) const override; + virtual bool sendHeaders( + const Http::StatusCode status, + std::vector > &headers, + const std::chrono::milliseconds &timeout, + const bool endStream + ) const override; + + virtual long sendData( + const void *src, + size_t size, + const std::chrono::milliseconds &timeout, + DataTransfer *dt + ) const override; + + virtual bool packRequestParameters( + std::vector &buf, + const struct Request &rp, + const std::string &rootDir + ) const override; - virtual bool packRequestParameters(std::vector &buf, const struct Request &rp, const std::string &rootDir) const override; - virtual void unpackResponseParameters(struct Request &req, const void *src) const override; + virtual void unpackResponseParameters( + struct Request &req, + const void *src + ) const override; virtual ServerProtocol *process() override; virtual void close() override; }; -}; +} diff --git a/src/server/protocol/extensions/Sendfile.cpp b/src/server/protocol/extensions/Sendfile.cpp index 9c557ba..1758515 100644 --- a/src/server/protocol/extensions/Sendfile.cpp +++ b/src/server/protocol/extensions/Sendfile.cpp @@ -6,15 +6,21 @@ namespace HttpServer { - static std::string getMimeTypeByFileName(const std::string &fileName, const std::unordered_map &mimesTypes) noexcept - { + static std::string getMimeTypeByFileName( + const std::string &fileName, + const std::unordered_map &mimesTypes + ) noexcept { const size_t ext_pos = fileName.rfind('.'); - const std::string file_ext = Utils::getLowerString(std::string::npos != ext_pos ? fileName.substr(ext_pos + 1) : std::string() ); + const std::string file_ext = std::string::npos != ext_pos + ? Utils::getLowerString(fileName.substr(ext_pos + 1) ) + : std::string(); auto const it_mime = mimesTypes.find(file_ext); - return mimesTypes.cend() != it_mime ? it_mime->second : std::string("application/octet-stream"); + return mimesTypes.cend() == it_mime + ? std::string("application/octet-stream") + : it_mime->second; } static std::vector > getRanges( @@ -23,15 +29,17 @@ namespace HttpServer const size_t fileSize, std::string *resultRangeHeader, size_t *contentLength - ) noexcept - { + ) noexcept { std::vector > ranges; *contentLength = 0; size_t delimiter = posSymEqual; // rangeHeader.find('='); - const std::string range_unit_name(rangeHeader.cbegin(), rangeHeader.cbegin() + delimiter); + const std::string range_unit_name( + rangeHeader.cbegin(), + rangeHeader.cbegin() + delimiter + ); static const std::unordered_map ranges_units { { "bytes", 1 } @@ -39,8 +47,7 @@ namespace HttpServer auto const it_unit = ranges_units.find(range_unit_name); - if (ranges_units.cend() == it_unit) - { + if (ranges_units.cend() == it_unit) { return ranges; } @@ -49,30 +56,41 @@ namespace HttpServer for (size_t str_pos; std::string::npos != delimiter; ) { str_pos = delimiter + 1; - delimiter = rangeHeader.find(',', str_pos); const size_t range_pos = rangeHeader.find('-', str_pos); if (range_pos < delimiter) { - const std::string range_begin_str(rangeHeader.cbegin() + str_pos, rangeHeader.cbegin() + range_pos); - const std::string range_end_str(rangeHeader.cbegin() + range_pos + 1, std::string::npos == delimiter ? rangeHeader.cend() : rangeHeader.cbegin() + delimiter); - - if (false == range_begin_str.empty() ) + const std::string range_begin_str( + rangeHeader.cbegin() + str_pos, + rangeHeader.cbegin() + range_pos + ); + + const std::string range_end_str( + rangeHeader.cbegin() + range_pos + 1, + std::string::npos == delimiter + ? rangeHeader.cend() + : rangeHeader.cbegin() + delimiter + ); + + if (range_begin_str.empty() == false) { - const size_t range_begin = std::strtoull(range_begin_str.c_str(), nullptr, 10) * range_unit; + const size_t range_begin = std::strtoull( + range_begin_str.c_str(), nullptr, 10 + ) * range_unit; if (range_begin < fileSize) { - if (false == range_end_str.empty() ) + if (range_end_str.empty() == false) { - size_t range_end = std::strtoull(range_end_str.c_str(), nullptr, 10) * range_unit; + size_t range_end = std::strtoull( + range_end_str.c_str(), nullptr, 10 + ) * range_unit; if (range_end >= range_begin) { - if (range_end > fileSize) - { + if (range_end > fileSize) { range_end = fileSize; } @@ -93,15 +111,21 @@ namespace HttpServer *resultRangeHeader += std::to_string(range_begin) + '-' + std::to_string(fileSize - 1) + ','; - ranges.emplace_back(std::tuple {range_begin, length}); + ranges.emplace_back(std::tuple { + range_begin, length + }); } } } - else if (false == range_end_str.empty() ) // if range_begin_str empty + else if (range_end_str.empty() == false) // if range_begin_str empty { - size_t range_end = std::strtoull(range_end_str.c_str(), nullptr, 10) * range_unit; + size_t range_end = std::strtoull( + range_end_str.c_str(), nullptr, 10 + ) * range_unit; - const size_t length = range_end < fileSize ? fileSize - range_end : fileSize; + const size_t length = range_end < fileSize + ? fileSize - range_end + : fileSize; const size_t range_begin = fileSize - length; @@ -111,15 +135,15 @@ namespace HttpServer *resultRangeHeader += std::to_string(range_begin) + '-' + std::to_string(range_end) + ','; - ranges.emplace_back(std::tuple {range_begin, length}); + ranges.emplace_back(std::tuple { + range_begin, length + }); } } } - if (false == ranges.empty() ) - { + if (ranges.empty() == false) { (*resultRangeHeader).back() = '/'; - *resultRangeHeader = "bytes " + *resultRangeHeader + std::to_string(fileSize); } @@ -136,13 +160,15 @@ namespace HttpServer const std::string &rangeHeader, std::vector > &additionalHeaders, const bool headersOnly - ) noexcept - { + ) noexcept { const size_t pos_sym_equal = rangeHeader.find('='); - if (std::string::npos == pos_sym_equal) - { - prot.sendHeaders(Http::StatusCode::BAD_REQUEST, additionalHeaders, req.timeout); + if (std::string::npos == pos_sym_equal) { + prot.sendHeaders( + Http::StatusCode::BAD_REQUEST, + additionalHeaders, + req.timeout + ); return 1; } @@ -151,11 +177,20 @@ namespace HttpServer size_t content_length; - const std::vector > ranges = getRanges(rangeHeader, pos_sym_equal, fileSize, &content_range_header, &content_length); - - if (0 == content_length) - { - prot.sendHeaders(Http::StatusCode::REQUESTED_RANGE_NOT_SATISFIABLE, additionalHeaders, req.timeout); + const std::vector > ranges = getRanges( + rangeHeader, + pos_sym_equal, + fileSize, + &content_range_header, + &content_length + ); + + if (0 == content_length) { + prot.sendHeaders( + Http::StatusCode::REQUESTED_RANGE_NOT_SATISFIABLE, + additionalHeaders, + req.timeout + ); return 2; } @@ -163,11 +198,14 @@ namespace HttpServer // Ranges transfer std::ifstream file(fileName, std::ifstream::binary); - if ( ! file) - { + if ( ! file) { file.close(); - prot.sendHeaders(Http::StatusCode::INTERNAL_SERVER_ERROR, additionalHeaders, req.timeout); + prot.sendHeaders( + Http::StatusCode::INTERNAL_SERVER_ERROR, + additionalHeaders, + req.timeout + ); return 3; } @@ -181,10 +219,14 @@ namespace HttpServer additionalHeaders.emplace_back("last-modified", Utils::getDatetimeAsString(fileTime, true) ); // Отправить заголовки (206 Partial Content) - if (false == prot.sendHeaders(Http::StatusCode::PARTIAL_CONTENT, additionalHeaders, req.timeout, headersOnly) ) - { + if (prot.sendHeaders( + Http::StatusCode::PARTIAL_CONTENT, + additionalHeaders, + req.timeout, + headersOnly + ) == false + ) { file.close(); - return 4; } @@ -203,7 +245,11 @@ namespace HttpServer { std::tie(position, length) = range; - buf.resize(length < 512 * 1024 ? length : 512 * 1024); + buf.resize( + length < 512 * 1024 + ? length + : 512 * 1024 + ); file.seekg(position, file.beg); @@ -211,10 +257,8 @@ namespace HttpServer long send_size; - do - { - if (send_size_left < 512 * 1024) - { + do { + if (send_size_left < 512 * 1024) { buf.resize(send_size_left); } @@ -222,7 +266,12 @@ namespace HttpServer auto const read_size = file.gcount(); - send_size = prot.sendData(buf.data(), read_size, req.timeout, &dt); + send_size = prot.sendData( + buf.data(), + read_size, + req.timeout, + &dt + ); send_size_left -= send_size; } @@ -245,8 +294,7 @@ namespace HttpServer const std::unordered_map &mimesTypes, std::vector > &additionalHeaders, const bool headersOnly - ) noexcept - { + ) noexcept { // Get current time in GMT additionalHeaders.emplace_back("date", Utils::getDatetimeAsString() ); @@ -254,9 +302,12 @@ namespace HttpServer size_t file_size; // Получить размер файла и дату последнего изменения - if (false == System::getFileSizeAndTimeGmt(fileName, &file_size, &file_time) ) - { - prot.sendHeaders(Http::StatusCode::NOT_FOUND, additionalHeaders, req.timeout); + if (System::getFileSizeAndTimeGmt(fileName, &file_size, &file_time) == false) { + prot.sendHeaders( + Http::StatusCode::NOT_FOUND, + additionalHeaders, + req.timeout + ); return 1; } @@ -265,13 +316,15 @@ namespace HttpServer auto const it_modified = req.incoming_headers.find("if-modified-since"); // Если найден заголовок проверки изменения файла (проверить, изменялся ли файл) - if (req.incoming_headers.cend() != it_modified) - { + if (req.incoming_headers.cend() != it_modified) { const time_t time_in_request = Utils::rfc822DatetimeToTimestamp(it_modified->second); - if (file_time == time_in_request) - { - prot.sendHeaders(Http::StatusCode::NOT_MODIFIED, additionalHeaders, req.timeout); + if (file_time == time_in_request) { + prot.sendHeaders( + Http::StatusCode::NOT_MODIFIED, + additionalHeaders, + req.timeout + ); return 2; } @@ -280,19 +333,31 @@ namespace HttpServer auto const it_range = req.incoming_headers.find("range"); // Range transfer - if (req.incoming_headers.cend() != it_range) - { - return transferFilePart(prot, req, fileName, mimesTypes, file_time, file_size, it_range->second, additionalHeaders, headersOnly); + if (req.incoming_headers.cend() != it_range) { + return transferFilePart( + prot, + req, + fileName, + mimesTypes, + file_time, + file_size, + it_range->second, + additionalHeaders, + headersOnly + ); } // File transfer std::ifstream file(fileName, std::ifstream::binary); - if ( ! file) - { + if ( ! file) { file.close(); - prot.sendHeaders(Http::StatusCode::INTERNAL_SERVER_ERROR, additionalHeaders, req.timeout); + prot.sendHeaders( + Http::StatusCode::INTERNAL_SERVER_ERROR, + additionalHeaders, + req.timeout + ); return 3; } @@ -305,17 +370,25 @@ namespace HttpServer additionalHeaders.emplace_back("last-modified", Utils::getDatetimeAsString(file_time, true) ); // Отправить заголовки (200 OK) - if (false == prot.sendHeaders(Http::StatusCode::OK, additionalHeaders, req.timeout, headersOnly || 0 == file_size) ) - { + if (prot.sendHeaders( + Http::StatusCode::OK, + additionalHeaders, + req.timeout, + headersOnly || 0 == file_size + ) == false + ) { file.close(); - return 4; } // Отправить файл if (false == headersOnly && file_size) { - std::vector buf(file_size < 512 * 1024 ? file_size : 512 * 1024); + std::vector buf( + file_size < 512 * 1024 + ? file_size + : 512 * 1024 + ); long send_size; @@ -324,10 +397,15 @@ namespace HttpServer 0 }; - do - { + do { file.read(buf.data(), buf.size() ); - send_size = prot.sendData(buf.data(), file.gcount(), req.timeout, &dt); + + send_size = prot.sendData( + buf.data(), + file.gcount(), + req.timeout, + &dt + ); } while (false == file.eof() && false == file.fail() && send_size > 0 && (dt.full_size - dt.send_total) ); } @@ -337,8 +415,7 @@ namespace HttpServer return 0; } - bool Sendfile::isConnectionReuse(const struct Request &req) noexcept - { + bool Sendfile::isConnectionReuse(const struct Request &req) noexcept { return (req.connection_params & ConnectionParams::CONNECTION_REUSE) == ConnectionParams::CONNECTION_REUSE; } @@ -346,30 +423,32 @@ namespace HttpServer const ServerProtocol &prot, struct Request &req, const std::unordered_map &mimesTypes - ) noexcept - { + ) noexcept { auto const it_x_sendfile = req.outgoing_headers.find("x-sendfile"); if (req.outgoing_headers.cend() != it_x_sendfile) { std::vector > additional_headers; - if (Transfer::ProtocolVariant::HTTP_1 == req.protocol_variant) - { - if (isConnectionReuse(req) ) - { + if (Transfer::ProtocolVariant::HTTP_1 == req.protocol_variant) { + if (isConnectionReuse(req) ) { additional_headers.emplace_back("connection", "keep-alive"); additional_headers.emplace_back("keep-alive", "timeout=5; max=" + std::to_string(req.keep_alive_count) ); - } - else - { + } else { additional_headers.emplace_back("connection", "close"); } } const bool headers_only = ("head" == req.method); - transferFile(prot, req, it_x_sendfile->second, mimesTypes, additional_headers, headers_only); + transferFile( + prot, + req, + it_x_sendfile->second, + mimesTypes, + additional_headers, + headers_only + ); } } -}; +} diff --git a/src/server/protocol/extensions/Sendfile.h b/src/server/protocol/extensions/Sendfile.h index eb2823b..23793d0 100644 --- a/src/server/protocol/extensions/Sendfile.h +++ b/src/server/protocol/extensions/Sendfile.h @@ -38,4 +38,4 @@ namespace HttpServer const std::unordered_map &mimesTypes ) noexcept; }; -}; +} diff --git a/src/socket/Adapter.cpp b/src/socket/Adapter.cpp index 0c50bc3..c99bee6 100644 --- a/src/socket/Adapter.cpp +++ b/src/socket/Adapter.cpp @@ -3,12 +3,26 @@ 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 { diff --git a/src/socket/Adapter.h b/src/socket/Adapter.h index 35b3964..2787176 100644 --- a/src/socket/Adapter.h +++ b/src/socket/Adapter.h @@ -19,11 +19,27 @@ 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; diff --git a/src/socket/AdapterDefault.cpp b/src/socket/AdapterDefault.cpp index 1f2fe36..2940daf 100644 --- a/src/socket/AdapterDefault.cpp +++ b/src/socket/AdapterDefault.cpp @@ -3,25 +3,33 @@ 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 { return sock.get_handle(); } ::gnutls_session_t AdapterDefault::get_tls_session() const noexcept { - return 0; + return nullptr; } 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); } diff --git a/src/socket/AdapterDefault.h b/src/socket/AdapterDefault.h index d743783..db8b191 100644 --- a/src/socket/AdapterDefault.h +++ b/src/socket/AdapterDefault.h @@ -18,8 +18,17 @@ 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 b63bf73..118e885 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 @@ -39,6 +42,8 @@ namespace Socket { int ret; + ::gnutls_handshake_set_timeout(this->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); + do { ret = ::gnutls_handshake(this->session); } @@ -56,9 +61,10 @@ 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) { @@ -67,8 +73,6 @@ namespace Socket Socket sock(this->get_handle() ); - // ::gnutls_record_set_timeout(this->session, static_cast(timeout.count() ) ); - size_t total = 0; while (total < length) { @@ -80,7 +84,12 @@ namespace Socket do { sock.nonblock_send_sync(); - send_size = ::gnutls_record_send(this->session, reinterpret_cast(buf) + total, record_size); + + send_size = ::gnutls_record_send( + this->session, + reinterpret_cast(buf) + total, + record_size + ); } while (GNUTLS_E_AGAIN == send_size); @@ -95,7 +104,9 @@ namespace Socket } System::native_socket_type AdapterTls::get_handle() const noexcept { - return static_cast(::gnutls_transport_get_int(this->session) ); + return static_cast( + ::gnutls_transport_get_int(this->session) + ); } ::gnutls_session_t AdapterTls::get_tls_session() const noexcept { @@ -106,8 +117,11 @@ namespace Socket return new AdapterTls(this->session); } - long AdapterTls::nonblock_recv(void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept - { + long AdapterTls::nonblock_recv( + void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) const noexcept { Socket sock(this->get_handle() ); long result; @@ -126,7 +140,11 @@ namespace Socket 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); } diff --git a/src/socket/AdapterTls.h b/src/socket/AdapterTls.h index 27bad11..04aab40 100644 --- a/src/socket/AdapterTls.h +++ b/src/socket/AdapterTls.h @@ -12,18 +12,38 @@ 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 1746a79..a1accbd 100644 --- a/src/socket/List.cpp +++ b/src/socket/List.cpp @@ -16,7 +16,7 @@ namespace Socket #elif POSIX this->obj_list = ~0; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -30,7 +30,7 @@ namespace Socket obj.obj_list = ~0; obj.epoll_events.swap(this->epoll_events); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -63,7 +63,7 @@ namespace Socket return true; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -79,7 +79,7 @@ namespace Socket this->obj_list = ~0; this->epoll_events.clear(); #else - #error "Undefine platform" + #error "Undefined platform" #endif } } @@ -91,7 +91,7 @@ namespace Socket #elif POSIX return this->obj_list != ~0; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -102,7 +102,7 @@ namespace Socket } #ifdef WIN32 - WSAPOLLFD event = { + WSAPOLLFD event { sock.get_handle(), POLLRDNORM, 0 @@ -112,12 +112,17 @@ 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) { return false; @@ -127,7 +132,7 @@ namespace Socket return true; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -147,7 +152,12 @@ 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) { return false; @@ -157,7 +167,7 @@ namespace Socket return true; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -166,7 +176,11 @@ 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) { return false; @@ -181,7 +195,11 @@ namespace Socket System::native_socket_type client_socket = ~0; do { - client_socket = ::accept(event.fd, static_cast(nullptr), static_cast(nullptr) ); + client_socket = ::accept( + event.fd, + static_cast(nullptr), + static_cast(nullptr) + ); if (~0 != client_socket) { sockets.emplace_back(Socket(client_socket) ); @@ -193,7 +211,12 @@ 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); + const int count = ::epoll_wait( + this->obj_list, + this->epoll_events.data(), + this->epoll_events.size(), + ~0 + ); if (count == ~0) { return false; @@ -208,7 +231,11 @@ namespace Socket System::native_socket_type client_socket = ~0; do { - client_socket = ::accept(event.data.fd, static_cast(nullptr), static_cast(nullptr) ); + client_socket = ::accept( + event.data.fd, + static_cast(nullptr), + static_cast(nullptr) + ); if (~0 != client_socket) { sockets.emplace_back(Socket(client_socket) ); @@ -220,19 +247,25 @@ 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) { return false; @@ -250,7 +283,11 @@ namespace Socket ::sockaddr_in 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) { sockets.emplace_back(Socket(client_socket) ); @@ -263,7 +300,12 @@ 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); + const int count = ::epoll_wait( + this->obj_list, + this->epoll_events.data(), + this->epoll_events.size(), + ~0 + ); if (count == ~0) { return false; @@ -281,7 +323,11 @@ namespace Socket ::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) { sockets.emplace_back(Socket(client_socket) ); @@ -294,21 +340,28 @@ 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 - { + 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) { return false; @@ -328,7 +381,12 @@ namespace Socket 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() ); + const int count = ::epoll_wait( + this->obj_list, + this->epoll_events.data(), + this->epoll_events.size(), + timeout.count() + ); if (count == ~0) { return false; @@ -348,7 +406,7 @@ namespace Socket 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 19f83b0..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 96bd194..54904d3 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,7 +44,7 @@ namespace Socket #elif POSIX return errno; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -54,7 +54,9 @@ namespace Socket 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; } @@ -73,7 +75,7 @@ namespace Socket #elif POSIX const int result = ::close(this->socket_handle); #else - #error "Undefine platform" + #error "Undefined platform" #endif if (0 == result) { @@ -92,7 +94,7 @@ namespace Socket #elif POSIX return ~0 != this->socket_handle; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -100,16 +102,19 @@ namespace Socket 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 { @@ -119,11 +124,19 @@ namespace Socket 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); } @@ -132,27 +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) ); + 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) ); + client_socket = ::accept( + this->socket_handle, + static_cast(nullptr), + static_cast(nullptr) + ); } #else - #error "Undefine platform" + #error "Undefined platform" #endif return Socket(client_socket); } @@ -161,27 +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) ); + 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); } @@ -195,7 +224,7 @@ namespace Socket #elif POSIX return 0 == ::shutdown(this->socket_handle, SHUT_RDWR); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -208,9 +237,15 @@ namespace Socket unsigned long value = isNonBlock; 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 } @@ -223,7 +258,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 } */ @@ -232,67 +267,106 @@ 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); + 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; } - bool Socket::nonblock_recv_sync(const std::chrono::milliseconds &timeout) const noexcept - { + bool Socket::nonblock_recv_sync( + const std::chrono::milliseconds &timeout + ) const noexcept { #ifdef WIN32 - WSAPOLLFD event = { + WSAPOLLFD event { this->socket_handle, POLLIN, 0 @@ -300,30 +374,38 @@ namespace Socket return ::WSAPoll(&event, 1, timeout.count() ) == 1; #elif POSIX - struct ::pollfd event = { + struct ::pollfd event { this->socket_handle, POLLIN, 0 }; - return ::poll(&event, 1, timeout.count() ) == 1; + 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); + const long send_size = ::send( + socket_handle, + reinterpret_cast(data) + total, + length - total, + 0 + ); if (send_size < 0) { return send_size; } - total += send_size; + total += static_cast(send_size); } return static_cast(total); @@ -337,8 +419,12 @@ namespace Socket 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 @@ -350,7 +436,12 @@ namespace Socket while (total < length) { if (1 == ::WSAPoll(&event, 1, static_cast<::INT>(timeout.count() ) ) && event.revents & POLLOUT) { - const long send_size = ::send(socket_handle, reinterpret_cast(data) + total, static_cast(length - total), 0); + const long send_size = ::send( + socket_handle, + reinterpret_cast(data) + total, + static_cast(length - total), + 0 + ); if (send_size < 0) { return send_size; @@ -370,37 +461,58 @@ namespace Socket }; 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); + 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) { return send_size; } - total += send_size; + total += static_cast(send_size); } else { return -1; } } #else - #error "Undefine platform" + #error "Undefined platform" #endif return static_cast(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, POLLOUT, 0 @@ -408,7 +520,7 @@ namespace Socket ::WSAPoll(&event, 1, ~0); #elif POSIX - struct ::pollfd event = { + struct ::pollfd event { this->socket_handle, POLLOUT, 0 @@ -416,7 +528,7 @@ namespace Socket ::poll(&event, 1, ~0); #else - #error "Undefine platform" + #error "Undefined platform" #endif } diff --git a/src/socket/Socket.h b/src/socket/Socket.h index e0bfc6c..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(void *buf, const size_t length, const std::chrono::milliseconds &timeout) const noexcept; + long nonblock_recv( + std::vector &buf, + const std::chrono::milliseconds &timeout + ) const noexcept; - bool nonblock_recv_sync(const std::chrono::milliseconds &timeout) const noexcept; + long nonblock_recv( + void *buf, + const size_t length, + const std::chrono::milliseconds &timeout + ) 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; diff --git a/src/system/GlobalMutex.cpp b/src/system/GlobalMutex.cpp index 2079b4e..0c72d06 100644 --- a/src/system/GlobalMutex.cpp +++ b/src/system/GlobalMutex.cpp @@ -13,7 +13,8 @@ namespace System { - GlobalMutex::GlobalMutex() noexcept : mtx_desc(nullptr) + GlobalMutex::GlobalMutex() noexcept + : mtx_desc(nullptr) { } @@ -40,22 +41,25 @@ namespace System this->mtx_desc = ::CreateMutex(nullptr, false, mutex_name.c_str() ); - if (nullptr == this->mtx_desc) - { + if (nullptr == this->mtx_desc) { return false; } #elif POSIX - ::sem_t *sem = ::sem_open(mutexName.c_str(), O_CREAT, 0666, 1); - - if (SEM_FAILED == sem) - { + ::sem_t *sem = ::sem_open( + mutexName.c_str(), + O_CREAT, + 0666, + 1 + ); + + if (SEM_FAILED == sem) { return false; } this->mtx_desc = sem; this->mtx_name = mutexName; #else - #error "Undefine platform" + #error "Undefined platform" #endif return true; @@ -79,7 +83,7 @@ namespace System #elif POSIX return 0 == ::sem_unlink(mutexName.c_str() ); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -101,13 +105,15 @@ namespace System return ret; #elif POSIX - const int ret = ::sem_unlink(this->mtx_name.c_str() ); + const int ret = ::sem_unlink( + this->mtx_name.c_str() + ); - this->close(); + this->close(); - return 0 == ret; + return 0 == ret; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -128,21 +134,22 @@ namespace System this->mtx_desc = ::OpenMutex(SYNCHRONIZE, false, mutex_name.c_str() ); - if (nullptr == this->mtx_desc) - { + if (nullptr == this->mtx_desc) { return false; } #elif POSIX - ::sem_t *sem = ::sem_open(mutexName.c_str(), 0); + ::sem_t *sem = ::sem_open( + mutexName.c_str(), + 0 + ); - if (SEM_FAILED == sem) - { + if (SEM_FAILED == sem) { return false; } this->mtx_desc = sem; #else - #error "Undefine platform" + #error "Undefined platform" #endif this->mtx_name = mutexName; @@ -161,7 +168,7 @@ namespace System ::sem_close(this->mtx_desc); this->mtx_desc = nullptr; #else - #error "Undefine platform" + #error "Undefined platform" #endif this->mtx_name.clear(); @@ -179,7 +186,7 @@ namespace System #elif POSIX return nullptr != this->mtx_desc; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -190,7 +197,7 @@ namespace System #elif POSIX return 0 == ::sem_wait(this->mtx_desc); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -201,7 +208,7 @@ namespace System #elif POSIX return 0 == ::sem_trywait(this->mtx_desc); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -212,7 +219,7 @@ namespace System #elif POSIX return 0 == ::sem_post(this->mtx_desc); #else - #error "Undefine platform" + #error "Undefined platform" #endif } -}; +} diff --git a/src/system/GlobalMutex.h b/src/system/GlobalMutex.h index 5250d78..d6bc0b0 100644 --- a/src/system/GlobalMutex.h +++ b/src/system/GlobalMutex.h @@ -19,7 +19,7 @@ namespace System #elif POSIX ::sem_t *mtx_desc; #else - #error "Undefine platform" + #error "Undefined platform" #endif std::string mtx_name; @@ -42,4 +42,4 @@ namespace System bool try_lock() const noexcept; bool unlock() const noexcept; }; -}; +} diff --git a/src/system/Module.cpp b/src/system/Module.cpp index 8cbddb1..a417a59 100644 --- a/src/system/Module.cpp +++ b/src/system/Module.cpp @@ -14,36 +14,38 @@ namespace System { - Module::Module() noexcept : lib_handle(nullptr) + Module::Module() noexcept + : lib_handle(nullptr) { } - Module::Module(const std::string &libPath): lib_handle(nullptr) + Module::Module(const std::string &libPath) + : lib_handle(nullptr) { open(libPath); } - Module::Module(const Module &obj) noexcept : lib_handle(obj.lib_handle) + Module::Module(const Module &obj) noexcept + : lib_handle(obj.lib_handle) { } - Module::Module(Module &&obj) noexcept : lib_handle(obj.lib_handle) + Module::Module(Module &&obj) noexcept + : lib_handle(obj.lib_handle) { obj.lib_handle = nullptr; } - bool Module::is_open() const noexcept - { + bool Module::is_open() const noexcept { return nullptr != this->lib_handle; } bool Module::open(const std::string &libPath) { - if (is_open() ) - { - close(); + if (this->is_open() ) { + this->close(); } #ifdef WIN32 @@ -77,19 +79,18 @@ namespace System const std::string &lib_path = libPath; #endif - lib_handle = ::LoadLibraryEx(lib_path.c_str(), 0, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + this->lib_handle = ::LoadLibraryEx(lib_path.c_str(), 0, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); - if (cookie) - { + if (cookie) { ::RemoveDllDirectory(cookie); } #elif POSIX - lib_handle = ::dlopen(libPath.c_str(), RTLD_NOW | RTLD_LOCAL); + this->lib_handle = ::dlopen(libPath.c_str(), RTLD_NOW | RTLD_LOCAL); #else - #error "Undefine platform" + #error "Undefined platform" #endif - if (nullptr == lib_handle) + if (nullptr == this->lib_handle) { #ifdef POSIX std::cout << ::dlerror() << std::endl; @@ -102,85 +103,89 @@ namespace System void Module::close() noexcept { - if (lib_handle) + if (this->lib_handle) { #ifdef WIN32 - ::FreeLibrary(lib_handle); + ::FreeLibrary(this->lib_handle); #elif POSIX - ::dlclose(lib_handle); + ::dlclose(this->lib_handle); #else - #error "Undefine platform" + #error "Undefined platform" #endif - lib_handle = nullptr; + this->lib_handle = nullptr; } } - bool Module::find(const std::string &symbolName, void *(**addr)(void *) ) const noexcept - { + bool Module::find( + const std::string &symbolName, + void *(**addr)(void *) + ) const noexcept { if (lib_handle) { #ifdef WIN32 - *addr = reinterpret_cast(::GetProcAddress(lib_handle, symbolName.c_str() ) ); + *addr = reinterpret_cast(::GetProcAddress(this->lib_handle, symbolName.c_str() ) ); return nullptr != *addr; #elif POSIX char *error = ::dlerror(); - *addr = reinterpret_cast(::dlsym(lib_handle, symbolName.c_str() ) ); + *addr = reinterpret_cast( + ::dlsym(this->lib_handle, symbolName.c_str() ) + ); error = ::dlerror(); return nullptr == error; #else - #error "Undefine platform" + #error "Undefined platform" #endif } return false; } - bool Module::find(const char *symbolName, void *(**addr)(void *) ) const noexcept - { + bool Module::find( + const char *symbolName, + void *(**addr)(void *) + ) const noexcept { if (lib_handle) { #ifdef WIN32 - *addr = reinterpret_cast(::GetProcAddress(lib_handle, symbolName) ); + *addr = reinterpret_cast(::GetProcAddress(this->lib_handle, symbolName) ); return nullptr != *addr; #elif POSIX char *error = ::dlerror(); - *addr = reinterpret_cast(::dlsym(lib_handle, symbolName) ); + *addr = reinterpret_cast( + ::dlsym(this->lib_handle, symbolName) + ); error = ::dlerror(); return nullptr == error; #else - #error "Undefine platform" + #error "Undefined platform" #endif } return false; } - bool Module::operator ==(const Module &obj) const noexcept - { + bool Module::operator ==(const Module &obj) const noexcept { return this->lib_handle == obj.lib_handle; } - bool Module::operator !=(const Module &obj) const noexcept - { + bool Module::operator !=(const Module &obj) const noexcept { return this->lib_handle != obj.lib_handle; } Module &Module::operator =(const Module &obj) noexcept { - if (*this != obj) - { - close(); - - lib_handle = obj.lib_handle; + if (*this != obj) { + this->close(); + this->lib_handle = obj.lib_handle; } return *this; @@ -188,15 +193,12 @@ namespace System Module &Module::operator =(Module &&obj) noexcept { - if (*this != obj) - { - close(); - - lib_handle = obj.lib_handle; - + if (*this != obj) { + this->close(); + this->lib_handle = obj.lib_handle; obj.lib_handle = nullptr; } return *this; } -}; +} diff --git a/src/system/Module.h b/src/system/Module.h index 49e2e34..d7739ed 100644 --- a/src/system/Module.h +++ b/src/system/Module.h @@ -17,7 +17,7 @@ namespace System #elif POSIX void *lib_handle; #else - #error "Undefine platform" + #error "Undefined platform" #endif public: @@ -33,8 +33,15 @@ namespace System bool open(const std::string &libPath); void close() noexcept; - bool find(const std::string &symbolName, void *(**addr)(void *) ) const noexcept; - bool find(const char *symbolName, void *(**addr)(void *) ) const noexcept; + bool find( + const std::string &symbolName, + void *(**addr)(void *) + ) const noexcept; + + bool find( + const char *symbolName, + void *(**addr)(void *) + ) const noexcept; bool operator ==(const Module &obj) const noexcept; bool operator !=(const Module &obj) const noexcept; @@ -42,4 +49,4 @@ namespace System Module &operator =(const Module &obj) noexcept; Module &operator =(Module &&obj) noexcept; }; -}; +} diff --git a/src/system/SharedMemory.cpp b/src/system/SharedMemory.cpp index 1c0560f..3169941 100644 --- a/src/system/SharedMemory.cpp +++ b/src/system/SharedMemory.cpp @@ -24,17 +24,18 @@ namespace System #elif POSIX this->shm_desc = -1; #else - #error "Undefine platform" + #error "Undefined platform" #endif } - SharedMemory::~SharedMemory() noexcept - { + SharedMemory::~SharedMemory() noexcept { this->close(); } - bool SharedMemory::create(const std::string &memName, const size_t memSize) - { + bool SharedMemory::create( + const std::string &memName, + const size_t memSize + ) { this->close(); #ifdef WIN32 @@ -57,31 +58,31 @@ namespace System memory_name.c_str() ); - if (nullptr == this->shm_desc) - { + if (nullptr == this->shm_desc) { return false; } #elif POSIX - this->shm_desc = ::shm_open(memName.c_str(), O_CREAT | O_RDWR, 0666); + this->shm_desc = ::shm_open( + memName.c_str(), + O_CREAT | O_RDWR, + 0666 + ); - if (-1 == this->shm_desc) - { + if (-1 == this->shm_desc) { return false; } - if (-1 == ::ftruncate64(this->shm_desc, memSize) ) - { + if (::ftruncate64(this->shm_desc, long(memSize)) == -1) { this->destroy(memName); - return false; } this->shm_name = memName; #else - #error "Undefine platform" + #error "Undefined platform" #endif return true; @@ -104,8 +105,7 @@ namespace System this->shm_desc = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, false, memory_name.c_str() ); - if (nullptr == this->shm_desc) - { + if (nullptr == this->shm_desc) { return false; } @@ -113,17 +113,20 @@ namespace System #elif POSIX - this->shm_desc = ::shm_open(memName.c_str(), O_RDWR, 0666); + this->shm_desc = ::shm_open( + memName.c_str(), + O_RDWR, + 0666 + ); - if (-1 == this->shm_desc) - { + if (-1 == this->shm_desc) { return false; } this->shm_name = memName; #else - #error "Undefine platform" + #error "Undefined platform" #endif return true; @@ -136,18 +139,20 @@ namespace System #elif POSIX return -1 != this->shm_desc; #else - #error "Undefine platform" + #error "Undefined platform" #endif } - bool SharedMemory::write(const void *src, const size_t size, const size_t offset) const noexcept - { + bool SharedMemory::write( + const void *src, + const size_t size, + const size_t offset + ) const noexcept { #ifdef WIN32 void * const addr = ::MapViewOfFile(this->shm_desc, FILE_MAP_WRITE, 0, static_cast<::DWORD>(offset), size); - if (nullptr == addr) - { + if (nullptr == addr) { return false; } @@ -157,32 +162,40 @@ namespace System #elif POSIX - void * const addr = ::mmap(0, size, PROT_WRITE, MAP_SHARED, this->shm_desc, offset); + void * const addr = ::mmap( + nullptr, + size, + PROT_WRITE, + MAP_SHARED, + this->shm_desc, + long(offset) + ); - if (reinterpret_cast(-1) == addr) - { + if (reinterpret_cast(-1) == addr) { return false; } - ::memcpy(addr, src, size); + std::memcpy(addr, src, size); ::munmap(addr, size); #else - #error "Undefine platform" + #error "Undefined platform" #endif return true; } - bool SharedMemory::read(void *dest, const size_t size, const size_t offset) const noexcept - { + bool SharedMemory::read( + void *dest, + const size_t size, + const size_t offset + ) const noexcept { #ifdef WIN32 void * const addr = ::MapViewOfFile(this->shm_desc, FILE_MAP_READ, 0, static_cast<::DWORD>(offset), size); - if (nullptr == addr) - { + if (nullptr == addr) { return false; } @@ -192,19 +205,25 @@ namespace System #elif POSIX - void * const addr = ::mmap(0, size, PROT_READ, MAP_SHARED, this->shm_desc, offset); + void * const addr = ::mmap( + nullptr, + size, + PROT_READ, + MAP_SHARED, + this->shm_desc, + long(offset) + ); - if (reinterpret_cast(-1) == addr) - { + if (reinterpret_cast(-1) == addr) { return false; } - ::memcpy(dest, addr, size); + std::memcpy(dest, addr, size); ::munmap(addr, size); #else - #error "Undefine platform" + #error "Undefined platform" #endif return true; @@ -221,7 +240,7 @@ namespace System ::close(this->shm_desc); this->shm_desc = ~0; #else - #error "Undefine platform" + #error "Undefined platform" #endif this->shm_name.clear(); @@ -250,13 +269,15 @@ namespace System return ret; #elif POSIX - const int ret = ::shm_unlink(this->shm_name.c_str() ); + const int ret = ::shm_unlink( + this->shm_name.c_str() + ); this->close(); return 0 == ret; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -278,7 +299,7 @@ namespace System #elif POSIX return 0 == ::shm_unlink(memName.c_str() ); #else - #error "Undefine platform" + #error "Undefined platform" #endif } -}; +} diff --git a/src/system/SharedMemory.h b/src/system/SharedMemory.h index d76608f..b9a84e9 100644 --- a/src/system/SharedMemory.h +++ b/src/system/SharedMemory.h @@ -17,7 +17,7 @@ namespace System #elif POSIX int shm_desc; #else - #error "Undefine platform" + #error "Undefined platform" #endif std::string shm_name; @@ -26,17 +26,30 @@ namespace System SharedMemory() noexcept; ~SharedMemory() noexcept; - bool create(const std::string &memName, const size_t memSize); + bool create( + const std::string &memName, + const size_t memSize + ); + bool open(const std::string &memName); bool is_open() const noexcept; - bool write(const void *data, const size_t size, const size_t offset = 0) const noexcept; - bool read(void *dest, const size_t size, const size_t offset = 0) const noexcept; + bool write( + const void *data, + const size_t size, + const size_t offset = 0 + ) const noexcept; + + bool read( + void *dest, + const size_t size, + const size_t offset = 0 + ) const noexcept; bool close() noexcept; bool destroy(); static bool destroy(const std::string &memName); }; -}; +} diff --git a/src/system/System.cpp b/src/system/System.cpp index 9dcaeb7..af696d9 100644 --- a/src/system/System.cpp +++ b/src/system/System.cpp @@ -20,8 +20,7 @@ namespace System { #ifdef WIN32 - struct EnumData - { + struct EnumData { native_processid_type process_id; ::HWND hWnd; }; @@ -34,7 +33,7 @@ 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; @@ -57,7 +56,7 @@ namespace System #elif POSIX return ::getpid(); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -74,7 +73,7 @@ namespace System #elif POSIX return 0 == ::chdir(dir.c_str() ); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -87,7 +86,7 @@ namespace System #elif POSIX return 0 == ::kill(pid, 0); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -106,7 +105,7 @@ namespace System #elif POSIX return 0 == ::kill(pid, signal); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -117,7 +116,7 @@ namespace System #elif POSIX return 0 != ::pthread_kill(handle, 0); #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -135,7 +134,7 @@ 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) { return std::string("/tmp/"); @@ -149,7 +148,7 @@ namespace System return str; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -179,12 +178,15 @@ namespace System 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; @@ -193,7 +195,15 @@ 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) { return false; @@ -206,7 +216,12 @@ namespace System ::FILETIME ftWrite; - ::BOOL result = ::GetFileTime(hFile, nullptr, nullptr, &ftWrite); + ::BOOL result = ::GetFileTime( + hFile, + nullptr, + nullptr, + &ftWrite + ); ::CloseHandle(hFile); @@ -227,7 +242,7 @@ namespace System stUtc.wYear - 1900, 0, 0, - -1 + -1 }; *fileTime = std::mktime(&tm_time); @@ -240,7 +255,7 @@ namespace System return false; } - *fileSize = attrib.st_size; + *fileSize = static_cast(attrib.st_size); std::tm clock {}; @@ -250,7 +265,7 @@ namespace System return true; #else - #error "Undefine platform" + #error "Undefined platform" #endif } @@ -297,7 +312,7 @@ namespace System } } #else - #error "Undefine platform" + #error "Undefined platform" #endif } } diff --git a/src/system/System.h b/src/system/System.h index 3b5b1bc..d7ae219 100644 --- a/src/system/System.h +++ b/src/system/System.h @@ -7,27 +7,27 @@ ::TCHAR myWndClassName[]; - #ifdef SIGTERM - #undef SIGTERM - #define SIGTERM (WM_USER + 15) - #endif - - #ifdef SIGINT - #undef SIGINT - #define SIGINT (WM_USER + 2) - #endif - - #ifndef SIGUSR1 - #define SIGUSR1 (WM_USER + 10) - #endif - - #ifndef SIGUSR2 - #define SIGUSR2 (WM_USER + 12) - #endif + #ifdef SIGTERM + #undef SIGTERM + #define SIGTERM (WM_USER + 15) + #endif + + #ifdef SIGINT + #undef SIGINT + #define SIGINT (WM_USER + 2) + #endif + + #ifndef SIGUSR1 + #define SIGUSR1 (WM_USER + 10) + #endif + + #ifndef SIGUSR2 + #define SIGUSR2 (WM_USER + 12) + #endif #elif POSIX #include #else - #error "Undefine platform" + #error "Undefined platform" #endif #include @@ -41,7 +41,7 @@ namespace System #elif POSIX typedef int native_socket_type; #else - #error "Undefine platform" + #error "Undefined platform" #endif #ifdef WIN32 @@ -49,7 +49,7 @@ namespace System #elif POSIX typedef ::pid_t native_processid_type; #else - #error "Undefine platform" + #error "Undefined platform" #endif native_processid_type getProcessId() noexcept; diff --git a/src/transfer/AppRequest.h b/src/transfer/AppRequest.h index b345a51..52d894e 100644 --- a/src/transfer/AppRequest.h +++ b/src/transfer/AppRequest.h @@ -7,15 +7,13 @@ 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 51ff300..e059e55 100644 --- a/src/transfer/AppResponse.h +++ b/src/transfer/AppResponse.h @@ -5,8 +5,7 @@ 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 ed2c49f..07fb877 100644 --- a/src/transfer/FileIncoming.cpp +++ b/src/transfer/FileIncoming.cpp @@ -6,23 +6,34 @@ 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; } @@ -53,8 +64,10 @@ namespace Transfer 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) { @@ -69,8 +82,10 @@ 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); @@ -90,7 +105,15 @@ 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 2568b73..87e745b 100644 --- a/src/transfer/FileIncoming.h +++ b/src/transfer/FileIncoming.h @@ -18,7 +18,13 @@ namespace Transfer FileIncoming() = delete; public: - FileIncoming(std::string &&fileTmpName, std::string &&fileName, std::string &&fileType, const size_t fileSize) noexcept; + FileIncoming( + std::string &&fileTmpName, + std::string &&fileName, + std::string &&fileType, + const size_t fileSize + ) noexcept; + FileIncoming(const FileIncoming &obj); FileIncoming(FileIncoming &&obj) noexcept; @@ -35,6 +41,13 @@ namespace Transfer 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 a560814..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, diff --git a/src/transfer/ProtocolVariant.h b/src/transfer/ProtocolVariant.h index fca95ef..093a02a 100644 --- a/src/transfer/ProtocolVariant.h +++ b/src/transfer/ProtocolVariant.h @@ -2,8 +2,7 @@ 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 7075b2f..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; @@ -5218,22 +5216,27 @@ namespace HPack 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; + 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) { @@ -5257,8 +5260,11 @@ 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; @@ -5279,15 +5285,17 @@ namespace HPack } } - 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; @@ -5321,9 +5329,12 @@ 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) { dest.emplace_back(num); @@ -5350,14 +5361,19 @@ namespace HPack } } - 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 }; @@ -5423,19 +5439,31 @@ namespace HPack dest[head] |= 0x80; } 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; @@ -5458,8 +5486,11 @@ namespace HPack 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; @@ -5492,23 +5523,24 @@ namespace HPack dest[head] |= 0x20; } */ - void pack(std::vector &dest, const std::vector > &headers, Http2::DynamicTable &dynamicTable) - { + 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, @@ -5526,8 +5558,10 @@ namespace HPack return getStaticTableSize() + stream.conn.decoding_dynamic_table.size(); } - static const std::pair *getHeaderFromTable(const size_t index, const Http2::IncStream &stream) noexcept - { + static const std::pair *getHeaderFromTable( + const size_t index, + const Http2::IncStream &stream + ) noexcept { if (getStaticTableSize() >= index) { return &staticTable[index - 1]; } @@ -5538,7 +5572,10 @@ namespace HPack 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); } @@ -5546,8 +5583,12 @@ namespace HPack 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 }; @@ -5556,24 +5597,42 @@ namespace HPack 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) - { + 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 }; @@ -5582,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) { @@ -5658,8 +5717,8 @@ 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(); @@ -5695,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; @@ -5743,7 +5805,13 @@ 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; @@ -5756,7 +5824,9 @@ namespace HPack return false; } - stream.conn.decoding_dynamic_table.changeHeaderTableSize(dec.left); + stream.conn.decoding_dynamic_table.changeHeaderTableSize( + static_cast(dec.left) + ); dec.state = HuffmanDecodeState::OPCODE; @@ -5779,7 +5849,13 @@ namespace HPack 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; @@ -5811,7 +5887,13 @@ 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; @@ -5819,9 +5901,9 @@ namespace HPack 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; } @@ -5831,7 +5913,12 @@ 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; @@ -5849,7 +5936,12 @@ 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; @@ -5878,7 +5970,13 @@ 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; @@ -5888,18 +5986,18 @@ namespace HPack 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; } @@ -5909,7 +6007,12 @@ 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; @@ -5918,9 +6021,9 @@ namespace HPack 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; @@ -5929,7 +6032,12 @@ 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; @@ -5938,9 +6046,9 @@ namespace HPack 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; diff --git a/src/transfer/http2/HPack.h b/src/transfer/http2/HPack.h index b467a15..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 ed7b963..71c60c9 100644 --- a/src/transfer/http2/Http2.cpp +++ b/src/transfer/http2/Http2.cpp @@ -4,16 +4,29 @@ 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 { @@ -28,7 +41,9 @@ 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) { } @@ -37,8 +52,15 @@ namespace Http2 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) { this->cur_header_list_size += pair.first.length() + pair.second.length(); @@ -51,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(); @@ -67,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(); @@ -94,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(); @@ -104,11 +136,13 @@ 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]; } @@ -117,15 +151,23 @@ namespace Http2 } 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); @@ -142,8 +184,7 @@ namespace Http2 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(); @@ -155,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); diff --git a/src/transfer/http2/Http2.h b/src/transfer/http2/Http2.h index 12b6d65..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,20 +190,29 @@ 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 d768a8e..3c9fd01 100644 --- a/src/utils/Event.cpp +++ b/src/utils/Event.cpp @@ -32,7 +32,9 @@ namespace Utils if (this->signaled.load() == false) { std::unique_lock lck(this->mtx); - is_timeout = this->cv.wait_for(lck, ms, [this] { return this->notifed(); } ) == false; + is_timeout = false == this->cv.wait_for(lck, ms, [this] { + return this->notifed(); + }); } if (false == this->manually) { @@ -42,8 +44,9 @@ namespace Utils 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 (this->signaled.load() == false) { diff --git a/src/utils/Utils.cpp b/src/utils/Utils.cpp index 4ddc424..aacd218 100644 --- a/src/utils/Utils.cpp +++ b/src/utils/Utils.cpp @@ -32,7 +32,11 @@ namespace Utils 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) { @@ -103,13 +107,13 @@ namespace Utils static unsigned char hexStringToBinEncodeSymbol(const char c) noexcept { if (c >= '0' && c <= '9') { - return c - 0x30; + return static_cast(c - 0x30); } else if (c >= 'a' && c <= 'f') { - return c - 0x57; + return static_cast(c - 0x57); } else if (c >= 'A' && c <= 'F') { - return c - 0x37; + return static_cast(c - 0x37); } return 0; @@ -123,7 +127,7 @@ namespace Utils const char a = hexStr[i * 2 + 0]; const char b = hexStr[i * 2 + 1]; - bin[i] = ( + bin[i] = char( (hexStringToBinEncodeSymbol(a) << 4) | hexStringToBinEncodeSymbol(b) ); } @@ -224,12 +228,16 @@ 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(); + size_t time = size_t( + std::chrono::high_resolution_clock::now().time_since_epoch().count() + ); + time = hton64(time); + return binToHexString(&time, sizeof(time) ); } @@ -265,7 +273,7 @@ namespace Utils uint8_t *packNumber(uint8_t *dest, const size_t number) noexcept { if (number <= PACK_NUMBER_SIZE_BYTE) { - *dest = number; + *dest = static_cast(number); dest += sizeof(uint8_t); } @@ -343,12 +351,21 @@ namespace Utils packNumber(buf, str.length() ); if (str.length() ) { - std::copy(str.cbegin(), str.cend(), std::back_inserter(buf) ); + 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) ) ); + *pointer = *reinterpret_cast( + const_cast( + static_cast(src) + ) + ); + return src + sizeof(void *); } @@ -403,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) @@ -433,7 +449,7 @@ namespace Utils 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); @@ -459,7 +475,7 @@ namespace Utils 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); @@ -468,7 +484,7 @@ namespace Utils 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); @@ -477,7 +493,7 @@ namespace Utils 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); @@ -486,7 +502,7 @@ namespace Utils 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); @@ -516,8 +532,8 @@ 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() == '-') { timezone *= -1; @@ -584,7 +600,7 @@ namespace Utils return ~0; } - tc.tm_mday = std::strtoul(ptrStr, nullptr, 10); + tc.tm_mday = std::atoi(ptrStr); ++strTime; @@ -594,7 +610,7 @@ namespace Utils return ~0; } - tc.tm_year = std::strtoul(strTime, nullptr, 10) - 1900; + tc.tm_year = std::atoi(strTime) - 1900; ++ptrStr; @@ -604,7 +620,7 @@ namespace Utils return ~0; } - tc.tm_hour = std::strtoul(ptrStr, nullptr, 10); + tc.tm_hour = std::atoi(ptrStr); ++strTime; @@ -614,11 +630,11 @@ namespace Utils 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) ); } @@ -637,21 +653,29 @@ namespace Utils #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); @@ -675,14 +699,19 @@ namespace Utils return length; } - bool parseCookies(const std::string &cookieHeader, std::unordered_multimap &cookies) - { + 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); @@ -691,17 +720,30 @@ namespace Utils 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) { ++next_value; @@ -723,10 +765,10 @@ 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) { encoded.push_back('+'); @@ -749,14 +791,14 @@ 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() ) { const char a = str[++i]; const char b = str[++i]; - c = ( + c = static_cast( (hexStringToBinEncodeSymbol(a) << 4) | hexStringToBinEncodeSymbol(b) ); } @@ -765,7 +807,7 @@ namespace Utils 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 340c6eb..551e975 100644 --- a/src/utils/Utils.h +++ b/src/utils/Utils.h @@ -128,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); From 4b3ee40b97abd07e63a8614b0a66e123d3f1376d Mon Sep 17 00:00:00 2001 From: Ignat Prokopovich Date: Sun, 1 Apr 2018 17:26:45 +0300 Subject: [PATCH 4/7] Fixed code (and style) for Windows. --- src/server/config/ConfigParser.cpp | 6 +- src/server/data-variant/FormUrlencoded.cpp | 23 +++---- src/server/protocol/ServerHttp2Protocol.cpp | 5 +- src/server/protocol/extensions/Sendfile.cpp | 18 ++++- src/socket/AdapterTls.cpp | 4 +- src/socket/List.cpp | 12 ++-- src/socket/Socket.cpp | 23 ++++--- src/system/GlobalMutex.cpp | 38 +++++++++-- src/system/Module.cpp | 76 ++++++++++++++------- src/system/SharedMemory.cpp | 44 ++++++++++-- src/system/System.cpp | 9 ++- src/system/System.h | 6 +- 12 files changed, 179 insertions(+), 85 deletions(-) diff --git a/src/server/config/ConfigParser.cpp b/src/server/config/ConfigParser.cpp index 1bbb42a..ab08166 100644 --- a/src/server/config/ConfigParser.cpp +++ b/src/server/config/ConfigParser.cpp @@ -279,7 +279,7 @@ namespace HttpServer try { if (app_init) { - const std::string root = root_dir; + const std::string &root = root_dir; success = app_init(root.data() ); } } @@ -356,8 +356,8 @@ namespace HttpServer if (names.empty() ) { apps_tree.addApplication(app_name, settings); } else { - for (size_t i = 0; i < names.size(); ++i) { - apps_tree.addApplication(names[i], settings); + for (auto const &name : names) { + apps_tree.addApplication(name, settings); } } diff --git a/src/server/data-variant/FormUrlencoded.cpp b/src/server/data-variant/FormUrlencoded.cpp index 08f8180..28adff0 100644 --- a/src/server/data-variant/FormUrlencoded.cpp +++ b/src/server/data-variant/FormUrlencoded.cpp @@ -1,4 +1,4 @@ - + #include "FormUrlencoded.h" #include "../../utils/Utils.h" @@ -20,7 +20,7 @@ namespace DataVariant std::string::npos != var_end; var_pos = var_end + 1 ) { - // Поиск следующего параметра + // Search next parameter var_end = buf.find('&', var_pos); if (std::string::npos == var_end) { @@ -30,12 +30,11 @@ namespace DataVariant } } - // Поиск значения параметра + // Search parameter value size_t delimiter = buf.find('=', var_pos); - if (delimiter >= var_end) - { - // Получить имя параметра + if (delimiter >= var_end) { + // Get parameter name std::string var_name = Utils::urlDecode( buf.substr( var_pos, @@ -45,15 +44,13 @@ namespace DataVariant ) ); - // Сохранить параметр с пустым значением + // Store parameter with empty value rd->incoming_data.emplace( std::move(var_name), std::string() ); - } - else - { - // Получить имя параметра + } else { + // Get parameter name std::string var_name = Utils::urlDecode( buf.substr( var_pos, @@ -63,7 +60,7 @@ namespace DataVariant ++delimiter; - // Получить значение параметра + // Get parameter value std::string var_value = Utils::urlDecode( buf.substr( delimiter, @@ -73,7 +70,7 @@ namespace DataVariant ) ); - // Сохранить параметр и значение + // Store parameter and value rd->incoming_data.emplace( std::move(var_name), std::move(var_value) diff --git a/src/server/protocol/ServerHttp2Protocol.cpp b/src/server/protocol/ServerHttp2Protocol.cpp index fd4ed10..6cb996b 100644 --- a/src/server/protocol/ServerHttp2Protocol.cpp +++ b/src/server/protocol/ServerHttp2Protocol.cpp @@ -25,9 +25,8 @@ namespace HttpServer } std::random_device rd; - std::uniform_int_distribution dist; - uint8_t padding = dist(rd); + uint8_t padding = uint8_t(rd()); while (dataSize <= padding) { padding /= 2; @@ -177,7 +176,7 @@ namespace HttpServer } data += data_size; - send_size += data_size; + send_size += long(data_size); dt->send_total += data_size; // stream->window_size_out -= frame_size; diff --git a/src/server/protocol/extensions/Sendfile.cpp b/src/server/protocol/extensions/Sendfile.cpp index 1758515..2799f57 100644 --- a/src/server/protocol/extensions/Sendfile.cpp +++ b/src/server/protocol/extensions/Sendfile.cpp @@ -100,7 +100,9 @@ namespace HttpServer *resultRangeHeader += std::to_string(range_begin) + '-' + std::to_string(range_end) + ','; - ranges.emplace_back(std::tuple {range_begin, length}); + ranges.emplace_back(std::tuple { + range_begin, length + }); } } else // if range_end_str empty @@ -275,7 +277,12 @@ namespace HttpServer send_size_left -= send_size; } - while (false == file.eof() && false == file.fail() && send_size > 0 && send_size_left); + while ( + false == file.eof() && + false == file.fail() && + send_size > 0 && + send_size_left + ); } } @@ -407,7 +414,12 @@ namespace HttpServer &dt ); } - while (false == file.eof() && false == file.fail() && send_size > 0 && (dt.full_size - dt.send_total) ); + while ( + false == file.eof() && + false == file.fail() && + send_size > 0 && + (dt.full_size - dt.send_total) + ); } file.close(); diff --git a/src/socket/AdapterTls.cpp b/src/socket/AdapterTls.cpp index 118e885..0126830 100644 --- a/src/socket/AdapterTls.cpp +++ b/src/socket/AdapterTls.cpp @@ -97,10 +97,10 @@ namespace Socket 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 { diff --git a/src/socket/List.cpp b/src/socket/List.cpp index a1accbd..eab986d 100644 --- a/src/socket/List.cpp +++ b/src/socket/List.cpp @@ -1,4 +1,4 @@ - + #include "List.h" #ifdef POSIX @@ -271,17 +271,15 @@ namespace Socket 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 { ::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, @@ -367,10 +365,8 @@ namespace Socket 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) { sockets.emplace_back(Socket(event.fd) ); } diff --git a/src/socket/Socket.cpp b/src/socket/Socket.cpp index 54904d3..40b0f92 100644 --- a/src/socket/Socket.cpp +++ b/src/socket/Socket.cpp @@ -188,7 +188,7 @@ namespace Socket 0 }; - if (1 == ::WSAPoll(&event, 1, static_cast<::INT>(timeout.count() ) ) && event.revents & POLLRDNORM) { + if (1 == ::WSAPoll(&event, 1, int(timeout.count()) ) && event.revents & POLLRDNORM) { client_socket = ::accept( this->socket_handle, static_cast(nullptr), @@ -235,7 +235,12 @@ 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, @@ -338,7 +343,7 @@ namespace Socket 0 }; - if (1 == ::WSAPoll(&event, 1, static_cast<::INT>(timeout.count() ) ) && event.revents & POLLRDNORM) { + if (1 == ::WSAPoll(&event, 1, int(timeout.count()) ) && event.revents & POLLRDNORM) { recv_len = ::recv( this->socket_handle, reinterpret_cast(buf), @@ -372,7 +377,7 @@ namespace Socket 0 }; - return ::WSAPoll(&event, 1, timeout.count() ) == 1; + return ::WSAPoll(&event, 1, int(timeout.count()) ) == 1; #elif POSIX struct ::pollfd event { this->socket_handle, @@ -405,7 +410,7 @@ namespace Socket return send_size; } - total += static_cast(send_size); + total += size_t(send_size); } return static_cast(total); @@ -435,7 +440,7 @@ namespace Socket }; while (total < length) { - if (1 == ::WSAPoll(&event, 1, static_cast<::INT>(timeout.count() ) ) && event.revents & POLLOUT) { + if (1 == ::WSAPoll(&event, 1, int(timeout.count()) ) && event.revents & POLLOUT) { const long send_size = ::send( socket_handle, reinterpret_cast(data) + total, @@ -447,7 +452,7 @@ namespace Socket return send_size; } - total += send_size; + total += size_t(send_size); } else { return -1; } @@ -473,7 +478,7 @@ namespace Socket return send_size; } - total += static_cast(send_size); + total += size_t(send_size); } else { return -1; } @@ -482,7 +487,7 @@ namespace Socket #error "Undefined platform" #endif - return static_cast(total); + return long(total); } long Socket::nonblock_send( diff --git a/src/system/GlobalMutex.cpp b/src/system/GlobalMutex.cpp index 0c72d06..9a5477e 100644 --- a/src/system/GlobalMutex.cpp +++ b/src/system/GlobalMutex.cpp @@ -39,7 +39,11 @@ namespace System const std::string &mutex_name = this->mtx_name; #endif - this->mtx_desc = ::CreateMutex(nullptr, false, mutex_name.c_str() ); + this->mtx_desc = ::CreateMutex( + nullptr, + false, + mutex_name.c_str() + ); if (nullptr == this->mtx_desc) { return false; @@ -77,7 +81,11 @@ namespace System const std::string &mutex_name = mtx_name; #endif - ::HANDLE hMutex = ::OpenMutex(DELETE, true, mutex_name.c_str() ); + const ::HANDLE hMutex = ::OpenMutex( + DELETE, + true, + mutex_name.c_str() + ); return 0 != ::CloseHandle(hMutex); #elif POSIX @@ -97,9 +105,15 @@ namespace System const std::string &mutex_name = this->mtx_name; #endif - ::HANDLE hMutex = ::OpenMutex(DELETE, true, mutex_name.c_str() ); + const ::HANDLE hMutex = ::OpenMutex( + DELETE, + true, + mutex_name.c_str() + ); - const bool ret = (0 != ::CloseHandle(hMutex) ); + const bool ret = ( + 0 != ::CloseHandle(hMutex) + ); this->close(); @@ -132,7 +146,11 @@ namespace System const std::string &mutex_name = this->mtx_name; #endif - this->mtx_desc = ::OpenMutex(SYNCHRONIZE, false, mutex_name.c_str() ); + this->mtx_desc = ::OpenMutex( + SYNCHRONIZE, + false, + mutex_name.c_str() + ); if (nullptr == this->mtx_desc) { return false; @@ -193,7 +211,10 @@ namespace System bool GlobalMutex::lock() const noexcept { #ifdef WIN32 - return WAIT_OBJECT_0 == ::WaitForSingleObject(this->mtx_desc, INFINITE); + return WAIT_OBJECT_0 == ::WaitForSingleObject( + this->mtx_desc, + INFINITE + ); #elif POSIX return 0 == ::sem_wait(this->mtx_desc); #else @@ -204,7 +225,10 @@ namespace System bool GlobalMutex::try_lock() const noexcept { #ifdef WIN32 - return WAIT_OBJECT_0 == ::WaitForSingleObject(this->mtx_desc, 0); + return WAIT_OBJECT_0 == ::WaitForSingleObject( + this->mtx_desc, + 0 + ); #elif POSIX return 0 == ::sem_trywait(this->mtx_desc); #else diff --git a/src/system/Module.cpp b/src/system/Module.cpp index a417a59..ef7f512 100644 --- a/src/system/Module.cpp +++ b/src/system/Module.cpp @@ -1,4 +1,4 @@ - + #include "Module.h" #ifdef WIN32 @@ -52,24 +52,26 @@ namespace System const size_t pos_slash = libPath.rfind('\\'); const size_t pos_slash_back = libPath.rfind('/'); - size_t pos = std::string::npos; - - if (pos_slash != std::string::npos && pos_slash > pos_slash_back) - { - pos = pos_slash; - } - else if (pos_slash_back != std::string::npos) - { - pos = pos_slash_back; - } - - DLL_DIRECTORY_COOKIE cookie = nullptr; - - if (std::string::npos != pos) - { - std::wstring directory(libPath.cbegin(), libPath.cbegin() + pos + 1); + const size_t pos = ( + pos_slash != std::string::npos && + pos_slash > pos_slash_back + ? pos_slash + : pos_slash_back != std::string::npos + ? pos_slash_back + : std::string::npos + ); + + ::DLL_DIRECTORY_COOKIE cookie = nullptr; + + if (std::string::npos != pos) { + const std::wstring directory( + libPath.cbegin(), + libPath.cbegin() + pos + 1 + ); - cookie = ::AddDllDirectory(directory.data() ); + cookie = ::AddDllDirectory( + directory.data() + ); } #ifdef UNICODE @@ -79,13 +81,20 @@ namespace System const std::string &lib_path = libPath; #endif - this->lib_handle = ::LoadLibraryEx(lib_path.c_str(), 0, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + this->lib_handle = ::LoadLibraryEx( + lib_path.c_str(), + 0, + LOAD_LIBRARY_SEARCH_DEFAULT_DIRS + ); if (cookie) { ::RemoveDllDirectory(cookie); } #elif POSIX - this->lib_handle = ::dlopen(libPath.c_str(), RTLD_NOW | RTLD_LOCAL); + this->lib_handle = ::dlopen( + libPath.c_str(), + RTLD_NOW | RTLD_LOCAL + ); #else #error "Undefined platform" #endif @@ -121,17 +130,24 @@ namespace System const std::string &symbolName, void *(**addr)(void *) ) const noexcept { - if (lib_handle) - { + if (lib_handle) { #ifdef WIN32 - *addr = reinterpret_cast(::GetProcAddress(this->lib_handle, symbolName.c_str() ) ); + *addr = reinterpret_cast( + ::GetProcAddress( + this->lib_handle, + symbolName.c_str() + ) + ); return nullptr != *addr; #elif POSIX char *error = ::dlerror(); *addr = reinterpret_cast( - ::dlsym(this->lib_handle, symbolName.c_str() ) + ::dlsym( + this->lib_handle, + symbolName.c_str() + ) ); error = ::dlerror(); @@ -152,14 +168,22 @@ namespace System if (lib_handle) { #ifdef WIN32 - *addr = reinterpret_cast(::GetProcAddress(this->lib_handle, symbolName) ); + *addr = reinterpret_cast( + ::GetProcAddress( + this->lib_handle, + symbolName + ) + ); return nullptr != *addr; #elif POSIX char *error = ::dlerror(); *addr = reinterpret_cast( - ::dlsym(this->lib_handle, symbolName) + ::dlsym( + this->lib_handle, + symbolName + ) ); error = ::dlerror(); diff --git a/src/system/SharedMemory.cpp b/src/system/SharedMemory.cpp index 3169941..a88b1e7 100644 --- a/src/system/SharedMemory.cpp +++ b/src/system/SharedMemory.cpp @@ -103,7 +103,11 @@ namespace System const std::string &memory_name = this->shm_name; #endif - this->shm_desc = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, false, memory_name.c_str() ); + this->shm_desc = ::OpenFileMapping( + FILE_MAP_ALL_ACCESS, + false, + memory_name.c_str() + ); if (nullptr == this->shm_desc) { return false; @@ -150,7 +154,16 @@ namespace System ) const noexcept { #ifdef WIN32 - void * const addr = ::MapViewOfFile(this->shm_desc, FILE_MAP_WRITE, 0, static_cast<::DWORD>(offset), size); + ::ULARGE_INTEGER off; + off.QuadPart = ::ULONGLONG(offset); + + void * const addr = ::MapViewOfFile( + this->shm_desc, + FILE_MAP_WRITE, + off.HighPart, + off.LowPart, + size + ); if (nullptr == addr) { return false; @@ -193,7 +206,16 @@ namespace System ) const noexcept { #ifdef WIN32 - void * const addr = ::MapViewOfFile(this->shm_desc, FILE_MAP_READ, 0, static_cast<::DWORD>(offset), size); + ::ULARGE_INTEGER off; + off.QuadPart = ::ULONGLONG(offset); + + void * const addr = ::MapViewOfFile( + this->shm_desc, + FILE_MAP_READ, + off.HighPart, + off.LowPart, + size + ); if (nullptr == addr) { return false; @@ -261,9 +283,15 @@ namespace System const std::string &memory_name = this->shm_name; #endif - ::HANDLE hMemory = ::OpenFileMapping(DELETE, false, memory_name.c_str() ); + const ::HANDLE hMemory = ::OpenFileMapping( + DELETE, + false, + memory_name.c_str() + ); - const bool ret = (0 != ::CloseHandle(hMemory) ); + const bool ret = ( + 0 != ::CloseHandle(hMemory) + ); this->close(); @@ -293,7 +321,11 @@ namespace System const std::string &memory_name = shm_name; #endif - ::HANDLE hMemory = ::OpenFileMapping(DELETE, false, memory_name.c_str() ); + const ::HANDLE hMemory = ::OpenFileMapping( + DELETE, + false, + memory_name.c_str() + ); return 0 != ::CloseHandle(hMemory); #elif POSIX diff --git a/src/system/System.cpp b/src/system/System.cpp index af696d9..ebb5935 100644 --- a/src/system/System.cpp +++ b/src/system/System.cpp @@ -1,4 +1,4 @@ - + #include "System.h" #include @@ -37,7 +37,7 @@ namespace System { 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) ) { ed.hWnd = hWnd; @@ -284,7 +284,10 @@ 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() ); + memory_name.erase( + pos, + memory_name.length() + ); } ::TCHAR buf[MAX_PATH + 1] {}; diff --git a/src/system/System.h b/src/system/System.h index d7ae219..8b637d4 100644 --- a/src/system/System.h +++ b/src/system/System.h @@ -1,9 +1,11 @@ -#pragma once +#pragma once #ifdef WIN32 #include - typedef long ssize_t; + #ifndef ssize_t + typedef long ssize_t; + #endif ::TCHAR myWndClassName[]; From 0e8c8dd92569d86fc7dae2da08e1731fe497c0a2 Mon Sep 17 00:00:00 2001 From: awwit Date: Mon, 2 Apr 2018 21:34:19 +0300 Subject: [PATCH 5/7] Optimized some copy operations. Added copy constructor for FileIncoming. --- src/server/protocol/ServerHttp2.cpp | 6 +++--- src/server/protocol/ServerHttp2Protocol.cpp | 8 +++++--- src/transfer/FileIncoming.h | 7 ++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/server/protocol/ServerHttp2.cpp b/src/server/protocol/ServerHttp2.cpp index 12ae2be..35632ad 100644 --- a/src/server/protocol/ServerHttp2.cpp +++ b/src/server/protocol/ServerHttp2.cpp @@ -590,9 +590,9 @@ namespace HttpServer } } else { std::copy( - buf.cbegin() + length, - buf.cbegin() + read_size, - buf.begin() + buf.data() + length, + buf.data() + read_size, + buf.data() ); read_size -= length; diff --git a/src/server/protocol/ServerHttp2Protocol.cpp b/src/server/protocol/ServerHttp2Protocol.cpp index 6cb996b..857c216 100644 --- a/src/server/protocol/ServerHttp2Protocol.cpp +++ b/src/server/protocol/ServerHttp2Protocol.cpp @@ -106,7 +106,9 @@ namespace HttpServer } } - const size_t frame_size = data_size + padding_size; + const uint32_t frame_size = static_cast( + data_size + padding_size + ); buf.resize(frame_size + Http2::FRAME_HEADER_SIZE); @@ -141,7 +143,7 @@ namespace HttpServer this->stream->setHttp2FrameHeader( buf.data(), - static_cast(frame_size), + frame_size, Http2::FrameType::DATA, flags ); @@ -149,7 +151,7 @@ namespace HttpServer std::copy( data, data + data_size, - buf.begin() + long(cur) + buf.data() + cur ); if (padding) { diff --git a/src/transfer/FileIncoming.h b/src/transfer/FileIncoming.h index 87e745b..448c8c8 100644 --- a/src/transfer/FileIncoming.h +++ b/src/transfer/FileIncoming.h @@ -14,10 +14,9 @@ namespace Transfer std::string file_type; size_t file_size; - private: - FileIncoming() = delete; - public: + FileIncoming() = default; + FileIncoming( std::string &&fileTmpName, std::string &&fileName, @@ -30,6 +29,8 @@ namespace Transfer ~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; From a3389a3fee20b8186754bca73faac8ee8c4e7146 Mon Sep 17 00:00:00 2001 From: awwit Date: Thu, 31 May 2018 16:12:19 +0300 Subject: [PATCH 6/7] Added output of messages with exceptions. --- src/server/Server.cpp | 4 ++-- src/server/ServerSettings.cpp | 6 ++---- src/server/config/ConfigParser.cpp | 2 +- src/server/protocol/ServerProtocol.cpp | 12 ++++++++---- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/server/Server.cpp b/src/server/Server.cpp index df464eb..ca069e9 100644 --- a/src/server/Server.cpp +++ b/src/server/Server.cpp @@ -313,7 +313,7 @@ namespace HttpServer app->application_final(root.data() ); } } - catch (std::exception &exc) { + catch (const std::exception &exc) { std::cout << "Warning: an exception was thrown when the application '" << app->server_module << "' was finishes: " << exc.what() << std::endl; } @@ -460,7 +460,7 @@ namespace HttpServer app->application_init(root.data() ); } } - catch (std::exception &exc) { + catch (const std::exception &exc) { std::cout << "Warning: an exception was thrown when the application '" << module_name << "' was initialized: " << exc.what() << std::endl; } } diff --git a/src/server/ServerSettings.cpp b/src/server/ServerSettings.cpp index 3677a62..4370d1e 100644 --- a/src/server/ServerSettings.cpp +++ b/src/server/ServerSettings.cpp @@ -34,15 +34,13 @@ namespace HttpServer for (auto &app : applications) { - try - { + try { if (app->application_final) { const std::string root = app->root_dir; app->application_final(root.data() ); } } - catch (std::exception &exc) - { + catch (const std::exception &exc) { std::cout << "Warning: an exception was thrown when the application '" << app->server_module << "' was finishes: " << exc.what() << std::endl; } diff --git a/src/server/config/ConfigParser.cpp b/src/server/config/ConfigParser.cpp index ab08166..c00ea41 100644 --- a/src/server/config/ConfigParser.cpp +++ b/src/server/config/ConfigParser.cpp @@ -283,7 +283,7 @@ namespace HttpServer success = app_init(root.data() ); } } - catch (std::exception &exc) { + catch (const std::exception &exc) { std::cout << "Warning: an exception was thrown when the application '" << it_module->second << "' was initialized: " << exc.what() << std::endl; success = false; } diff --git a/src/server/protocol/ServerProtocol.cpp b/src/server/protocol/ServerProtocol.cpp index 42628eb..4f3010d 100644 --- a/src/server/protocol/ServerProtocol.cpp +++ b/src/server/protocol/ServerProtocol.cpp @@ -2,6 +2,8 @@ #include "ServerProtocol.h" #include "../../utils/Utils.h" +#include + namespace HttpServer { ServerProtocol::ServerProtocol( @@ -167,8 +169,9 @@ namespace HttpServer // Launch application req.app_exit_code = appSets.application_call(&request, &response); } - catch (std::exception &exc) { - // TODO: exception output + catch (const std::exception &exc) { + // Exception output + std::cout << "Exception when application_call: " << exc.what() << std::endl; } if (response.response_data && response.data_size) @@ -181,8 +184,9 @@ namespace HttpServer try { appSets.application_clear(response.response_data, response.data_size); } - catch (std::exception &exc) { - // TODO: exception output + catch (const std::exception &exc) { + // Exception output + std::cout << "Exception when application_clear: " << exc.what() << std::endl; } } } From d824fe72fe134e5abcddbb7879dd339a06142b92 Mon Sep 17 00:00:00 2001 From: awwit Date: Mon, 30 Jul 2018 15:31:31 +0300 Subject: [PATCH 7/7] Fixed issue #6 --- src/server/protocol/extensions/Sendfile.cpp | 6 +++-- src/socket/Socket.cpp | 26 ++++++++++++--------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/server/protocol/extensions/Sendfile.cpp b/src/server/protocol/extensions/Sendfile.cpp index 2799f57..dc46186 100644 --- a/src/server/protocol/extensions/Sendfile.cpp +++ b/src/server/protocol/extensions/Sendfile.cpp @@ -221,7 +221,8 @@ namespace HttpServer additionalHeaders.emplace_back("last-modified", Utils::getDatetimeAsString(fileTime, true) ); // Отправить заголовки (206 Partial Content) - if (prot.sendHeaders( + if ( + prot.sendHeaders( Http::StatusCode::PARTIAL_CONTENT, additionalHeaders, req.timeout, @@ -377,7 +378,8 @@ namespace HttpServer additionalHeaders.emplace_back("last-modified", Utils::getDatetimeAsString(file_time, true) ); // Отправить заголовки (200 OK) - if (prot.sendHeaders( + if ( + prot.sendHeaders( Http::StatusCode::OK, additionalHeaders, req.timeout, diff --git a/src/socket/Socket.cpp b/src/socket/Socket.cpp index 40b0f92..05263db 100644 --- a/src/socket/Socket.cpp +++ b/src/socket/Socket.cpp @@ -103,17 +103,21 @@ namespace Socket } bool Socket::bind(const int port) const noexcept { + // GCC bug with global namespace: https://bbs.archlinux.org/viewtopic.php?id=53751 + auto const net_port = htons(static_cast(port)); + auto const net_addr = ::htonl(INADDR_ANY); + const ::sockaddr_in sock_addr { AF_INET, - ::htons(port), - ::htonl(INADDR_ANY), - 0 + net_port, + { net_addr }, + { 0 } // sin_zero }; return 0 == ::bind( this->socket_handle, - reinterpret_cast(&sock_addr), - sizeof(sockaddr_in) + reinterpret_cast(&sock_addr), + sizeof(::sockaddr_in) ); } @@ -147,9 +151,9 @@ namespace Socket #ifdef WIN32 WSAPOLLFD event { this->socket_handle, - POLLRDNORM, - 0 - }; + POLLRDNORM, + 0 + }; if (1 == ::WSAPoll(&event, 1, ~0) && event.revents & POLLRDNORM) { client_socket = ::accept( @@ -161,9 +165,9 @@ namespace Socket #elif POSIX struct ::pollfd event { this->socket_handle, - POLLIN, - 0 - }; + POLLIN, + 0 + }; if (1 == ::poll(&event, 1, ~0) && event.revents & POLLIN) { client_socket = ::accept(