1
0
mirror of synced 2025-04-21 22:25:55 +03:00
This commit is contained in:
yhirose 2018-04-06 17:02:37 -04:00
parent a0f50911e1
commit 5536d4c1ff
2 changed files with 79 additions and 15 deletions

View File

@ -437,25 +437,32 @@ inline int select_read(socket_t sock, size_t sec, size_t usec)
return select(sock + 1, &fds, NULL, NULL, &tv); return select(sock + 1, &fds, NULL, NULL, &tv);
} }
inline bool is_socket_writable(socket_t sock, size_t sec, size_t usec) inline bool wait_until_socket_is_ready(socket_t sock, size_t sec, size_t usec)
{ {
fd_set fdsw; fd_set fdsr;
FD_ZERO(&fdsw); FD_ZERO(&fdsr);
FD_SET(sock, &fdsw); FD_SET(sock, &fdsr);
fd_set fdse; auto fdsw = fdsr;
FD_ZERO(&fdse); auto fdse = fdsr;
FD_SET(sock, &fdse);
timeval tv; timeval tv;
tv.tv_sec = sec; tv.tv_sec = sec;
tv.tv_usec = usec; tv.tv_usec = usec;
if (select(sock + 1, NULL, &fdsw, &fdse, &tv) <= 0) { if (select(sock + 1, &fdsr, &fdsw, &fdse, &tv) < 0) {
return false;
} else if (FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw)) {
int error = 0;
socklen_t len = sizeof(error);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*)&error, &len) < 0 || error) {
return false;
}
} else {
return false; return false;
} }
return FD_ISSET(sock, &fdsw) != 0; return true;
} }
template <typename T> template <typename T>
@ -1690,13 +1697,16 @@ inline socket_t Client::create_client_socket() const
detail::set_nonblocking(sock, true); detail::set_nonblocking(sock, true);
auto ret = connect(sock, ai.ai_addr, ai.ai_addrlen); auto ret = connect(sock, ai.ai_addr, ai.ai_addrlen);
if (ret == -1 && detail::is_connection_error()) { if (ret < 0) {
return false; if (detail::is_connection_error() ||
!detail::wait_until_socket_is_ready(sock, timeout_sec_, 0)) {
detail::close_socket(sock);
return false;
}
} }
detail::set_nonblocking(sock, false); detail::set_nonblocking(sock, false);
return true;
return detail::is_socket_writable(sock, timeout_sec_, 0);
}); });
} }

View File

@ -121,7 +121,7 @@ TEST(GetHeaderValueTest, Range)
void testChunkedEncoding(httplib::HttpVersion ver) void testChunkedEncoding(httplib::HttpVersion ver)
{ {
auto host = "www.httpwatch.com"; auto host = "www.httpwatch.com";
auto sec = 5; auto sec = 2;
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto port = 443; auto port = 443;
@ -186,6 +186,60 @@ TEST(RangeTest, FromHTTPBin)
} }
} }
TEST(ConnectionErrorTest, InvalidHost)
{
auto host = "abcde.com";
auto sec = 2;
auto ver = httplib::HttpVersion::v1_1;
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto port = 443;
httplib::SSLClient cli(host, port, sec, ver);
#else
auto port = 80;
httplib::Client cli(host, port, sec, ver);
#endif
auto res = cli.get("/");
ASSERT_TRUE(res == nullptr);
}
TEST(ConnectionErrorTest, InvalidPort)
{
auto host = "localhost";
auto sec = 2;
auto ver = httplib::HttpVersion::v1_1;
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto port = 44380;
httplib::SSLClient cli(host, port, sec, ver);
#else
auto port = 8080;
httplib::Client cli(host, port, sec, ver);
#endif
auto res = cli.get("/");
ASSERT_TRUE(res == nullptr);
}
TEST(ConnectionErrorTest, Timeout)
{
auto host = "google.com";
auto sec = 2;
auto ver = httplib::HttpVersion::v1_1;
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto port = 44380;
httplib::SSLClient cli(host, port, sec, ver);
#else
auto port = 8080;
httplib::Client cli(host, port, sec, ver);
#endif
auto res = cli.get("/");
ASSERT_TRUE(res == nullptr);
}
class ServerTest : public ::testing::Test { class ServerTest : public ::testing::Test {
protected: protected:
ServerTest() ServerTest()
@ -584,7 +638,7 @@ TEST_F(ServerTest, GetMethodRemoteAddr)
ASSERT_TRUE(res != nullptr); ASSERT_TRUE(res != nullptr);
EXPECT_EQ(200, res->status); EXPECT_EQ(200, res->status);
EXPECT_EQ("text/plain", res->get_header_value("Content-Type")); EXPECT_EQ("text/plain", res->get_header_value("Content-Type"));
EXPECT_EQ("::1", res->body); // NOTE: depends on user's environment... EXPECT_TRUE(res->body == "::1" || res->body == "127.0.0.1");
} }
#ifdef CPPHTTPLIB_ZLIB_SUPPORT #ifdef CPPHTTPLIB_ZLIB_SUPPORT