diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-02-27 15:19:14 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-28 22:57:26 +0100 |
commit | 4bf27a24c088a36ba53f006f34c3f66e4d0369b9 (patch) | |
tree | 08aac86f8279eadc38ec6c99db473276a59c7e89 /src/network | |
parent | 0de55b6c9f5d266f891b746e2d63e6a45d3b3c32 (diff) |
Do not upload on closed SPDY streams
We should never upload on a SPDY stream in a closed or half-closed
state. To avoid it we need to stop listening for readyRead on the
upload device, and ignore WINDOW_UPDATE on completed streams.
This fixes SPDY access of facebook.com.
Change-Id: Icad45ffc109b2c14b921f1571e114b70a30f40a9
Reviewed-by: Peter Hartmann <phartmann@blackberry.com>
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/access/qspdyprotocolhandler.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp index 7c5d1c3d8f..ce8a2d2b1d 100644 --- a/src/network/access/qspdyprotocolhandler.cpp +++ b/src/network/access/qspdyprotocolhandler.cpp @@ -709,6 +709,11 @@ bool QSpdyProtocolHandler::uploadData(qint32 streamID) QHttpNetworkReplyPrivate *replyPrivate = reply->d_func(); Q_ASSERT(replyPrivate); + if (reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYHalfClosed || reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYClosed) { + qWarning() << Q_FUNC_INFO << "Trying to upload to closed stream"; + return false; + } + qint32 dataLeftInWindow = replyPrivate->windowSizeUpload - replyPrivate->currentlyUploadedDataInWindow; @@ -754,6 +759,8 @@ bool QSpdyProtocolHandler::uploadData(qint32 streamID) Q_ASSERT(writeSize == 0); Q_UNUSED(writeSize); // silence -Wunused-variable replyPrivate->state = QHttpNetworkReplyPrivate::SPDYHalfClosed; + if (reply->request().uploadByteDevice()) + reply->request().uploadByteDevice()->disconnect(this); // ### this will not work if the content length is not known, but // then again many servers will fail in this case anyhow according // to the SPDY RFC @@ -1179,6 +1186,10 @@ void QSpdyProtocolHandler::handleWINDOW_UPDATE(char /*flags*/, quint32 /*length* QHttpNetworkReplyPrivate *replyPrivate = reply->d_func(); Q_ASSERT(replyPrivate); + // Ignore WINDOW_UPDATE if we are already done. + if (replyPrivate->state == QHttpNetworkReplyPrivate::SPDYHalfClosed || replyPrivate->state == QHttpNetworkReplyPrivate::SPDYClosed) + return; + replyPrivate->currentlyUploadedDataInWindow = replyPrivate->windowSizeUpload - deltaWindowSize; uploadData(streamID); // we hopefully can continue to upload } @@ -1293,6 +1304,9 @@ void QSpdyProtocolHandler::handleDataFrame(const QByteArray &frameHeaders) void QSpdyProtocolHandler::replyFinished(QHttpNetworkReply *httpReply, qint32 streamID) { httpReply->d_func()->state = QHttpNetworkReplyPrivate::SPDYClosed; + httpReply->disconnect(this); + if (httpReply->request().uploadByteDevice()) + httpReply->request().uploadByteDevice()->disconnect(this); int streamsRemoved = m_inFlightStreams.remove(streamID); Q_ASSERT(streamsRemoved == 1); Q_UNUSED(streamsRemoved); // silence -Wunused-variable @@ -1304,6 +1318,9 @@ void QSpdyProtocolHandler::replyFinishedWithError(QHttpNetworkReply *httpReply, { Q_ASSERT(httpReply); httpReply->d_func()->state = QHttpNetworkReplyPrivate::SPDYClosed; + httpReply->disconnect(this); + if (httpReply->request().uploadByteDevice()) + httpReply->request().uploadByteDevice()->disconnect(this); int streamsRemoved = m_inFlightStreams.remove(streamID); Q_ASSERT(streamsRemoved == 1); Q_UNUSED(streamsRemoved); // silence -Wunused-variable |