diff options
author | Shane Kearns <ext-shane.2.kearns@nokia.com> | 2012-03-27 19:28:44 (GMT) |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-03-30 12:44:53 (GMT) |
commit | 621f18955082fc73471e75d1f8c35c2dcd4befeb (patch) | |
tree | 8e1f8c4c30c3fddda147f9c27fb6ec733e87515f /tests/auto | |
parent | fc1e202e776934f4d286b206c84ee9c82440f7b1 (diff) | |
download | Qt-621f18955082fc73471e75d1f8c35c2dcd4befeb.zip Qt-621f18955082fc73471e75d1f8c35c2dcd4befeb.tar.gz Qt-621f18955082fc73471e75d1f8c35c2dcd4befeb.tar.bz2 |
Fix regressions due to partial QSslSocket::peek fix
The fix broke HTTPS transactions with chunked encoding.
It also broke use of a QSslSocket in unencrypted mode where peek
and read calls are mixed.
See change 68b1d5c17aa38d5921bdade2b0e0cb67c6c90513.
Change-Id: Ib115b3737b0e4217496f5def10aaaea3c6452ff8
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/qsslsocket/tst_qsslsocket.cpp | 132 |
1 files changed, 131 insertions, 1 deletions
diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp index cf4d04e..1c43095 100644 --- a/tests/auto/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp @@ -191,6 +191,7 @@ private slots: void writeBigChunk(); void blacklistedCertificates(); void qtbug18498_peek(); + void qtbug18498_peek2(); void setEmptyDefaultConfiguration(); static void exitLoop() @@ -2119,7 +2120,7 @@ void tst_QSslSocket::qtbug18498_peek() QVERIFY(server.listen(QHostAddress::LocalHost)); client->connectToHost("127.0.0.1", server.serverPort()); QVERIFY(client->waitForConnected(5000)); - QVERIFY(server.waitForNewConnection(0)); + QVERIFY(server.waitForNewConnection(1000)); client->setObjectName("client"); client->ignoreSslErrors(); @@ -2159,6 +2160,135 @@ void tst_QSslSocket::qtbug18498_peek() QCOMPARE(read_data, data); } +class SslServer5 : public QTcpServer +{ + Q_OBJECT +public: + SslServer5() : socket(0) {} + QSslSocket *socket; + +protected: + void incomingConnection(int socketDescriptor) + { + socket = new QSslSocket; + socket->setSocketDescriptor(socketDescriptor); + } +}; + +void tst_QSslSocket::qtbug18498_peek2() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + SslServer5 listener; + QVERIFY(listener.listen(QHostAddress::Any)); + QScopedPointer<QSslSocket> client(new QSslSocket); + client->connectToHost(QHostAddress::LocalHost, listener.serverPort()); + QVERIFY(client->waitForConnected(5000)); + QVERIFY(listener.waitForNewConnection(1000)); + + QScopedPointer<QSslSocket> server(listener.socket); + + QVERIFY(server->write("HELLO\r\n", 7)); + QElapsedTimer stopwatch; + stopwatch.start(); + while (client->bytesAvailable() < 7 && stopwatch.elapsed() < 5000) + QTest::qWait(100); + char c; + QVERIFY(client->peek(&c,1) == 1); + QCOMPARE(c, 'H'); + QVERIFY(client->read(&c,1) == 1); + QCOMPARE(c, 'H'); + QByteArray b = client->peek(2); + QCOMPARE(b, QByteArray("EL")); + char a[3]; + QVERIFY(client->peek(a, 2) == 2); + QCOMPARE(a[0], 'E'); + QCOMPARE(a[1], 'L'); + QCOMPARE(client->readAll(), QByteArray("ELLO\r\n")); + + //check data split between QIODevice and plain socket buffers. + QByteArray bigblock; + bigblock.fill('#', QIODEVICE_BUFFERSIZE + 1024); + QVERIFY(client->write(QByteArray("head"))); + QVERIFY(client->write(bigblock)); + while (server->bytesAvailable() < bigblock.length() + 4 && stopwatch.elapsed() < 5000) + QTest::qWait(100); + QCOMPARE(server->read(4), QByteArray("head")); + QCOMPARE(server->peek(bigblock.length()), bigblock); + b.reserve(bigblock.length()); + b.resize(server->peek(b.data(), bigblock.length())); + QCOMPARE(b, bigblock); + + //check oversized peek + QCOMPARE(server->peek(bigblock.length() * 3), bigblock); + b.reserve(bigblock.length() * 3); + b.resize(server->peek(b.data(), bigblock.length() * 3)); + QCOMPARE(b, bigblock); + + QCOMPARE(server->readAll(), bigblock); + + QVERIFY(client->write("STARTTLS\r\n")); + stopwatch.start(); + // ### Qt5 use QTRY_VERIFY + while (server->bytesAvailable() < 10 && stopwatch.elapsed() < 5000) + QTest::qWait(100); + QVERIFY(server->peek(&c,1) == 1); + QCOMPARE(c, 'S'); + b = server->peek(3); + QCOMPARE(b, QByteArray("STA")); + QCOMPARE(server->read(5), QByteArray("START")); + QVERIFY(server->peek(a, 3) == 3); + QCOMPARE(a[0], 'T'); + QCOMPARE(a[1], 'L'); + QCOMPARE(a[2], 'S'); + QCOMPARE(server->readAll(), QByteArray("TLS\r\n")); + + QFile file(SRCDIR "certs/fluke.key"); + QVERIFY(file.open(QIODevice::ReadOnly)); + QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); + QVERIFY(!key.isNull()); + server->setPrivateKey(key); + + QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert"); + QVERIFY(!localCert.isEmpty()); + QVERIFY(localCert.first().handle()); + server->setLocalCertificate(localCert.first()); + + server->setProtocol(QSsl::AnyProtocol); + server->setPeerVerifyMode(QSslSocket::VerifyNone); + + server->ignoreSslErrors(); + client->ignoreSslErrors(); + + server->startServerEncryption(); + client->startClientEncryption(); + + QVERIFY(server->write("hello\r\n", 7)); + stopwatch.start(); + while (client->bytesAvailable() < 7 && stopwatch.elapsed() < 5000) + QTest::qWait(100); + QVERIFY(server->mode() == QSslSocket::SslServerMode && client->mode() == QSslSocket::SslClientMode); + QVERIFY(client->peek(&c,1) == 1); + QCOMPARE(c, 'h'); + QVERIFY(client->read(&c,1) == 1); + QCOMPARE(c, 'h'); + b = client->peek(2); + QCOMPARE(b, QByteArray("el")); + QCOMPARE(client->readAll(), QByteArray("ello\r\n")); + + QVERIFY(client->write("goodbye\r\n")); + stopwatch.start(); + while (server->bytesAvailable() < 9 && stopwatch.elapsed() < 5000) + QTest::qWait(100); + QVERIFY(server->peek(&c,1) == 1); + QCOMPARE(c, 'g'); + QCOMPARE(server->readAll(), QByteArray("goodbye\r\n")); + client->disconnectFromHost(); + QVERIFY(client->waitForDisconnected(5000)); +} + void tst_QSslSocket::setEmptyDefaultConfiguration() { // used to produce a crash in QSslConfigurationPrivate::deepCopyDefaultConfiguration, QTBUG-13265 |