Skip to content

Commit 793ae98

Browse files
authored
* Fix yhirose#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 6c673b2. * Adjust is_socket_alive according to the code review
1 parent 9fa426d commit 793ae98

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

httplib.h

+13-1
Original file line numberDiff line numberDiff line change
@@ -2337,6 +2337,17 @@ inline bool wait_until_socket_is_ready(socket_t sock, time_t sec, time_t usec) {
23372337
#endif
23382338
}
23392339

2340+
inline bool is_socket_alive(socket_t sock) {
2341+
const auto val = detail::select_read(sock, 0, 0);
2342+
if (val == 0) {
2343+
return true;
2344+
} else if (val < 0 && errno == EBADF) {
2345+
return false;
2346+
}
2347+
char buf[1];
2348+
return detail::read_socket(sock, &buf[0], sizeof(buf), MSG_PEEK) > 0;
2349+
}
2350+
23402351
class SocketStream : public Stream {
23412352
public:
23422353
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) {
57235734

57245735
{
57255736
std::lock_guard<std::mutex> guard(socket_mutex_);
5737+
57265738
// Set this to false immediately - if it ever gets set to true by the end of
57275739
// the request, we know another thread instructed us to close the socket.
57285740
socket_should_be_closed_when_request_is_done_ = false;
57295741

57305742
auto is_alive = false;
57315743
if (socket_.is_open()) {
5732-
is_alive = detail::select_write(socket_.sock, 0, 0) > 0;
5744+
is_alive = detail::is_socket_alive(socket_.sock);
57335745
if (!is_alive) {
57345746
// Attempt to avoid sigpipe by shutting down nongracefully if it seems
57355747
// like the other side has already closed the connection Also, there

test/test.cc

+30
Original file line numberDiff line numberDiff line change
@@ -3756,6 +3756,36 @@ TEST(KeepAliveTest, ReadTimeout) {
37563756
ASSERT_FALSE(svr.is_running());
37573757
}
37583758

3759+
TEST(KeepAliveTest, Issue1041) {
3760+
const auto resourcePath = "/hi";
3761+
3762+
Server svr;
3763+
svr.set_keep_alive_timeout(3);
3764+
3765+
svr.Get(resourcePath, [](const httplib::Request &, httplib::Response &res) {
3766+
res.set_content("Hello World!", "text/plain");
3767+
});
3768+
3769+
auto a2 = std::async(std::launch::async, [&svr]{ svr.listen(HOST, PORT); });
3770+
std::this_thread::sleep_for(std::chrono::milliseconds(200));
3771+
3772+
Client cli(HOST, PORT);
3773+
cli.set_keep_alive(true);
3774+
3775+
auto result = cli.Get(resourcePath);
3776+
ASSERT_TRUE(result);
3777+
EXPECT_EQ(200, result->status);
3778+
3779+
std::this_thread::sleep_for(std::chrono::seconds(5));
3780+
3781+
result = cli.Get(resourcePath);
3782+
ASSERT_TRUE(result);
3783+
EXPECT_EQ(200, result->status);
3784+
3785+
svr.stop();
3786+
a2.wait();
3787+
}
3788+
37593789
TEST(ClientProblemDetectionTest, ContentProvider) {
37603790
Server svr;
37613791

0 commit comments

Comments
 (0)