summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2014-02-27 15:19:14 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-28 22:57:26 +0100
commit4bf27a24c088a36ba53f006f34c3f66e4d0369b9 (patch)
tree08aac86f8279eadc38ec6c99db473276a59c7e89 /src/network
parent0de55b6c9f5d266f891b746e2d63e6a45d3b3c32 (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.cpp17
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