summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qiodevice_p.h5
-rw-r--r--src/network/ssl/qsslsocket.cpp38
2 files changed, 32 insertions, 11 deletions
diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h
index 881d85904c..c6b27b1e16 100644
--- a/src/corelib/io/qiodevice_p.h
+++ b/src/corelib/io/qiodevice_p.h
@@ -110,6 +110,11 @@ public:
first += r;
return r;
}
+ int peek(char* target, int size) {
+ int r = qMin(size, len);
+ memcpy(target, first, r);
+ return r;
+ }
char* reserve(int size) {
makeSpace(size + len, freeSpaceAtEnd);
char* writePtr = first + len;
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 7fc36c8523..2b809a70d3 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -2249,15 +2249,24 @@ void QSslSocketPrivate::_q_flushReadBuffer()
qint64 QSslSocketPrivate::peek(char *data, qint64 maxSize)
{
if (mode == QSslSocket::UnencryptedMode && !autoStartHandshake) {
- if (plainSocket)
- return plainSocket->peek(data, maxSize);
- else
+ //unencrypted mode - do not use QIODevice::peek, as it reads ahead data from the plain socket
+ //peek at data already in the QIODevice buffer (from a previous read)
+ qint64 r = buffer.peek(data, maxSize);
+ if (r == maxSize)
+ return r;
+ data += r;
+ //peek at data in the plain socket
+ if (plainSocket) {
+ qint64 r2 = plainSocket->peek(data, maxSize - r);
+ if (r2 < 0)
+ return (r > 0 ? r : r2);
+ return r + r2;
+ } else {
return -1;
+ }
} else {
- QByteArray tmp;
- tmp = readBuffer.peek(maxSize);
- memcpy(data, tmp.data(), tmp.length());
- return tmp.length();
+ //encrypted mode - the socket engine will read and decrypt data into the QIODevice buffer
+ return QTcpSocketPrivate::peek(data, maxSize);
}
}
@@ -2267,14 +2276,21 @@ qint64 QSslSocketPrivate::peek(char *data, qint64 maxSize)
QByteArray QSslSocketPrivate::peek(qint64 maxSize)
{
if (mode == QSslSocket::UnencryptedMode && !autoStartHandshake) {
+ //unencrypted mode - do not use QIODevice::peek, as it reads ahead data from the plain socket
+ //peek at data already in the QIODevice buffer (from a previous read)
+ QByteArray ret;
+ ret.reserve(maxSize);
+ ret.resize(buffer.peek(ret.data(), maxSize));
+ if (ret.length() == maxSize)
+ return ret;
+ //peek at data in the plain socket
if (plainSocket)
- return plainSocket->peek(maxSize);
+ return ret + plainSocket->peek(maxSize - ret.length());
else
return QByteArray();
} else {
- QByteArray tmp;
- tmp = readBuffer.peek(maxSize);
- return tmp;
+ //encrypted mode - the socket engine will read and decrypt data into the QIODevice buffer
+ return QTcpSocketPrivate::peek(maxSize);
}
}