summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorMÃ¥rten Nordheim <marten.nordheim@qt.io>2021-02-05 18:41:51 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-02-15 16:00:45 +0000
commit5c63d158c2b4a0d4c5ada4ca8da14ba4b3c069f0 (patch)
tree6321cad269c122ad729cdd314279a1321a4c7a60 /src/network
parent2e541d2ae2f66b45fa8181b5b1904ee234a78b77 (diff)
Schannel: Fix incomplete downloads with read buffer restricted
When the read buffer has a max size we do our best not to exceed it. Usually there's no problem and we just read more when the next tcp frame arrives. However if there's data leftover after the last tcp frame arrived then we won't receive any more data. To counter this QSslSocket would try to invoke QSslSocketPrivate::transmit indirectly if there were any bytes available on the plain socket. The problem is that with Schannel the last few remaining bytes would not be in the plain socket, but in the 'intermediateBuffer'. So let's make QSslSocket aware of that. Fixes: QTBUG-90625 Change-Id: If56e4cce558f99c9a08a1f6818e005a887712ef2 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Norbert Pfeiler <norbert.pfeiler+git@gmail.com> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> (cherry picked from commit 6d4da1340f18b66e60ed6969aeb7180e00d39077) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/network')
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--src/network/ssl/qsslsocket_p.h2
-rw-r--r--src/network/ssl/qsslsocket_schannel_p.h2
3 files changed, 5 insertions, 1 deletions
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index a7c6b16b19..c0d893cba7 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1798,7 +1798,7 @@ qint64 QSslSocket::readData(char *data, qint64 maxlen)
#endif
} else {
// possibly trigger another transmit() to decrypt more data from the socket
- if (d->plainSocket->bytesAvailable())
+ if (d->plainSocket->bytesAvailable() || d->hasUndecryptedData())
QMetaObject::invokeMethod(this, "_q_flushReadBuffer", Qt::QueuedConnection);
else if (d->state != QAbstractSocket::ConnectedState)
return maxlen ? qint64(-1) : qint64(0);
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 31b8b79302..161c3f2491 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -215,6 +215,8 @@ private:
static bool s_loadedCiphersAndCerts;
protected:
bool verifyErrorsHaveBeenIgnored();
+ // Only implemented/useful in Schannel for now
+ virtual bool hasUndecryptedData() { return false; };
bool paused;
bool flushTriggered;
bool systemOrSslErrorDetected = false;
diff --git a/src/network/ssl/qsslsocket_schannel_p.h b/src/network/ssl/qsslsocket_schannel_p.h
index 57c8c75629..30f5a9695b 100644
--- a/src/network/ssl/qsslsocket_schannel_p.h
+++ b/src/network/ssl/qsslsocket_schannel_p.h
@@ -123,6 +123,8 @@ private:
bool rootCertOnDemandLoadingAllowed();
+ bool hasUndecryptedData() override { return intermediateBuffer.size() > 0; }
+
SecPkgContext_ConnectionInfo connectionInfo = {};
SecPkgContext_StreamSizes streamSizes = {};