Details
-
Bug
-
Resolution: Out of scope
-
Not Evaluated
-
None
-
4.6.2
-
None
-
Ubuntu 9.04, 64 bits
Description
When using a QSslSocket, if I connect the readyRead() signal to a incomingData() slot with the following code:
void SslTest::incomingData() { QSslSocket * socket = qobject_cast<QSslSocket*>(sender()); QByteArray data; while(data.size() != 10000) { data.append(socket->readAll()); qDebug() << "Size:" << data.size(); socket->waitForReadyRead(5000); } }
and I send 10K (or any amount > 4096 bytes) on that socket (in one go) from another client (handshake went fine), I get the following output:
Size: 4096
Size: 4096
Size: 4096
Size: 4096
etc....
with 5s gaps between each line, meaning waitForReadyRead() times out, without ever seeing new data. So clearly, either waitForReadyRead() is not doing it's role, or readAll() isn't. But I can only get the first 4096 bytes from the original data sent.
Now, if I change this slot to :
void SslTest::incomingData()
{
QSslSocket * socket = qobject_cast<QSslSocket*>(sender());
QByteArray data;
data.append(socket->readAll());
qDebug() << "Size:" << data.size();
}
Then I get the correct (but somewhat unexpected) output, which properly adds up to 10k :
Size: 4096
Size: 4096
Size: 1808
I say "somewhat unexpected" because the data is cut in chunks of exactly 4096, but I guess that's due to the encryption.
I had a look at the qsslsocket sources, and noticed that readData(...) contained a "QMetaObject::invokeMethod(this, "_q_flushReadBuffer", Qt::QueuedConnection);". Obviously that's not going to get called from a waitForReadyRead() so I will never have the extra data I'm waiting for until I exit the incomingData() slot, even though it's probably in the plain socket's buffer, but not decrypted yet.
This bug seems to be very similar to this one:
http://www.qtcentre.org/threads/20513-QSslSocket-and-decryption-buffer
Also, I seem to not be the first to notice the strange implementation of the waitFor* family of functions of QSslSocket, as if you have a look in your own testsuite, in tests/auto/qsslsocket/tst_qsslsocket.cpp, you will find this comment (around line 1594):
// I don't understand how socket->waitForDisconnected can work on other platforms // since socket->write will end to: // QMetaObject::invokeMethod(this, "_q_flushWriteBuffer", Qt::QueuedConnection); // In order that _q_flushWriteBuffer will be called the eventloop need to run // If we just call waitForDisconnected, which blocks the whole thread how that can happen?
which is my point exactly.
Summary: I'd very much like to have access to more than 4096 bytes when using the blocking API with QSslSocket.