Skip to content

WebSocket receiveFrame() keeps returning the same frame when no payload (flags/header only) #4884

@thunderbolt10

Description

@thunderbolt10

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

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions