Jens Geyer created THRIFT-6231:
----------------------------------
Summary: C++ and D WebSocket servers take a frame header that
arrives in more than one read for the end of the stream
Key: THRIFT-6231
URL: https://issues.apache.org/jira/browse/THRIFT-6231
Project: Thrift
Issue Type: Bug
Components: C++ - Library, D - Library
Reporter: Jens Geyer
{{TWebSocketServer::readFrame()}} in C++ and
{{TServerWebSocketTransport.readFrame()}} in D read each part of a frame header
-- the first two bytes, the 16- or 64-bit extended payload length, and the
four-byte masking key -- with a single {{read()}} on the transport underneath,
and take a short read for the end of the stream:
{code:cpp}
auto read = transport_->read(headerBuffer, 2);
if (read < 2) {
return false;
}
{code}
A socket read returns whatever one {{recv()}} produced ({{TSocket::read}} in
C++, {{TSocket.read}} in D), so a segment boundary that falls inside a frame
header ends the connection. THRIFT-6178 made the payload read wait for the
whole payload; the header reads were left as they were. Nothing unusual is
needed on the client side: when frames follow one another on a connection, a
boundary can fall anywhere in the stream, headers included.
Reproduced on master (C++) after the handshake, with a transport that serves
one chunk per read as in {{lib/cpp/test/TWebSocketServerTest.cpp}}, and one
well-formed, masked 11-byte frame carrying "hello":
||Frame delivered as||{{readAll(buf, 5)}} returns||
|one piece|5|
|1 byte, then the rest|0|
|2 bytes, then the rest|5|
|3 bytes, then the rest|0|
|4 bytes, then the rest|0|
|6 bytes, then the rest|5|
|8 bytes, then the rest|5|
The D transport reads its header the same way: served at most 1, 2 or 3 bytes
per read, {{readFrame()}} returns {{false}} for the same frame; at 8 bytes per
read it returns the payload.
Possible change: read the header fields with {{readAll()}} too, and turn
{{END_OF_FILE}} into the {{return false}} the caller sees today -- as
THRIFT-6178 does for the payload.
_Drafted with AI assistance (Claude Opus 5); reviewed and filed by Jens Geyer._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)