mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2025-05-12 06:01:40 +00:00
* Fix #1041 * Fixed problem with is_socket_alive * Adjust the way to check if the sockt is still alive. * Revert "Adjust the way to check if the sockt is still alive." This reverts commit 6c673b21e5439087e3cdc9c3dd39eba2d99928c8. * Adjust is_socket_alive according to the code review
This commit is contained in:
parent
9fa426d51b
commit
793ae9855e
14
httplib.h
14
httplib.h
@ -2337,6 +2337,17 @@ inline bool wait_until_socket_is_ready(socket_t sock, time_t sec, time_t usec) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool is_socket_alive(socket_t sock) {
|
||||||
|
const auto val = detail::select_read(sock, 0, 0);
|
||||||
|
if (val == 0) {
|
||||||
|
return true;
|
||||||
|
} else if (val < 0 && errno == EBADF) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char buf[1];
|
||||||
|
return detail::read_socket(sock, &buf[0], sizeof(buf), MSG_PEEK) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
class SocketStream : public Stream {
|
class SocketStream : public Stream {
|
||||||
public:
|
public:
|
||||||
SocketStream(socket_t sock, time_t read_timeout_sec, time_t read_timeout_usec,
|
SocketStream(socket_t sock, time_t read_timeout_sec, time_t read_timeout_usec,
|
||||||
@ -5723,13 +5734,14 @@ inline bool ClientImpl::send(Request &req, Response &res, Error &error) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(socket_mutex_);
|
std::lock_guard<std::mutex> guard(socket_mutex_);
|
||||||
|
|
||||||
// Set this to false immediately - if it ever gets set to true by the end of
|
// Set this to false immediately - if it ever gets set to true by the end of
|
||||||
// the request, we know another thread instructed us to close the socket.
|
// the request, we know another thread instructed us to close the socket.
|
||||||
socket_should_be_closed_when_request_is_done_ = false;
|
socket_should_be_closed_when_request_is_done_ = false;
|
||||||
|
|
||||||
auto is_alive = false;
|
auto is_alive = false;
|
||||||
if (socket_.is_open()) {
|
if (socket_.is_open()) {
|
||||||
is_alive = detail::select_write(socket_.sock, 0, 0) > 0;
|
is_alive = detail::is_socket_alive(socket_.sock);
|
||||||
if (!is_alive) {
|
if (!is_alive) {
|
||||||
// Attempt to avoid sigpipe by shutting down nongracefully if it seems
|
// Attempt to avoid sigpipe by shutting down nongracefully if it seems
|
||||||
// like the other side has already closed the connection Also, there
|
// like the other side has already closed the connection Also, there
|
||||||
|
30
test/test.cc
30
test/test.cc
@ -3756,6 +3756,36 @@ TEST(KeepAliveTest, ReadTimeout) {
|
|||||||
ASSERT_FALSE(svr.is_running());
|
ASSERT_FALSE(svr.is_running());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(KeepAliveTest, Issue1041) {
|
||||||
|
const auto resourcePath = "/hi";
|
||||||
|
|
||||||
|
Server svr;
|
||||||
|
svr.set_keep_alive_timeout(3);
|
||||||
|
|
||||||
|
svr.Get(resourcePath, [](const httplib::Request &, httplib::Response &res) {
|
||||||
|
res.set_content("Hello World!", "text/plain");
|
||||||
|
});
|
||||||
|
|
||||||
|
auto a2 = std::async(std::launch::async, [&svr]{ svr.listen(HOST, PORT); });
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
|
||||||
|
Client cli(HOST, PORT);
|
||||||
|
cli.set_keep_alive(true);
|
||||||
|
|
||||||
|
auto result = cli.Get(resourcePath);
|
||||||
|
ASSERT_TRUE(result);
|
||||||
|
EXPECT_EQ(200, result->status);
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||||
|
|
||||||
|
result = cli.Get(resourcePath);
|
||||||
|
ASSERT_TRUE(result);
|
||||||
|
EXPECT_EQ(200, result->status);
|
||||||
|
|
||||||
|
svr.stop();
|
||||||
|
a2.wait();
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ClientProblemDetectionTest, ContentProvider) {
|
TEST(ClientProblemDetectionTest, ContentProvider) {
|
||||||
Server svr;
|
Server svr;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user