mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-24 12:04:40 +00:00
Keep a Client usable when its URL cannot be used
An unsupported scheme without exceptions, or a port out of range, left Client with no implementation, so the first request after it went through a null pointer. Put a client in its place that reports itself invalid and fails every request with Error::Connection.
This commit is contained in:
1 parent
0116be0a2b
commit
b270564c18
2 files changed
+27
-1
No files matched your search
@@ -3103,6 +3103,24 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
// Stands in for a client that Client could not make from its arguments, so a
|
||||||
|
// request fails rather than going through a null pointer.
|
||||||
|
class InvalidClientImpl final : public ClientImpl {
|
||||||
|
public:
|
||||||
|
InvalidClientImpl() : ClientImpl(std::string(), 0) {}
|
||||||
|
bool is_valid() const override { return false; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool create_and_connect_socket(Socket &, Error &error) override {
|
||||||
|
error = Error::Connection;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
// Universal interface
|
// Universal interface
|
||||||
@@ -17697,6 +17715,7 @@ inline Client::Client(const std::string &scheme_host_port,
|
|||||||
std::string msg = "'" + scheme + "' scheme is not supported.";
|
std::string msg = "'" + scheme + "' scheme is not supported.";
|
||||||
throw std::invalid_argument(msg);
|
throw std::invalid_argument(msg);
|
||||||
#endif
|
#endif
|
||||||
|
cli_ = detail::make_unique<detail::InvalidClientImpl>();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17705,7 +17724,10 @@ inline Client::Client(const std::string &scheme_host_port,
|
|||||||
auto host = std::move(uc.host);
|
auto host = std::move(uc.host);
|
||||||
|
|
||||||
auto port = is_ssl ? 443 : 80;
|
auto port = is_ssl ? 443 : 80;
|
||||||
if (!uc.port.empty() && !detail::parse_port(uc.port, port)) { return; }
|
if (!uc.port.empty() && !detail::parse_port(uc.port, port)) {
|
||||||
|
cli_ = detail::make_unique<detail::InvalidClientImpl>();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_ssl) {
|
if (is_ssl) {
|
||||||
#ifdef CPPHTTPLIB_SSL_ENABLED
|
#ifdef CPPHTTPLIB_SSL_ENABLED
|
||||||
|
|||||||
@@ -14627,6 +14627,10 @@ TEST(HostAndPortPropertiesTest, PortOutOfRange) {
|
|||||||
// Port 99999 exceeds valid range (1-65535) — should not crash
|
// Port 99999 exceeds valid range (1-65535) — should not crash
|
||||||
httplib::Client cli("http://www.google.com:99999");
|
httplib::Client cli("http://www.google.com:99999");
|
||||||
ASSERT_FALSE(cli.is_valid());
|
ASSERT_FALSE(cli.is_valid());
|
||||||
|
|
||||||
|
auto res = cli.Get("/");
|
||||||
|
EXPECT_FALSE(res);
|
||||||
|
EXPECT_EQ(Error::Connection, res.error());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(HostAndPortPropertiesTest, TrailingCharactersInPort) {
|
TEST(HostAndPortPropertiesTest, TrailingCharactersInPort) {
|
||||||
|
|||||||
Reference in new issue
Block a user