This commit is contained in:
yhirose 2023-12-04 21:27:34 -05:00
parent 115a786581
commit c5c704cb3b
2 changed files with 44 additions and 0 deletions

View file

@ -382,6 +382,7 @@ public:
DataSink &operator=(DataSink &&) = delete;
std::function<bool(const char *data, size_t data_len)> write;
std::function<bool()> is_writable;
std::function<void()> done;
std::function<void(const Headers &trailer)> done_with_trailer;
std::ostream os;
@ -3959,6 +3960,8 @@ inline bool write_content(Stream &strm, const ContentProvider &content_provider,
return ok;
};
data_sink.is_writable = [&]() -> bool { return strm.is_writable(); };
while (offset < end_offset && !is_shutting_down()) {
if (!strm.is_writable()) {
error = Error::Write;
@ -4003,6 +4006,8 @@ write_content_without_length(Stream &strm,
return ok;
};
data_sink.is_writable = [&]() -> bool { return strm.is_writable(); };
data_sink.done = [&](void) { data_available = false; };
while (data_available && !is_shutting_down()) {
@ -4053,6 +4058,8 @@ write_content_chunked(Stream &strm, const ContentProvider &content_provider,
return ok;
};
data_sink.is_writable = [&]() -> bool { return strm.is_writable(); };
auto done_with_trailer = [&](const Headers *trailer) {
if (!ok) { return; }

View file

@ -4464,6 +4464,43 @@ TEST(ErrorHandlerWithContentProviderTest, ErrorHandler) {
EXPECT_EQ("helloworld", res->body);
}
TEST(LongPollingTest, ClientCloseDetection) {
Server svr;
svr.Get("/events", [&](const Request & /*req*/, Response &res) {
res.set_chunked_content_provider(
"text/plain", [](std::size_t const, DataSink &sink) -> bool {
EXPECT_TRUE(sink.is_writable()); // the socket is alive
sink.os << "hello";
auto count = 10;
while (count > 0 && sink.is_writable()) {
this_thread::sleep_for(chrono::milliseconds(10));
}
EXPECT_FALSE(sink.is_writable()); // the socket is closed
return true;
});
});
auto listen_thread = std::thread([&svr]() { svr.listen("localhost", PORT); });
auto se = detail::scope_exit([&] {
svr.stop();
listen_thread.join();
ASSERT_FALSE(svr.is_running());
});
svr.wait_until_ready();
Client cli("localhost", PORT);
auto res = cli.Get("/events", [&](const char *data, size_t data_length) {
EXPECT_EQ("hello", string(data, data_length));
return false; // close the socket immediately.
});
ASSERT_FALSE(res);
}
TEST(GetWithParametersTest, GetWithParameters) {
Server svr;