Skip to content

Commit 807a2bd

Browse files
Test stream handlers and Stream::is_readable()
1 parent afce9b5 commit 807a2bd

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

test/test.cc

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8351,3 +8351,109 @@ TEST(MaxTimeoutTest, ContentStreamSSL) {
83518351
max_timeout_test(svr, cli, timeout, threshold);
83528352
}
83538353
#endif
8354+
8355+
template <typename S, typename C>
8356+
static void stream_handler_test(S &svr, C &cli) {
8357+
const auto delay = std::chrono::milliseconds{200};
8358+
const auto timeout_us =
8359+
std::chrono::duration_cast<std::chrono::microseconds>(delay).count() / 2;
8360+
8361+
svr.Get("/", [delay](const Request &req, Response &res) {
8362+
// Request should contain limited default headers
8363+
EXPECT_EQ(req.has_header("Host"), true);
8364+
EXPECT_EQ(req.has_header("User-Agent"), true);
8365+
EXPECT_EQ(req.has_header("Connection"), true);
8366+
// Need connection to close at the end for test to succeed
8367+
EXPECT_EQ(req.get_header_value("Connection"), "close");
8368+
// REMOTE_ADDR, REMOTE_PORT, LOCAL_ADDR, LOCAL_PORT = 4
8369+
EXPECT_EQ(req.headers.size(), (4 + 3));
8370+
8371+
res.set_stream_handler([&](Stream &strm) -> bool {
8372+
char buf[16]{};
8373+
// Client shpuld time out first
8374+
std::this_thread::sleep_for(delay);
8375+
strm.write(buf, sizeof(buf));
8376+
8377+
// Synchronize with client and close connection
8378+
EXPECT_TRUE(strm.wait_readable());
8379+
8380+
return true;
8381+
});
8382+
});
8383+
auto thread = std::thread([&]() { svr.listen(HOST, PORT); });
8384+
8385+
auto se = detail::scope_exit([&] {
8386+
svr.stop();
8387+
thread.join();
8388+
ASSERT_FALSE(svr.is_running());
8389+
});
8390+
8391+
svr.wait_until_ready();
8392+
8393+
cli.set_read_timeout(0, timeout_us);
8394+
8395+
Request req;
8396+
req.method = "GET";
8397+
req.path = "/";
8398+
req.response_handler = [](const Response &res) -> bool {
8399+
EXPECT_EQ(res.get_header_value("Connection"), "close");
8400+
EXPECT_EQ(res.headers.size(), 1);
8401+
return true;
8402+
};
8403+
req.stream_handler = [delay](Stream &strm) -> bool {
8404+
char buf[16]{};
8405+
ssize_t n = 0;
8406+
// Buffer should be empty and first read should time out
8407+
EXPECT_FALSE(strm.is_readable());
8408+
EXPECT_FALSE(strm.wait_readable());
8409+
8410+
// Sever will send data soon
8411+
std::this_thread::sleep_for(delay);
8412+
EXPECT_TRUE(strm.wait_readable());
8413+
8414+
n = strm.read(buf, sizeof(buf) / 2);
8415+
EXPECT_EQ(sizeof(buf) / 2, n);
8416+
8417+
// Server sent 16 bytes, we read 8; remainder should be buffered
8418+
EXPECT_TRUE(strm.is_readable());
8419+
8420+
// Read remaining bytes from buffer
8421+
n = strm.read(buf, sizeof(buf) / 2);
8422+
EXPECT_EQ(sizeof(buf) / 2, n);
8423+
8424+
// Buffer should be empty
8425+
EXPECT_FALSE(strm.is_readable());
8426+
8427+
// Signal server to close connection
8428+
strm.write(buf, sizeof(buf));
8429+
std::this_thread::sleep_for(delay);
8430+
8431+
// Server should have closed connection
8432+
n = strm.read(buf, sizeof(buf));
8433+
EXPECT_EQ(0, n);
8434+
8435+
return true;
8436+
};
8437+
8438+
Response res;
8439+
Error error;
8440+
ASSERT_TRUE(cli.send(req, res, error));
8441+
EXPECT_EQ(StatusCode::OK_200, res.status);
8442+
EXPECT_EQ(res.headers.size(), 1);
8443+
EXPECT_TRUE(res.body.empty());
8444+
}
8445+
8446+
TEST(StreamHandlerTest, Basic) {
8447+
Server svr;
8448+
Client cli(HOST, PORT);
8449+
8450+
stream_handler_test(svr, cli);
8451+
}
8452+
8453+
TEST(StreamHandlerTest, BasicSSL) {
8454+
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
8455+
SSLClient cli(HOST, PORT);
8456+
cli.enable_server_certificate_verification(false);
8457+
8458+
stream_handler_test(svr, cli);
8459+
}

0 commit comments

Comments
 (0)