-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
After upgrading Poco from 1.13 to 1.14.1 client websockets now constantly loop on receive continuously reading the same header frame without completing or timeout.
There are 2 implementations of WebSocketImpl::receiveBytes. This issue relates to int WebSocketImpl::receiveBytes(Poco::Buffer<char>& buffer, int, const Poco::Timespan&)
which is missing a call to skipHeader()
if the payloadLength is zero. The same header therefore remains in the buffer the next time receiveBytes()
is called.
To reproduce the socket must receive either a PING or PONG frame where the payloadLength is zero.
The other implementation of receiveBytes,
int WebSocketImpl::receiveBytes(void* buffer, int length, int)
appears to be correct as it calls skipHeader for zero payloadLength.
if (payloadLength <= 0)
{
skipHeader(_receiveState.headerLength);
return payloadLength;
}
A solution for the receiveBytes with Timespan implementation could be to move the call to skipHeader several lines forward so that it is always called regardless of payloadLength.
int WebSocketImpl::receiveBytes(Poco::Buffer<char>& buffer, int, const Poco::Timespan&)
{
if (getBlocking())
{
int payloadLength = -1;
while (payloadLength < 0)
{
payloadLength = peekHeader(_receiveState);
}
skipHeader(_receiveState.headerLength); <--- move to here
if (payloadLength <= 0)
{
return payloadLength;
}
// skipHeader(_receiveState.headerLength); <--- original location
POCO version 1.14.1
OS Windows 11