Client now supports event streams with \r\n line endings in addition to regular \n
This commit is contained in:
parent
7c44f73ec5
commit
66b6be499d
2 changed files with 58 additions and 5 deletions
|
|
@ -719,7 +719,7 @@ namespace SimpleWeb {
|
||||||
|
|
||||||
void read_server_sent_event(const std::shared_ptr<Session> &session, const std::shared_ptr<asio::streambuf> &events_streambuf) {
|
void read_server_sent_event(const std::shared_ptr<Session> &session, const std::shared_ptr<asio::streambuf> &events_streambuf) {
|
||||||
session->connection->set_timeout();
|
session->connection->set_timeout();
|
||||||
asio::async_read_until(*session->connection->socket, *events_streambuf, "\n\n", [this, session, events_streambuf](const error_code &ec, std::size_t /*bytes_transferred*/) {
|
asio::async_read_until(*session->connection->socket, *events_streambuf, HeaderEndMatch(), [this, session, events_streambuf](const error_code &ec, std::size_t /*bytes_transferred*/) {
|
||||||
session->connection->cancel_timeout();
|
session->connection->cancel_timeout();
|
||||||
auto lock = session->connection->handler_runner->continue_lock();
|
auto lock = session->connection->handler_runner->continue_lock();
|
||||||
if(!lock)
|
if(!lock)
|
||||||
|
|
@ -733,8 +733,8 @@ namespace SimpleWeb {
|
||||||
std::istream istream(events_streambuf.get());
|
std::istream istream(events_streambuf.get());
|
||||||
std::ostream ostream(&session->response->streambuf);
|
std::ostream ostream(&session->response->streambuf);
|
||||||
std::string line;
|
std::string line;
|
||||||
while(std::getline(istream, line) && !line.empty()) {
|
while(std::getline(istream, line) && !line.empty() && !(line.back() == '\r' && line.size() == 1)) {
|
||||||
ostream.write(line.data(), static_cast<std::streamsize>(line.size()));
|
ostream.write(line.data(), static_cast<std::streamsize>(line.size() - (line.back() == '\r' ? 1 : 0)));
|
||||||
ostream.put('\n');
|
ostream.put('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ int main() {
|
||||||
response->write("6\r\nSimple\r\n3\r\nWeb\r\nE\r\n in\r\n\r\nchunks.\r\n0\r\n\r\n", {{"Transfer-Encoding", "chunked"}});
|
response->write("6\r\nSimple\r\n3\r\nWeb\r\nE\r\n in\r\n\r\nchunks.\r\n0\r\n\r\n", {{"Transfer-Encoding", "chunked"}});
|
||||||
};
|
};
|
||||||
|
|
||||||
server.resource["^/event-stream$"]["GET"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> /*request*/) {
|
server.resource["^/event-stream1$"]["GET"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> /*request*/) {
|
||||||
thread work_thread([response] {
|
thread work_thread([response] {
|
||||||
response->close_connection_after_response = true; // Unspecified content length
|
response->close_connection_after_response = true; // Unspecified content length
|
||||||
|
|
||||||
|
|
@ -167,6 +167,31 @@ int main() {
|
||||||
work_thread.detach();
|
work_thread.detach();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
server.resource["^/event-stream2$"]["GET"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> /*request*/) {
|
||||||
|
thread work_thread([response] {
|
||||||
|
response->close_connection_after_response = true; // Unspecified content length
|
||||||
|
|
||||||
|
// Send header
|
||||||
|
promise<bool> header_error;
|
||||||
|
response->write({{"Content-Type", "text/event-stream"}});
|
||||||
|
response->send([&header_error](const SimpleWeb::error_code &ec) {
|
||||||
|
header_error.set_value(static_cast<bool>(ec));
|
||||||
|
});
|
||||||
|
ASSERT(!header_error.get_future().get());
|
||||||
|
|
||||||
|
*response << "data: 1\r\n\r\n";
|
||||||
|
promise<bool> error;
|
||||||
|
response->send([&error](const SimpleWeb::error_code &ec) {
|
||||||
|
error.set_value(static_cast<bool>(ec));
|
||||||
|
});
|
||||||
|
ASSERT(!error.get_future().get());
|
||||||
|
|
||||||
|
// Write result
|
||||||
|
*response << "data: 2\r\n\r\n";
|
||||||
|
});
|
||||||
|
work_thread.detach();
|
||||||
|
};
|
||||||
|
|
||||||
server.resource["^/session-close$"]["GET"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> /*request*/) {
|
server.resource["^/session-close$"]["GET"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> /*request*/) {
|
||||||
response->close_connection_after_response = true; // Unspecified content length
|
response->close_connection_after_response = true; // Unspecified content length
|
||||||
response->write("test", {{"Session", "close"}});
|
response->write("test", {{"Session", "close"}});
|
||||||
|
|
@ -371,7 +396,35 @@ int main() {
|
||||||
{
|
{
|
||||||
vector<int> calls(4, 0);
|
vector<int> calls(4, 0);
|
||||||
std::size_t call_num = 0;
|
std::size_t call_num = 0;
|
||||||
client.request("GET", "/event-stream", [&calls, &call_num](shared_ptr<HttpClient::Response> response, const SimpleWeb::error_code &ec) {
|
client.request("GET", "/event-stream1", [&calls, &call_num](shared_ptr<HttpClient::Response> response, const SimpleWeb::error_code &ec) {
|
||||||
|
calls.at(call_num) = 1;
|
||||||
|
if(call_num == 0) {
|
||||||
|
ASSERT(response->content.string().empty());
|
||||||
|
ASSERT(!ec);
|
||||||
|
}
|
||||||
|
else if(call_num == 1) {
|
||||||
|
ASSERT(response->content.string() == "data: 1\n");
|
||||||
|
ASSERT(!ec);
|
||||||
|
}
|
||||||
|
else if(call_num == 2) {
|
||||||
|
ASSERT(response->content.string() == "data: 2\n");
|
||||||
|
ASSERT(!ec);
|
||||||
|
}
|
||||||
|
else if(call_num == 3) {
|
||||||
|
ASSERT(response->content.string().empty());
|
||||||
|
ASSERT(ec == SimpleWeb::error::eof);
|
||||||
|
}
|
||||||
|
++call_num;
|
||||||
|
});
|
||||||
|
SimpleWeb::restart(*client.io_service);
|
||||||
|
client.io_service->run();
|
||||||
|
for(auto call : calls)
|
||||||
|
ASSERT(call);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
vector<int> calls(4, 0);
|
||||||
|
std::size_t call_num = 0;
|
||||||
|
client.request("GET", "/event-stream2", [&calls, &call_num](shared_ptr<HttpClient::Response> response, const SimpleWeb::error_code &ec) {
|
||||||
calls.at(call_num) = 1;
|
calls.at(call_num) = 1;
|
||||||
if(call_num == 0) {
|
if(call_num == 0) {
|
||||||
ASSERT(response->content.string().empty());
|
ASSERT(response->content.string().empty());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue