diff --git a/src/http.cc b/src/http.cc index 8af3dfa..a96177b 100644 --- a/src/http.cc +++ b/src/http.cc @@ -140,18 +140,22 @@ Url Url::Parse(std::string value) { unsigned int port = 0; struct sockaddr_in6 dst; if (inet_pton(AF_INET6, host.c_str(), &(dst.sin6_addr)) <= 0) { - if (host.front() != '[' || host.back() != ']') { + if ((host.front() != '[' || host.back() != ']') && utils::Contains(host, ':')) { std::stringstream ss(host); std::string portstr; while (std::getline(ss, portstr, ':')) { } if (!portstr.empty()) { - try { - port = static_cast(std::stoi(portstr)); + char* str_end{}; + const long l = std::strtol(portstr.c_str(), &str_end, 10); + size_t length = std::distance(portstr.c_str(), const_cast(str_end)); + if (length == portstr.size()) { + if (l < 1 || l > 65535) { + return Url{}; + } + port = static_cast(l); host = host.substr(0, host.rfind(":" + portstr)); - } catch (const std::invalid_argument&) { - port = 0; } } } diff --git a/src/request.cc b/src/request.cc index 9b6130c..0b199d0 100644 --- a/src/request.cc +++ b/src/request.cc @@ -162,6 +162,7 @@ BaseUrl::BaseUrl(std::string host, bool https, std::string region) return; } + this->https = url.https; this->host = url.host; this->port = url.port; diff --git a/tests/tests.cc b/tests/tests.cc index 427dd62..f8fa3aa 100644 --- a/tests/tests.cc +++ b/tests/tests.cc @@ -699,6 +699,36 @@ class Tests { throw; } } + + void TestBaseUrl() { + std::cout << "TestBaseUrl()" << std::endl; + std::vector> tests = { + {"http://localhost:9000", "localhost", false, 9000}, + {"http://localhost", "localhost", false, 0}, + {"http://localhost:80", "localhost", false, 0}, + {"https://localhost:9443", "localhost", true, 9443}, + {"https://localhost", "localhost", true, 0}, + {"https://5.localhost.foo", "5.localhost.foo", true, 0}, + {"https://5.localhost.foo:9000", "5.localhost.foo", true, 9000}, + }; + for (auto& [url, host, https, port] : tests) { + minio::s3::BaseUrl base_url(url); + if (base_url.host != host) { + throw std::runtime_error("BaseUrl(" + url +").host: expected: " + host + + ", got: " + base_url.host); + } + if (base_url.https != https) { + throw std::runtime_error("BaseUrl("+ url +").https: expected: " + + std::to_string(https) + + ", got: " + std::to_string(base_url.https)); + } + if (base_url.port != port) { + throw std::runtime_error("BaseUrl("+ url +").port: expected: " + + std::to_string(port) + + ", got: " + std::to_string(base_url.port)); + } + } + } }; // class Tests int main(int /*argc*/, char* /*argv*/[]) { @@ -756,6 +786,7 @@ int main(int /*argc*/, char* /*argv*/[]) { tests.RemoveObjects(); tests.SelectObjectContent(); tests.ListenBucketNotification(); + tests.TestBaseUrl(); return EXIT_SUCCESS; }