summaryrefslogtreecommitdiffstats
path: root/src/network/access/qhttp2protocolhandler.cpp
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@theqtcompany.com>2016-08-09 19:22:48 +0200
committerTimur Pocheptsov <timur.pocheptsov@theqtcompany.com>2016-08-11 12:45:59 +0000
commit193abdfc0798cf10eac06769b650ac03e86eb55e (patch)
tree92ef3e1e58ea886a953bbb873fc7a9f23b3c9010 /src/network/access/qhttp2protocolhandler.cpp
parent615616b0699d98cfb9f4eeb67e005e3226398097 (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.cpp106
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()