[Libreoffice-commits] online.git: 2 commits - loolwsd/Connect.cpp loolwsd/IoUtil.cpp loolwsd/LOOLWebSocket.hpp loolwsd/LOOLWSD.cpp loolwsd/test
Michael Meeks
michael.meeks at collabora.com
Fri Nov 25 09:53:49 UTC 2016
loolwsd/Connect.cpp | 11 ++++------
loolwsd/IoUtil.cpp | 42 ++++++++++++++++++++++++++++++-----------
loolwsd/LOOLWSD.cpp | 5 +---
loolwsd/LOOLWebSocket.hpp | 21 ++++++++++++++++----
loolwsd/test/UnitFonts.cpp | 13 ++++++------
loolwsd/test/helpers.hpp | 40 +++++++++++++++++++++++++++------------
loolwsd/test/httpcrashtest.cpp | 9 +++-----
loolwsd/test/httpwstest.cpp | 40 ++++++++++++++++-----------------------
8 files changed, 111 insertions(+), 70 deletions(-)
New commits:
commit 4432aba25b6ee68356e0ddfc724afb8373651945
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Fri Nov 25 09:48:59 2016 +0000
Revert "loolwsd: support reading long messages directly"
This reverts commit 84607b43a31574533471defcb4756ba855f835f1.
LOOLWebSocket piece requires a much too recent Poco.
diff --git a/loolwsd/IoUtil.cpp b/loolwsd/IoUtil.cpp
index adf5c55..035dcf8 100644
--- a/loolwsd/IoUtil.cpp
+++ b/loolwsd/IoUtil.cpp
@@ -50,17 +50,17 @@ void SocketProcessor(const std::shared_ptr<LOOLWebSocket>& ws,
// Timeout given is in microseconds.
static const Poco::Timespan waitTime(POLL_TIMEOUT_MS * 1000);
- constexpr auto bufferSize = READ_BUFFER_SIZE * 8;
-
+ const auto bufferSize = READ_BUFFER_SIZE * 100;
int flags = 0;
int n = -1;
bool stop = false;
std::vector<char> payload(bufferSize);
- Poco::Buffer<char> buffer(bufferSize);
try
{
ws->setReceiveTimeout(0);
+ payload.resize(0);
+
for (;;)
{
stop = stopPredicate();
@@ -79,12 +79,10 @@ void SocketProcessor(const std::shared_ptr<LOOLWebSocket>& ws,
try
{
- payload.resize(0);
- buffer.resize(0);
+ payload.resize(payload.capacity());
n = -1;
- n = ws->receiveFrame(buffer, flags);
- LOG_WRN("GOT: [" << LOOLProtocol::getAbbreviatedMessage(buffer.begin(), buffer.size()) << "]");
- payload.insert(payload.end(), buffer.begin(), buffer.end());
+ n = ws->receiveFrame(payload.data(), payload.capacity(), flags);
+ payload.resize(n > 0 ? n : 0);
}
catch (const Poco::TimeoutException&)
{
@@ -101,7 +99,7 @@ void SocketProcessor(const std::shared_ptr<LOOLWebSocket>& ws,
assert(n > 0);
- const std::string firstLine = LOOLProtocol::getFirstLine(buffer.begin(), buffer.size());
+ const std::string firstLine = LOOLProtocol::getFirstLine(payload);
if ((flags & WebSocket::FrameFlags::FRAME_FLAG_FIN) != WebSocket::FrameFlags::FRAME_FLAG_FIN)
{
// One WS message split into multiple frames.
@@ -109,7 +107,8 @@ void SocketProcessor(const std::shared_ptr<LOOLWebSocket>& ws,
LOG_WRN("SocketProcessor [" << name << "]: Receiving multi-parm frame.");
while (true)
{
- n = ws->receiveFrame(buffer, flags);
+ char buffer[READ_BUFFER_SIZE * 10];
+ n = ws->receiveFrame(buffer, sizeof(buffer), flags);
if (n <= 0 || (flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_CLOSE)
{
LOG_WRN("SocketProcessor [" << name << "]: Connection closed while reading multiframe message.");
@@ -117,7 +116,7 @@ void SocketProcessor(const std::shared_ptr<LOOLWebSocket>& ws,
break;
}
- payload.insert(payload.end(), buffer.begin(), buffer.end());
+ payload.insert(payload.end(), buffer, buffer + n);
if ((flags & WebSocket::FrameFlags::FRAME_FLAG_FIN) == WebSocket::FrameFlags::FRAME_FLAG_FIN)
{
// No more frames.
@@ -125,6 +124,27 @@ void SocketProcessor(const std::shared_ptr<LOOLWebSocket>& ws,
}
}
}
+ else
+ {
+ int size = 0;
+ Poco::StringTokenizer tokens(firstLine, " ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
+ // Check if it is a "nextmessage:" and in that case read the large
+ // follow-up message separately, and handle that only.
+ if (tokens.count() == 2 && tokens[0] == "nextmessage:" &&
+ LOOLProtocol::getTokenInteger(tokens[1], "size", size) && size > 0)
+ {
+ LOG_TRC("SocketProcessor [" << name << "]: Getting large message of " << size << " bytes.");
+ if (size > MAX_MESSAGE_SIZE)
+ {
+ LOG_ERR("SocketProcessor [" << name << "]: Large-message size (" << size << ") over limit or invalid.");
+ }
+ else
+ {
+ payload.resize(size);
+ continue;
+ }
+ }
+ }
if (n <= 0 || (flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_CLOSE)
{
diff --git a/loolwsd/LOOLWebSocket.hpp b/loolwsd/LOOLWebSocket.hpp
index fb1d88b..e10af2a 100644
--- a/loolwsd/LOOLWebSocket.hpp
+++ b/loolwsd/LOOLWebSocket.hpp
@@ -108,39 +108,6 @@ public:
return -1;
}
-
- /// Wrapper for Poco::Net::WebSocket::receiveFrame() that handles PING frames
- /// (by replying with a PONG frame) and PONG frames. PONG frames are ignored.
- /// Should we also factor out the handling of non-final and continuation frames into this?
- int receiveFrame(Poco::Buffer<char>& buffer, int& flags)
- {
-#ifdef ENABLE_DEBUG
- // Delay receiving the frame
- std::this_thread::sleep_for(getWebSocketDelay());
-#endif
- // Timeout given is in microseconds.
- static const Poco::Timespan waitTime(POLL_TIMEOUT_MS * 1000);
-
- while (poll(waitTime, Poco::Net::Socket::SELECT_READ))
- {
- const int n = Poco::Net::WebSocket::receiveFrame(buffer, flags);
- if (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_PING)
- {
- sendFrame(buffer.begin(), n, WebSocket::FRAME_FLAG_FIN | WebSocket::FRAME_OP_PONG);
- }
- else if ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_PONG)
- {
- // In case we do send pongs in the future.
- }
- else
- {
- return n;
- }
- }
-
- return -1;
- }
-
/// Wrapper for Poco::Net::WebSocket::sendFrame() that handles large frames.
int sendFrame(const char* buffer, const int length, const int flags = FRAME_TEXT)
{
@@ -150,6 +117,19 @@ public:
#endif
std::unique_lock<std::mutex> lock(_mutex);
+ // Size after which messages will be sent preceded with
+ // 'nextmessage' frame to let the receiver know in advance
+ // the size of larger coming message. All messages up to this
+ // size are considered small messages.
+ constexpr int SMALL_MESSAGE_SIZE = READ_BUFFER_SIZE / 2;
+
+ if (length > SMALL_MESSAGE_SIZE)
+ {
+ const std::string nextmessage = "nextmessage: size=" + std::to_string(length);
+ Poco::Net::WebSocket::sendFrame(nextmessage.data(), nextmessage.size());
+ Log::debug("Message is long, sent " + nextmessage);
+ }
+
const int result = Poco::Net::WebSocket::sendFrame(buffer, length, flags);
lock.unlock();
diff --git a/loolwsd/test/helpers.hpp b/loolwsd/test/helpers.hpp
index 7e5f039..30aeac1 100644
--- a/loolwsd/test/helpers.hpp
+++ b/loolwsd/test/helpers.hpp
@@ -197,7 +197,6 @@ std::vector<char> getResponseMessage(LOOLWebSocket& ws, const std::string& prefi
int retries = timeoutMs / 500;
const Poco::Timespan waitTime(retries ? timeoutMs * 1000 / retries : timeoutMs * 1000);
std::vector<char> response;
- Poco::Buffer<char> buffer(READ_BUFFER_SIZE);
bool timedout = false;
ws.setReceiveTimeout(0);
@@ -211,10 +210,9 @@ std::vector<char> getResponseMessage(LOOLWebSocket& ws, const std::string& prefi
timedout = false;
}
- response.resize(0);
- buffer.resize(0);
- const int bytes = ws.receiveFrame(buffer, flags);
- response.insert(response.end(), buffer.begin(), buffer.end());
+ response.resize(READ_BUFFER_SIZE);
+ int bytes = ws.receiveFrame(response.data(), response.size(), flags);
+ response.resize(bytes >= 0 ? bytes : 0);
std::cerr << name << "Got " << LOOLProtocol::getAbbreviatedFrameDump(response.data(), bytes, flags) << std::endl;
const auto message = LOOLProtocol::getFirstLine(response);
if (bytes > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE)
@@ -223,6 +221,26 @@ std::vector<char> getResponseMessage(LOOLWebSocket& ws, const std::string& prefi
{
return response;
}
+ else if (LOOLProtocol::matchPrefix("nextmessage", message))
+ {
+ int size = 0;
+ if (LOOLProtocol::getTokenIntegerFromMessage(message, "size", size) && size > 0)
+ {
+ response.resize(size);
+ bytes = ws.receiveFrame(response.data(), response.size(), flags);
+ response.resize(bytes >= 0 ? bytes : 0);
+ std::cerr << name << "Got " << LOOLProtocol::getAbbreviatedFrameDump(response.data(), bytes, flags) << std::endl;
+ if (bytes > 0 &&
+ LOOLProtocol::matchPrefix(prefix, LOOLProtocol::getFirstLine(response)))
+ {
+ return response;
+ }
+ }
+ }
+ }
+ else
+ {
+ response.resize(0);
}
if (bytes <= 0)
commit a2058341a389f09d8b8763a56aecbc0a1d3c7591
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Fri Nov 25 09:46:01 2016 +0000
Revert "loolwsd: kill receiveFrame with char* and cleanup usage cases"
This reverts commit 45c1856c6ad1753f8a90d3bb90711ab0338d623c.
This patch requires a very bleeding edge Poco, reverting for now.
diff --git a/loolwsd/Connect.cpp b/loolwsd/Connect.cpp
index aad78fa..5b550dd 100644
--- a/loolwsd/Connect.cpp
+++ b/loolwsd/Connect.cpp
@@ -89,24 +89,23 @@ public:
{
do
{
- Poco::Buffer<char> buffer(READ_BUFFER_SIZE);
- buffer.resize(0);
- n = _ws.receiveFrame(buffer, flags);
+ char buffer[100000];
+ n = _ws.receiveFrame(buffer, sizeof(buffer), flags);
if (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE)
{
{
std::unique_lock<std::mutex> lock(coutMutex);
- std::cout << "Got " << getAbbreviatedFrameDump(buffer.begin(), n, flags) << std::endl;
+ std::cout << "Got " << getAbbreviatedFrameDump(buffer, n, flags) << std::endl;
}
- const std::string firstLine = getFirstLine(buffer.begin(), n);
+ std::string firstLine = getFirstLine(buffer, n);
StringTokenizer tokens(firstLine, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
if (std::getenv("DISPLAY") != nullptr && tokens[0] == "tile:")
{
TemporaryFile pngFile;
std::ofstream pngStream(pngFile.path(), std::ios::binary);
- pngStream.write(buffer.begin() + firstLine.size() + 1, n - firstLine.size() - 1);
+ pngStream.write(buffer + firstLine.size() + 1, n - firstLine.size() - 1);
pngStream.close();
if (std::system((std::string("display ") + pngFile.path()).c_str()) == -1)
{
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index b7ad287..5ca3fce 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -196,7 +196,7 @@ void shutdownLimitReached(LOOLWebSocket& ws)
{
int flags = 0;
int retries = 7;
- Poco::Buffer<char> buffer(READ_BUFFER_SIZE);
+ std::vector<char> buffer(READ_BUFFER_SIZE * 100);
const Poco::Timespan waitTime(POLL_TIMEOUT_MS * 1000);
do
@@ -214,8 +214,7 @@ void shutdownLimitReached(LOOLWebSocket& ws)
// Ignore incoming messages.
if (ws.poll(waitTime, Poco::Net::Socket::SELECT_READ))
{
- buffer.resize(0);
- ws.receiveFrame(buffer, flags);
+ ws.receiveFrame(buffer.data(), buffer.capacity(), flags);
}
// Shutdown.
diff --git a/loolwsd/LOOLWebSocket.hpp b/loolwsd/LOOLWebSocket.hpp
index 827c324..fb1d88b 100644
--- a/loolwsd/LOOLWebSocket.hpp
+++ b/loolwsd/LOOLWebSocket.hpp
@@ -79,6 +79,39 @@ public:
/// Wrapper for Poco::Net::WebSocket::receiveFrame() that handles PING frames
/// (by replying with a PONG frame) and PONG frames. PONG frames are ignored.
/// Should we also factor out the handling of non-final and continuation frames into this?
+ int receiveFrame(char* buffer, const int length, int& flags)
+ {
+#ifdef ENABLE_DEBUG
+ // Delay receiving the frame
+ std::this_thread::sleep_for(getWebSocketDelay());
+#endif
+ // Timeout given is in microseconds.
+ static const Poco::Timespan waitTime(POLL_TIMEOUT_MS * 1000);
+
+ while (poll(waitTime, Poco::Net::Socket::SELECT_READ))
+ {
+ const int n = Poco::Net::WebSocket::receiveFrame(buffer, length, flags);
+ if ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_PING)
+ {
+ sendFrame(buffer, n, WebSocket::FRAME_FLAG_FIN | WebSocket::FRAME_OP_PONG);
+ }
+ else if ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_PONG)
+ {
+ // In case we do send pongs in the future.
+ }
+ else
+ {
+ return n;
+ }
+ }
+
+ return -1;
+ }
+
+
+ /// Wrapper for Poco::Net::WebSocket::receiveFrame() that handles PING frames
+ /// (by replying with a PONG frame) and PONG frames. PONG frames are ignored.
+ /// Should we also factor out the handling of non-final and continuation frames into this?
int receiveFrame(Poco::Buffer<char>& buffer, int& flags)
{
#ifdef ENABLE_DEBUG
diff --git a/loolwsd/test/UnitFonts.cpp b/loolwsd/test/UnitFonts.cpp
index 232ecb2..60312d4 100644
--- a/loolwsd/test/UnitFonts.cpp
+++ b/loolwsd/test/UnitFonts.cpp
@@ -44,16 +44,17 @@ namespace {
std::string readFontList(const std::shared_ptr<LOOLWebSocket> &socket)
{
int flags;
- Poco::Buffer<char> buffer(READ_BUFFER_SIZE);
+ char buffer[100 * 1000];
- buffer.resize(0);
- const int length = socket->receiveFrame(buffer, flags);
+ int length = socket->receiveFrame(buffer, sizeof (buffer), flags);
if (length > 0)
{
- return std::string(buffer.begin(), length);
+ assert(length<(int)sizeof(buffer));
+ buffer[length] = '\0';
+ return std::string(buffer);
}
-
- return std::string("read failure");
+ else
+ return std::string("read failure");
}
}
diff --git a/loolwsd/test/helpers.hpp b/loolwsd/test/helpers.hpp
index c6c730a..7e5f039 100644
--- a/loolwsd/test/helpers.hpp
+++ b/loolwsd/test/helpers.hpp
@@ -173,8 +173,7 @@ int getErrorCode(LOOLWebSocket& ws, std::string& message)
ws.setReceiveTimeout(timeout);
do
{
- buffer.resize(0);
- bytes = ws.receiveFrame(buffer, flags);
+ bytes = ws.receiveFrame(buffer.begin(), READ_BUFFER_SIZE, flags);
}
while ((flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE);
@@ -410,7 +409,7 @@ void SocketProcessor(const std::string& name,
const Poco::Timespan waitTime(timeoutMs * 1000);
int flags = 0;
int n = 0;
- Poco::Buffer<char> buffer(READ_BUFFER_SIZE);
+ char buffer[READ_BUFFER_SIZE];
do
{
if (!socket->poll(waitTime, Poco::Net::Socket::SELECT_READ))
@@ -419,12 +418,11 @@ void SocketProcessor(const std::string& name,
break;
}
- buffer.resize(0);
- n = socket->receiveFrame(buffer, flags);
- std::cerr << name << "Got " << LOOLProtocol::getAbbreviatedFrameDump(buffer.begin(), n, flags) << std::endl;
+ n = socket->receiveFrame(buffer, sizeof(buffer), flags);
+ std::cerr << name << "Got " << LOOLProtocol::getAbbreviatedFrameDump(buffer, n, flags) << std::endl;
if (n > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE)
{
- if (!handler(std::string(buffer.begin(), n)))
+ if (!handler(std::string(buffer, n)))
{
break;
}
diff --git a/loolwsd/test/httpcrashtest.cpp b/loolwsd/test/httpcrashtest.cpp
index b9a297c..1bfd4f2 100644
--- a/loolwsd/test/httpcrashtest.cpp
+++ b/loolwsd/test/httpcrashtest.cpp
@@ -164,12 +164,11 @@ void HTTPCrashTest::testCrashKit()
// receive close frame handshake
int bytes;
int flags;
- Poco::Buffer<char> buffer(READ_BUFFER_SIZE);
+ char buffer[READ_BUFFER_SIZE];
do
{
- buffer.resize(0);
- bytes = socket->receiveFrame(buffer, flags);
- std::cerr << testname << "Got " << LOOLProtocol::getAbbreviatedFrameDump(buffer.begin(), bytes, flags) << std::endl;
+ bytes = socket->receiveFrame(buffer, sizeof(buffer), flags);
+ std::cerr << testname << "Got " << LOOLProtocol::getAbbreviatedFrameDump(buffer, bytes, flags) << std::endl;
}
while ((flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE);
@@ -177,7 +176,7 @@ void HTTPCrashTest::testCrashKit()
socket->shutdown();
// no more messages is received.
- bytes = socket->receiveFrame(buffer, flags);
+ bytes = socket->receiveFrame(buffer, sizeof(buffer), flags);
CPPUNIT_ASSERT_MESSAGE("Expected no more data", bytes <= 2); // The 2-byte marker is ok.
CPPUNIT_ASSERT_EQUAL(0x88, flags);
}
diff --git a/loolwsd/test/httpwstest.cpp b/loolwsd/test/httpwstest.cpp
index eeff3f4..1e65fc2 100644
--- a/loolwsd/test/httpwstest.cpp
+++ b/loolwsd/test/httpwstest.cpp
@@ -253,42 +253,37 @@ void HTTPWSTest::testHandShake()
socket.setReceiveTimeout(0);
int flags = 0;
- Poco::Buffer<char> buffer(READ_BUFFER_SIZE);
- buffer.resize(0);
- int bytes = socket.receiveFrame(buffer, flags);
- CPPUNIT_ASSERT_EQUAL(std::string("statusindicator: find"), std::string(buffer.begin(), bytes));
-
- buffer.resize(0);
- bytes = socket.receiveFrame(buffer, flags);
- if (bytes > 0 && !std::strstr(buffer.begin(), "error:"))
+ char buffer[1024] = {0};
+ int bytes = socket.receiveFrame(buffer, sizeof(buffer), flags);
+ CPPUNIT_ASSERT_EQUAL(std::string("statusindicator: find"), std::string(buffer, bytes));
+
+ bytes = socket.receiveFrame(buffer, sizeof(buffer), flags);
+ if (bytes > 0 && !std::strstr(buffer, "error:"))
{
- CPPUNIT_ASSERT_EQUAL(std::string("statusindicator: connect"), std::string(buffer.begin(), bytes));
+ CPPUNIT_ASSERT_EQUAL(std::string("statusindicator: connect"), std::string(buffer, bytes));
- buffer.resize(0);
- bytes = socket.receiveFrame(buffer, flags);
- if (!std::strstr(buffer.begin(), "error:"))
+ bytes = socket.receiveFrame(buffer, sizeof(buffer), flags);
+ if (!std::strstr(buffer, "error:"))
{
- CPPUNIT_ASSERT_EQUAL(std::string("statusindicator: ready"), std::string(buffer.begin(), bytes));
+ CPPUNIT_ASSERT_EQUAL(std::string("statusindicator: ready"), std::string(buffer, bytes));
}
else
{
// check error message
- CPPUNIT_ASSERT(std::strstr(SERVICE_UNAVAILABLE_INTERNAL_ERROR, buffer.begin()) != nullptr);
+ CPPUNIT_ASSERT(std::strstr(SERVICE_UNAVAILABLE_INTERNAL_ERROR, buffer) != nullptr);
// close frame message
- buffer.resize(0);
- bytes = socket.receiveFrame(buffer, flags);
+ bytes = socket.receiveFrame(buffer, sizeof(buffer), flags);
CPPUNIT_ASSERT((flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) == Poco::Net::WebSocket::FRAME_OP_CLOSE);
}
}
else
{
// check error message
- CPPUNIT_ASSERT(std::strstr(SERVICE_UNAVAILABLE_INTERNAL_ERROR, buffer.begin()) != nullptr);
+ CPPUNIT_ASSERT(std::strstr(SERVICE_UNAVAILABLE_INTERNAL_ERROR, buffer) != nullptr);
// close frame message
- buffer.resize(0);
- bytes = socket.receiveFrame(buffer, flags);
+ bytes = socket.receiveFrame(buffer, sizeof(buffer), flags);
CPPUNIT_ASSERT((flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) == Poco::Net::WebSocket::FRAME_OP_CLOSE);
}
}
@@ -314,16 +309,15 @@ void HTTPWSTest::testCloseAfterClose()
// receive close frame handshake
int bytes;
int flags;
- Poco::Buffer<char> buffer(READ_BUFFER_SIZE);
+ char buffer[READ_BUFFER_SIZE];
do
{
- buffer.resize(0);
- bytes = socket->receiveFrame(buffer, flags);
+ bytes = socket->receiveFrame(buffer, sizeof(buffer), flags);
}
while (bytes && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE);
// no more messages is received.
- bytes = socket->receiveFrame(buffer, flags);
+ bytes = socket->receiveFrame(buffer, sizeof(buffer), flags);
std::cerr << "Received " << bytes << " bytes, flags: "<< std::hex << flags << std::dec << std::endl;
CPPUNIT_ASSERT_EQUAL(0, bytes);
CPPUNIT_ASSERT_EQUAL(0, flags);
More information about the Libreoffice-commits
mailing list