diff options
author | Timur Pocheptsov <timur.pocheptsov@theqtcompany.com> | 2016-08-09 19:22:48 +0200 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@theqtcompany.com> | 2016-08-11 12:45:59 +0000 |
commit | 193abdfc0798cf10eac06769b650ac03e86eb55e (patch) | |
tree | 92ef3e1e58ea886a953bbb873fc7a9f23b3c9010 /src/network/access/qhttp2protocolhandler.cpp | |
parent | 615616b0699d98cfb9f4eeb67e005e3226398097 (diff) |
http2frame - do not rely on a socket's buffer
- Whenever we have a read notification, read this data, even if it's not
enough for a frame's header - otherwise, QNAM can use a socket
in an Ubuffered mode and FrameReader can potentially fail to read
anything correctly.
- Do not call/rely on bytesAvailable and do not try to invoke
_q_receiveReply in Qt::QueuedConnection mode, instead try to read
until we end up in an incomplete frame or some error.
Change-Id: I7f44ba9e34bc64f3e26bd29080f0050da635b3ae
Reviewed-by: Alex Trotsenko <alex1973tr@gmail.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/network/access/qhttp2protocolhandler.cpp')
-rw-r--r-- | src/network/access/qhttp2protocolhandler.cpp | 106 |
1 files changed, 51 insertions, 55 deletions
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index 937686920c..89d4a24e37 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -170,64 +170,60 @@ void QHttp2ProtocolHandler::_q_receiveReply() Q_ASSERT(m_socket); Q_ASSERT(m_channel); - const auto result = inboundFrame.read(*m_socket); - switch (result) { - case FrameStatus::incompleteFrame: - return; - case FrameStatus::protocolError: - return connectionError(PROTOCOL_ERROR, "invalid frame"); - case FrameStatus::sizeError: - return connectionError(FRAME_SIZE_ERROR, "invalid frame size"); - default: - break; - } - - Q_ASSERT(result == FrameStatus::goodFrame); - - if (continuationExpected && inboundFrame.type != FrameType::CONTINUATION) - return connectionError(PROTOCOL_ERROR, "CONTINUATION expected"); + do { + const auto result = inboundFrame.read(*m_socket); + switch (result) { + case FrameStatus::incompleteFrame: + return; + case FrameStatus::protocolError: + return connectionError(PROTOCOL_ERROR, "invalid frame"); + case FrameStatus::sizeError: + return connectionError(FRAME_SIZE_ERROR, "invalid frame size"); + default: + break; + } - switch (inboundFrame.type) { - case FrameType::DATA: - handleDATA(); - break; - case FrameType::HEADERS: - handleHEADERS(); - break; - case FrameType::PRIORITY: - handlePRIORITY(); - break; - case FrameType::RST_STREAM: - handleRST_STREAM(); - break; - case FrameType::SETTINGS: - handleSETTINGS(); - break; - case FrameType::PUSH_PROMISE: - handlePUSH_PROMISE(); - break; - case FrameType::PING: - handlePING(); - break; - case FrameType::GOAWAY: - handleGOAWAY(); - break; - case FrameType::WINDOW_UPDATE: - handleWINDOW_UPDATE(); - break; - case FrameType::CONTINUATION: - handleCONTINUATION(); - break; - case FrameType::LAST_FRAME_TYPE: - // 5.1 - ignore unknown frames. - break; - } + Q_ASSERT(result == FrameStatus::goodFrame); - if (goingAway && !activeStreams.size()) - return; + if (continuationExpected && inboundFrame.type != FrameType::CONTINUATION) + return connectionError(PROTOCOL_ERROR, "CONTINUATION expected"); - if (m_socket->bytesAvailable()) - QMetaObject::invokeMethod(m_channel, "_q_receiveReply", Qt::QueuedConnection); + switch (inboundFrame.type) { + case FrameType::DATA: + handleDATA(); + break; + case FrameType::HEADERS: + handleHEADERS(); + break; + case FrameType::PRIORITY: + handlePRIORITY(); + break; + case FrameType::RST_STREAM: + handleRST_STREAM(); + break; + case FrameType::SETTINGS: + handleSETTINGS(); + break; + case FrameType::PUSH_PROMISE: + handlePUSH_PROMISE(); + break; + case FrameType::PING: + handlePING(); + break; + case FrameType::GOAWAY: + handleGOAWAY(); + break; + case FrameType::WINDOW_UPDATE: + handleWINDOW_UPDATE(); + break; + case FrameType::CONTINUATION: + handleCONTINUATION(); + break; + case FrameType::LAST_FRAME_TYPE: + // 5.1 - ignore unknown frames. + break; + } + } while (!goingAway || activeStreams.size()); } bool QHttp2ProtocolHandler::sendRequest() |