diff options
Diffstat (limited to 'test/other_tools/utils/curl_url.test.cpp')
-rw-r--r-- | test/other_tools/utils/curl_url.test.cpp | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/test/other_tools/utils/curl_url.test.cpp b/test/other_tools/utils/curl_url.test.cpp new file mode 100644 index 00000000..ebddeca9 --- /dev/null +++ b/test/other_tools/utils/curl_url.test.cpp @@ -0,0 +1,318 @@ +// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "catch2/catch.hpp" +#include "src/other_tools/utils/curl_url_handle.hpp" + +TEST_CASE("Curl URL handle basics", "[curl_url_handle_basics]") { + SECTION("Parse URL") { + // full syntax check + auto url_h_full = CurlURLHandle::Create( + "https://user:pass@example.com:50000/some/" + "pa.th?what=what&who=who#fragment"); + CHECK(url_h_full); + CHECK(*url_h_full); + // bare bone syntax check + auto url_h_thin = CurlURLHandle::Create("http://example.com"); + CHECK(url_h_thin); + CHECK(*url_h_thin); + // double dots in hostname + auto url_h_double_dots = CurlURLHandle::Create("http://..example..com"); + CHECK(url_h_double_dots); + CHECK(*url_h_double_dots); + // fail check + auto url_h_fail = CurlURLHandle::Create("file://foo:50505"); + CHECK(url_h_fail); + CHECK(not *url_h_fail); + } + + SECTION("Get URL") { + auto url_h = CurlURLHandle::Create("http://example.com:80"); + REQUIRE(url_h); + REQUIRE(*url_h); + + // get with default opts + auto ret_url = url_h.value()->GetURL(); + REQUIRE(ret_url); + CHECK(*ret_url == "http://example.com:80/"); + + // get with no default port + ret_url = url_h.value()->GetURL(false, /* use_default_port */ + false, /* use_default_scheme */ + true /* use_no_default_port */ + ); + REQUIRE(ret_url); + CHECK(*ret_url == "http://example.com/"); + } + + SECTION("Get scheme of URL") { + auto url_h = CurlURLHandle::Create("http://example.com:80"); + REQUIRE(url_h); + REQUIRE(*url_h); + + auto ret_url = url_h.value()->GetScheme(); + REQUIRE(ret_url); + CHECK(*ret_url == "http"); + } + + SECTION("Duplicate URL") { + auto url_h = CurlURLHandle::Create("http://example.com"); + REQUIRE(url_h); + REQUIRE(*url_h); + auto url_h_dup = url_h.value()->Duplicate(); + REQUIRE(url_h_dup); + CHECK(url_h.value()->GetURL() == url_h_dup->GetURL()); + } + + SECTION("Parse URL with permissive arguments") { + // guess scheme from hostname + auto url_h_guess_scheme = + CurlURLHandle::CreatePermissive("ftp.example.com", true); + CHECK(url_h_guess_scheme); + CHECK(*url_h_guess_scheme); + // check what was stored: path as-is stops after first slash + auto ret_url_guess_scheme = url_h_guess_scheme.value()->GetURL(); + REQUIRE(ret_url_guess_scheme); + CHECK(*ret_url_guess_scheme == "ftp://ftp.example.com/"); + + // non-supported scheme, no authority, path not normalized + auto url_h_nonstandard_scheme = CurlURLHandle::CreatePermissive( + "socks5:///foo/../bar#boo", false, false, true, true, true); + CHECK(url_h_nonstandard_scheme); + CHECK(*url_h_nonstandard_scheme); + // check what was stored: path as-is but without preceding slash + auto ret_url_nonstandard_scheme = + url_h_nonstandard_scheme.value()->GetURL(); + REQUIRE(ret_url_nonstandard_scheme); + CHECK(*ret_url_nonstandard_scheme == "socks5://foo/../bar#boo"); + + // bare IP treated with http scheme as default works (proxy-style) + auto url_h_bare_ip = + CurlURLHandle::CreatePermissive("192.0.2.1", true, false, true); + CHECK(url_h_bare_ip); + CHECK(*url_h_bare_ip); + // check what was stored: defaults to http + auto ret_url_bare_ip = url_h_bare_ip.value()->GetURL(); + REQUIRE(ret_url_bare_ip); + CHECK(*ret_url_bare_ip == "http://192.0.2.1/"); + + // default scheme, no authority, path not normalized + auto url_h_empty = + CurlURLHandle::CreatePermissive("", false, true, false, true, true); + CHECK(url_h_empty); + CHECK(*url_h_empty); + // check what was stored: scheme http, path single slash + auto ret_url_empty = url_h_empty.value()->GetURL(); + REQUIRE(ret_url_empty); + CHECK(*ret_url_empty == "https:///"); + } + + SECTION("Parse config key") { + auto key_h = CurlURLHandle::ParseConfigKey( + "http://user@*.com/foo/bar?query#fragment"); + CHECK(key_h); + REQUIRE(*key_h); + + // check exact fields + CHECK(key_h.value()->scheme); + CHECK(key_h.value()->scheme.value() == "http"); + CHECK(key_h.value()->user); + CHECK(key_h.value()->user.value() == "user"); + CHECK(key_h.value()->host); + CHECK(key_h.value()->host.value() == "*.com"); + CHECK(key_h.value()->port); + CHECK(key_h.value()->port.value() == "80"); // default http port + CHECK(key_h.value()->path.string() == "/foo/bar?query#fragment/"); + } +} + +TEST_CASE("Curl URL match config key", "[curl_url_match_config_key]") { + auto url_h = + CurlURLHandle::Create("http://user@example.com/foo/bar?query#fragment"); + REQUIRE(url_h); + REQUIRE(*url_h); + + SECTION("Match exactly") { + auto match_exactly = url_h.value()->MatchConfigKey( + "http://user@example.com/foo/bar?query#fragment"); + REQUIRE(match_exactly); + + CHECK(match_exactly->matched); + CHECK(match_exactly->host_len == 11); + CHECK(match_exactly->path_len == 24); + CHECK(match_exactly->user_matched); + } + + SECTION("Match without user") { + auto match_wo_user = url_h.value()->MatchConfigKey( + "http://example.com/foo/bar?query#fragment"); + REQUIRE(match_wo_user); + + CHECK(match_wo_user->matched); + CHECK(match_wo_user->host_len == 11); + CHECK(match_wo_user->path_len == 24); + CHECK(not match_wo_user->user_matched); + } + + SECTION("Match with default port") { + auto match_default_port = url_h.value()->MatchConfigKey( + "http://user@example.com:80/foo/bar?query#fragment"); + REQUIRE(match_default_port); + + CHECK(match_default_port->matched); + CHECK(match_default_port->host_len == 11); + CHECK(match_default_port->path_len == 24); + CHECK(match_default_port->user_matched); + } + + SECTION("Match with path prefix") { + auto match_path_prefix = + url_h.value()->MatchConfigKey("http://user@example.com/foo"); + REQUIRE(match_path_prefix); + + CHECK(match_path_prefix->matched); + CHECK(match_path_prefix->host_len == 11); + CHECK(match_path_prefix->path_len == 5); + CHECK(match_path_prefix->user_matched); + } + + SECTION("Match with path normalization") { + auto match_path_normal = url_h.value()->MatchConfigKey( + "http://user@example.com/./foo/boo/.."); + REQUIRE(match_path_normal); + + CHECK(match_path_normal->matched); + CHECK(match_path_normal->host_len == 11); + CHECK(match_path_normal->path_len == 5); + CHECK(match_path_normal->user_matched); + } + + SECTION("Match with wildcarded host") { + auto match_wildcard_host = url_h.value()->MatchConfigKey( + "http://user@*.com/foo/bar?query#fragment"); + REQUIRE(match_wildcard_host); + + CHECK(match_wildcard_host->matched); + CHECK(match_wildcard_host->host_len == 5); + CHECK(match_wildcard_host->path_len == 24); + CHECK(match_wildcard_host->user_matched); + } + + SECTION("Match with multiple wildcarded host") { + auto match_wildcard_host = url_h.value()->MatchConfigKey( + "http://user@*.*/foo/bar?query#fragment"); + REQUIRE(match_wildcard_host); + + CHECK(match_wildcard_host->matched); + CHECK(match_wildcard_host->host_len == 3); + CHECK(match_wildcard_host->path_len == 24); + CHECK(match_wildcard_host->user_matched); + } + + SECTION("Match fail with unparsable key") { + auto match_fail_parse = url_h.value()->MatchConfigKey("192.0.2.1"); + REQUIRE(match_fail_parse); + + CHECK(not match_fail_parse->matched); + CHECK(match_fail_parse->host_len == 0); + CHECK(match_fail_parse->path_len == 0); + CHECK(not match_fail_parse->user_matched); + } + + SECTION("Match fail with wrong host") { + auto match_fail_host = url_h.value()->MatchConfigKey( + "http://user@example.org/foo/bar?query#fragment"); + REQUIRE(match_fail_host); + + CHECK(not match_fail_host->matched); + CHECK(match_fail_host->host_len == 0); + CHECK(match_fail_host->path_len == 0); + CHECK(not match_fail_host->user_matched); + } + + SECTION("Match fail with wrong port") { + auto match_fail_port = url_h.value()->MatchConfigKey( + "http://user@example.com:1234/foo/bar?query#fragment"); + REQUIRE(match_fail_port); + + CHECK(not match_fail_port->matched); + CHECK(match_fail_port->host_len == 0); + CHECK(match_fail_port->path_len == 0); + CHECK(not match_fail_port->user_matched); + } + + SECTION("Match fail with wrong path") { + auto match_fail_path = + url_h.value()->MatchConfigKey("http://user@example.com/foo/bar"); + REQUIRE(match_fail_path); + + CHECK(not match_fail_path->matched); + CHECK(match_fail_path->host_len == 0); + CHECK(match_fail_path->path_len == 0); + CHECK(not match_fail_path->user_matched); + } +} + +TEST_CASE("Curl URL match no_proxy patterns", "[curl_url_match_no-proxy]") { + auto url_h = CurlURLHandle::Create( + "http://user@example.com:50000/foo/bar?query#fragment"); + REQUIRE(url_h); + REQUIRE(*url_h); + + SECTION("Match with wildcard") { + auto match_wildcard = url_h.value()->NoproxyStringMatches("*"); + REQUIRE(match_wildcard); + CHECK(*match_wildcard); + } + + SECTION("Match with host") { + auto match_host = url_h.value()->NoproxyStringMatches("example.com"); + REQUIRE(match_host); + CHECK(*match_host); + } + + SECTION("Match with domain only") { + auto match_domain = url_h.value()->NoproxyStringMatches("com"); + REQUIRE(match_domain); + CHECK(*match_domain); + } + + SECTION("Match with stripped leading dot") { + auto match_host_leading_dot = + url_h.value()->NoproxyStringMatches(".example.com"); + REQUIRE(match_host_leading_dot); + CHECK(*match_host_leading_dot); + } + + SECTION("Match with port") { + auto match_port = + url_h.value()->NoproxyStringMatches("example.com:50000"); + REQUIRE(match_port); + CHECK(*match_port); + } + + SECTION("Match from multiple patterns") { + auto match_check_parse = + url_h.value()->NoproxyStringMatches("fail, wrong *"); + REQUIRE(match_check_parse); + CHECK(*match_check_parse); + } + + SECTION("Match fail with wrong patterns") { + auto match_fail = + url_h.value()->NoproxyStringMatches("fail, wrong :50000,example"); + REQUIRE(match_fail); + CHECK(not *match_fail); + } +} |