This commit is contained in:
parent
479c3b628b
commit
760bc2ab68
4 changed files with 53 additions and 54 deletions
|
@ -38,7 +38,7 @@ fi
|
||||||
# Manual cmd command: for FILE in "$(git diff --cached --name-only --diff-filter=d | grep -E -i "\.(sh)$") .githooks/pre-commit"; do shellcheck -S warning $FILE; done
|
# Manual cmd command: for FILE in "$(git diff --cached --name-only --diff-filter=d | grep -E -i "\.(sh)$") .githooks/pre-commit"; do shellcheck -S warning $FILE; done
|
||||||
#
|
#
|
||||||
SHELLCHECK_RES=0
|
SHELLCHECK_RES=0
|
||||||
# for FILE in $GIT_SCRIPT_FILES; do shellcheck -S warning $FILE; RET_CODE=$?; SHELLCHECK_RES=$(( RET_CODE + SHELLCHECK_RES )); done
|
for FILE in $GIT_SCRIPT_FILES; do shellcheck -S warning $FILE; RET_CODE=$?; SHELLCHECK_RES=$(( RET_CODE + SHELLCHECK_RES )); done
|
||||||
|
|
||||||
if [[ $SHELLCHECK_RES != 0 ]]; then
|
if [[ $SHELLCHECK_RES != 0 ]]; then
|
||||||
printf "\n\t ${RED}[ERROR] shell scripts check FAILED!${NC} Fix above errors before commiting your changes. (check .githooks/pre-commit for additional info)\n"
|
printf "\n\t ${RED}[ERROR] shell scripts check FAILED!${NC} Fix above errors before commiting your changes. (check .githooks/pre-commit for additional info)\n"
|
||||||
|
@ -62,7 +62,7 @@ printf "\n\tBuild GTests to check (takes up to 30 seconds)"
|
||||||
cmake --build ${GTEST_FOLDER} --target larra_xmpp_tests --parallel "$(nproc)"
|
cmake --build ${GTEST_FOLDER} --target larra_xmpp_tests --parallel "$(nproc)"
|
||||||
|
|
||||||
printf "\n\tLaunch GTests to check\n"
|
printf "\n\tLaunch GTests to check\n"
|
||||||
# ./larra_xmpp_tests --gtest_brief=1
|
./larra_xmpp_tests --gtest_brief=1
|
||||||
|
|
||||||
GTEST_RES=$?
|
GTEST_RES=$?
|
||||||
cd ${PROJECT_FOLDER} && rm -rf ${GTEST_FOLDER?}
|
cd ${PROJECT_FOLDER} && rm -rf ${GTEST_FOLDER?}
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -40,7 +40,6 @@ temp*
|
||||||
#/.idea/codeStyles/Project.xml
|
#/.idea/codeStyles/Project.xml
|
||||||
#/.idea/vcs.xml
|
#/.idea/vcs.xml
|
||||||
/.idea/
|
/.idea/
|
||||||
.githooks/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -171,25 +171,25 @@ auto ConnectViaProxy(Socket& socket, const HttpProxy& param_proxy, std::string_v
|
||||||
|
|
||||||
// ответ от прокси-сервера
|
// ответ от прокси-сервера
|
||||||
boost::asio::streambuf response;
|
boost::asio::streambuf response;
|
||||||
std::size_t bytes_transferred = co_await boost::asio::async_read_until(socket, response, kEndOfHeaders, boost::asio::use_awaitable);
|
std::size_t bytesTransferred = co_await boost::asio::async_read_until(socket, response, kEndOfHeaders, boost::asio::use_awaitable);
|
||||||
|
|
||||||
// статус ответа
|
// статус ответа
|
||||||
std::istream response_stream(&response);
|
std::istream responseStream(&response);
|
||||||
std::string http_version;
|
std::string httpVersion;
|
||||||
unsigned int status_code = 0;
|
unsigned int statusCode = 0;
|
||||||
std::string status_message;
|
std::string statusMessage;
|
||||||
|
|
||||||
response_stream >> http_version >> status_code;
|
responseStream >> httpVersion >> statusCode;
|
||||||
std::getline(response_stream, status_message);
|
std::getline(responseStream, statusMessage);
|
||||||
|
|
||||||
if(!response_stream || http_version.substr(0, kEndOfHttpSubstring) != "HTTP/") {
|
if(!responseStream || httpVersion.substr(0, kEndOfHttpSubstring) != "HTTP/") {
|
||||||
throw std::runtime_error("Invalid HTTP response from proxy");
|
throw std::runtime_error("Invalid HTTP response from proxy");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(status_code != kSuccessStatusCode) {
|
if(statusCode != kSuccessStatusCode) {
|
||||||
std::ostringstream error_stream;
|
std::ostringstream errorStream;
|
||||||
error_stream << http_version << " " << status_code << " " << status_message;
|
errorStream << httpVersion << " " << statusCode << " " << statusMessage;
|
||||||
throw std::runtime_error("HTTP proxy CONNECT failed: " + error_stream.str());
|
throw std::runtime_error("HTTP proxy CONNECT failed: " + errorStream.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
|
|
|
@ -18,36 +18,36 @@ class ProxyTest : public ::testing::Test {
|
||||||
TEST_F(ProxyTest, ConnectViaHttpProxy_SuccessfulResponse) {
|
TEST_F(ProxyTest, ConnectViaHttpProxy_SuccessfulResponse) {
|
||||||
HttpProxy proxy{"proxy_host", 8080};
|
HttpProxy proxy{"proxy_host", 8080};
|
||||||
|
|
||||||
std::string target_host = "target_host";
|
std::string targetHost = "target_host";
|
||||||
uint16_t target_port = 80;
|
uint16_t targetPort = 80;
|
||||||
|
|
||||||
std::string expected_request =
|
std::string expectedRequest =
|
||||||
std::format("CONNECT {}:{} HTTP/1.1\r\nHost: {}:{}\r\n\r\n", target_host, target_port, target_host, target_port);
|
std::format("CONNECT {}:{} HTTP/1.1\r\nHost: {}:{}\r\n\r\n", targetHost, targetPort, targetHost, targetPort);
|
||||||
|
|
||||||
std::string proxy_response = "HTTP/1.1 200 Connection established\r\n\r\n";
|
std::string proxyResponse = "HTTP/1.1 200 Connection established\r\n\r\n";
|
||||||
|
|
||||||
mock_socket.AddReceivedData(proxy_response);
|
mock_socket.AddReceivedData(proxyResponse);
|
||||||
|
|
||||||
bool connect_successful = false;
|
bool connectSuccessful = false;
|
||||||
|
|
||||||
asio::co_spawn(
|
asio::co_spawn(
|
||||||
io_context,
|
io_context,
|
||||||
[&]() -> asio::awaitable<void> {
|
[&]() -> asio::awaitable<void> {
|
||||||
try {
|
try {
|
||||||
co_await client::impl::ConnectViaProxy(mock_socket, proxy, target_host, target_port);
|
co_await client::impl::ConnectViaProxy(mock_socket, proxy, targetHost, targetPort);
|
||||||
connect_successful = true;
|
connectSuccessful = true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
connect_successful = false;
|
connectSuccessful = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
asio::detached);
|
asio::detached);
|
||||||
|
|
||||||
io_context.run();
|
io_context.run();
|
||||||
|
|
||||||
std::string sent_data = mock_socket.GetSentData();
|
std::string sentData = mock_socket.GetSentData();
|
||||||
|
|
||||||
EXPECT_EQ(sent_data, expected_request);
|
EXPECT_EQ(sentData, expectedRequest);
|
||||||
EXPECT_TRUE(connect_successful);
|
EXPECT_TRUE(connectSuccessful);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test 2: Connect via SOCKS proxy
|
// Test 2: Connect via SOCKS proxy
|
||||||
|
@ -58,53 +58,53 @@ TEST(Socks5ProxyTest, ConnectViaProxy) {
|
||||||
larra::xmpp::impl::MockSocket socket{executor};
|
larra::xmpp::impl::MockSocket socket{executor};
|
||||||
|
|
||||||
// expected server responses
|
// expected server responses
|
||||||
std::string server_response;
|
std::string serverResponse;
|
||||||
server_response += "\x05\x00"; // VER, METHOD
|
serverResponse += "\x05\x00"; // VER, METHOD
|
||||||
server_response += "\x05\x00\x00\x01"; // VER, REP, RSV, ATYP (IPv4)
|
serverResponse += "\x05\x00\x00\x01"; // VER, REP, RSV, ATYP (IPv4)
|
||||||
server_response += "\x7F\x00\x00\x01"; // BND.ADDR (127.0.0.1)
|
serverResponse += "\x7F\x00\x00\x01"; // BND.ADDR (127.0.0.1)
|
||||||
server_response += "\x1F\x90"; // BND.PORT (8080)
|
serverResponse += "\x1F\x90"; // BND.PORT (8080)
|
||||||
|
|
||||||
socket.AddReceivedData(server_response);
|
socket.AddReceivedData(serverResponse);
|
||||||
|
|
||||||
Socks5Proxy proxy{"proxy.example.com", 1080};
|
Socks5Proxy proxy{"proxy.example.com", 1080};
|
||||||
std::string target_hostname = "target.example.com";
|
std::string targetHostname = "target.example.com";
|
||||||
std::uint16_t target_port = 80;
|
std::uint16_t targetPort = 80;
|
||||||
|
|
||||||
boost::asio::co_spawn(
|
boost::asio::co_spawn(
|
||||||
executor,
|
executor,
|
||||||
[&]() -> boost::asio::awaitable<void> {
|
[&]() -> boost::asio::awaitable<void> {
|
||||||
co_await client::impl::ConnectViaProxy(socket, proxy, target_hostname, target_port);
|
co_await client::impl::ConnectViaProxy(socket, proxy, targetHostname, targetPort);
|
||||||
|
|
||||||
auto sent_data = socket.GetSentData();
|
auto sentData = socket.GetSentData();
|
||||||
|
|
||||||
// Expected client greeting
|
// Expected client greeting
|
||||||
std::string expected_greeting = "\x05\x01\x00";
|
std::string expectedGreeting = "\x05\x01\x00";
|
||||||
|
|
||||||
// Expected CONNECT request
|
// Expected CONNECT request
|
||||||
std::array<std::uint8_t, 262> expected_request{};
|
std::array<std::uint8_t, 262> expectedRequest{};
|
||||||
std::size_t req_len = 0;
|
std::size_t req_len = 0;
|
||||||
|
|
||||||
expected_request[req_len++] = 0x05; // VER
|
expectedRequest[req_len++] = 0x05; // VER
|
||||||
expected_request[req_len++] = 0x01; // CMD: CONNECT
|
expectedRequest[req_len++] = 0x01; // CMD: CONNECT
|
||||||
expected_request[req_len++] = 0x00; // RSV
|
expectedRequest[req_len++] = 0x00; // RSV
|
||||||
expected_request[req_len++] = 0x03; // ATYP: DOMAINNAME
|
expectedRequest[req_len++] = 0x03; // ATYP: DOMAINNAME
|
||||||
|
|
||||||
expected_request[req_len++] = static_cast<std::uint8_t>(target_hostname.size()); // domain length
|
expectedRequest[req_len++] = static_cast<std::uint8_t>(targetHostname.size()); // domain length
|
||||||
|
|
||||||
std::memcpy(&expected_request[req_len], target_hostname.data(), target_hostname.size());
|
std::memcpy(&expectedRequest[req_len], targetHostname.data(), targetHostname.size());
|
||||||
req_len += target_hostname.size();
|
req_len += targetHostname.size();
|
||||||
|
|
||||||
std::uint16_t network_order_port = htons(target_port);
|
std::uint16_t networkOrderPort = htons(targetPort);
|
||||||
expected_request[req_len++] = static_cast<std::uint8_t>((network_order_port >> 8) & 0xFF);
|
expectedRequest[req_len++] = static_cast<std::uint8_t>((networkOrderPort >> 8) & 0xFF);
|
||||||
expected_request[req_len++] = static_cast<std::uint8_t>(network_order_port & 0xFF);
|
expectedRequest[req_len++] = static_cast<std::uint8_t>(networkOrderPort & 0xFF);
|
||||||
|
|
||||||
std::string expected_data = expected_greeting;
|
std::string expectedData = expectedGreeting;
|
||||||
auto transformed_view = expected_request | std::views::take(req_len) | std::views::transform([](std::uint8_t byte) {
|
auto transformed_view = expectedRequest | std::views::take(req_len) | std::views::transform([](std::uint8_t byte) {
|
||||||
return static_cast<char>(byte);
|
return static_cast<char>(byte);
|
||||||
});
|
});
|
||||||
|
|
||||||
expected_data.append(std::ranges::to<std::string>(transformed_view));
|
expectedData.append(std::ranges::to<std::string>(transformed_view));
|
||||||
EXPECT_EQ(sent_data, expected_data);
|
EXPECT_EQ(sentData, expectedData);
|
||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue