summaryrefslogtreecommitdiffstats
path: root/src/network/access
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2014-02-27 16:21:43 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-06 12:21:14 +0100
commit2df1a6c4c9c7bed8dceb23a6b53014fb42014ded (patch)
tree40f9b18f01809ece61ab51ca7ec466d91635b4d7 /src/network/access
parent27015857223fe59ed7a164c1837fcd57e1b625ee (diff)
Cleanup SPDY stream closing
We should not accept or process messages on closed streams, and unless we are in a half-closed state (having initiated close ourselves), we should respond to FIN with a FIN of our own. This patch means we no longer trigger all the corner case teardown on common sites that were fixed in earlier patches. Change-Id: I0d2bab62700a0022a959e66c7053afbad07a9f7e Reviewed-by: Peter Hartmann <phartmann@blackberry.com>
Diffstat (limited to 'src/network/access')
-rw-r--r--src/network/access/qspdyprotocolhandler.cpp49
1 files changed, 16 insertions, 33 deletions
diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp
index 6d5885eb68..6d22ebeb35 100644
--- a/src/network/access/qspdyprotocolhandler.cpp
+++ b/src/network/access/qspdyprotocolhandler.cpp
@@ -911,6 +911,11 @@ void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameD
QHttpNetworkReply *httpReply = pair.second;
Q_ASSERT(httpReply != 0);
+ if (httpReply->d_func()->state == QHttpNetworkReplyPrivate::SPDYClosed) {
+ sendRST_STREAM(streamID, RST_STREAM_STREAM_ALREADY_CLOSED);
+ return;
+ }
+
QByteArray uncompressedHeader;
if (!uncompressHeader(headerValuePairs, &uncompressedHeader)) {
qWarning() << Q_FUNC_INFO << "error reading header from SYN_REPLY message";
@@ -973,22 +978,9 @@ void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameD
emit httpReply->headerChanged();
if (flag_fin) {
- switch (httpReply->d_func()->state) {
- case QHttpNetworkReplyPrivate::SPDYSYNSent:
- httpReply->d_func()->state = QHttpNetworkReplyPrivate::SPDYHalfClosed;
- break;
- case QHttpNetworkReplyPrivate::SPDYHalfClosed:
- replyFinished(httpReply, streamID);
- break;
- case QHttpNetworkReplyPrivate::SPDYClosed: {
- sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR);
- replyFinishedWithError(httpReply, streamID, QNetworkReply::ProtocolFailure,
- "server sent SYN_REPLY on an already closed stream");
- break;
- }
- default:
- qWarning() << Q_FUNC_INFO << "got data frame in unknown state";
- }
+ if (httpReply->d_func()->state != QHttpNetworkReplyPrivate::SPDYHalfClosed)
+ sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, 0);
+ replyFinished(httpReply, streamID);
}
}
@@ -1238,6 +1230,11 @@ void QSpdyProtocolHandler::handleDataFrame(const QByteArray &frameHeaders)
QHttpNetworkReplyPrivate *replyPrivate = httpReply->d_func();
+ if (replyPrivate->state == QHttpNetworkReplyPrivate::SPDYClosed) {
+ sendRST_STREAM(streamID, RST_STREAM_STREAM_ALREADY_CLOSED);
+ return;
+ }
+
// check whether we need to send WINDOW_UPDATE (i.e. tell the sender it can send more)
replyPrivate->currentlyReceivedDataInWindow += length;
qint32 dataLeftInWindow = replyPrivate->windowSizeDownload - replyPrivate->currentlyReceivedDataInWindow;
@@ -1290,23 +1287,9 @@ void QSpdyProtocolHandler::handleDataFrame(const QByteArray &frameHeaders)
}
if (flag_fin) {
- switch (httpReply->d_func()->state) {
- case QHttpNetworkReplyPrivate::SPDYSYNSent:
- httpReply->d_func()->state = QHttpNetworkReplyPrivate::SPDYHalfClosed;
- // ### send FIN ourselves?
- break;
- case QHttpNetworkReplyPrivate::SPDYHalfClosed:
- replyFinished(httpReply, streamID);
- break;
- case QHttpNetworkReplyPrivate::SPDYClosed: {
- sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR);
- replyFinishedWithError(httpReply, streamID, QNetworkReply::ProtocolFailure,
- "server sent data on an already closed stream");
- break;
- }
- default:
- qWarning() << Q_FUNC_INFO << "got data frame in unknown state";
- }
+ if (httpReply->d_func()->state != QHttpNetworkReplyPrivate::SPDYHalfClosed)
+ sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, 0);
+ replyFinished(httpReply, streamID);
}
}