diff options
author | Markus Goetz <markus@woboq.com> | 2015-04-10 14:09:53 +0200 |
---|---|---|
committer | Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> | 2015-04-20 08:00:02 +0000 |
commit | cff39fba10ffc10ee4dcfdc66ff6528eb26462d3 (patch) | |
tree | 8ce12256215c34495a30f050ee8b0d6f5c6018c6 /src/network/access/qhttpprotocolhandler.cpp | |
parent | 68c137cc725ceadec68c455e0e3e365ecb00f2c1 (diff) |
QNAM: Fix upload corruptions when server closes connection
This patch fixes several upload corruptions if the server closes the connection
while/before we send data into it. They happen inside multiple places in the HTTP
layer and are explained in the comments.
Corruptions are:
* The upload byte device has an in-flight signal with pending upload data, if
it gets reset (because server closes the connection) then the re-send of the
request was sometimes taking this stale in-flight pending upload data.
* Because some signals were DirectConnection and some were QueuedConnection, there
was a chance that a direct signal overtakes a queued signal. The state machine
then sent data down the socket which was buffered there (and sent later) although
it did not match the current state of the state machine when it was actually sent.
* A socket was seen as being able to have requests sent even though it was not
encrypted yet. This relates to the previous corruption where data is stored inside
the socket's buffer and then sent later.
The included auto test produces all fixed corruptions, I detected no regressions
via the other tests.
This code also adds a bit of sanity checking to protect from possible further
problems.
[ChangeLog][QtNetwork] Fix HTTP(s) upload corruption when server closes connection
Change-Id: I54c883925ec897050941498f139c4b523030432e
Reviewed-by: Peter Hartmann <peter-qt@hartmann.tk>
Diffstat (limited to 'src/network/access/qhttpprotocolhandler.cpp')
-rw-r--r-- | src/network/access/qhttpprotocolhandler.cpp | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/src/network/access/qhttpprotocolhandler.cpp b/src/network/access/qhttpprotocolhandler.cpp index 28e10f751e..3357948519 100644 --- a/src/network/access/qhttpprotocolhandler.cpp +++ b/src/network/access/qhttpprotocolhandler.cpp @@ -368,6 +368,13 @@ bool QHttpProtocolHandler::sendRequest() // nothing to read currently, break the loop break; } else { + if (m_channel->written != uploadByteDevice->pos()) { + // Sanity check. This was useful in tracking down an upload corruption. + qWarning() << "QHttpProtocolHandler: Internal error in sendRequest. Expected to write at position" << m_channel->written << "but read device is at" << uploadByteDevice->pos(); + Q_ASSERT(m_channel->written == uploadByteDevice->pos()); + m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::ProtocolFailure); + return false; + } qint64 currentWriteSize = m_socket->write(readPointer, currentReadSize); if (currentWriteSize == -1 || currentWriteSize != currentReadSize) { // socket broke down |