diff options
author | Markus Goetz <Markus.Goetz@nokia.com> | 2009-10-14 09:59:44 (GMT) |
---|---|---|
committer | Markus Goetz <Markus.Goetz@nokia.com> | 2009-10-22 15:14:54 (GMT) |
commit | f182dcb82c4b0f4807a99bc8fb05bb6d07d8ddd3 (patch) | |
tree | dfc1376bc43c9239358a98018f1cf2780249d535 | |
parent | 760f221e7f1550ecc8198fb0c01c65ee13ded7f4 (diff) | |
download | Qt-f182dcb82c4b0f4807a99bc8fb05bb6d07d8ddd3.zip Qt-f182dcb82c4b0f4807a99bc8fb05bb6d07d8ddd3.tar.gz Qt-f182dcb82c4b0f4807a99bc8fb05bb6d07d8ddd3.tar.bz2 |
QHttp: Fix bug related to SSL and big POST data
QHttp is deprecated, but let's be nice and fix this.
POST/PUT now properly works over HTTPS without
buffering the whole data when it is not needed.
Reviewed-by: Peter Hartmann
-rw-r--r-- | src/network/access/qhttp.cpp | 28 | ||||
-rw-r--r-- | src/network/access/qhttp.h | 3 | ||||
-rw-r--r-- | tests/auto/qhttp/tst_qhttp.cpp | 43 |
3 files changed, 67 insertions, 7 deletions
diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp index 69faee3..f006fba 100644 --- a/src/network/access/qhttp.cpp +++ b/src/network/access/qhttp.cpp @@ -121,6 +121,9 @@ public: void _q_slotError(QAbstractSocket::SocketError); void _q_slotClosed(); void _q_slotBytesWritten(qint64 numBytes); +#ifndef QT_NO_OPENSSL + void _q_slotEncryptedBytesWritten(qint64 numBytes); +#endif void _q_slotDoFinished(); void _q_slotSendRequest(); void _q_continuePost(); @@ -135,6 +138,8 @@ public: void closeConn(); void setSock(QTcpSocket *sock); + void postMoreData(); + QTcpSocket *socket; int reconnectAttempts; bool deleteSocket; @@ -2659,19 +2664,40 @@ void QHttpPrivate::_q_slotError(QAbstractSocket::SocketError err) closeConn(); } +#ifndef QT_NO_OPENSSL +void QHttpPrivate::_q_slotEncryptedBytesWritten(qint64 written) +{ + Q_UNUSED(written); + postMoreData(); +} +#endif + void QHttpPrivate::_q_slotBytesWritten(qint64 written) { Q_Q(QHttp); bytesDone += written; emit q->dataSendProgress(bytesDone, bytesTotal); + postMoreData(); +} +// Send the POST data +void QHttpPrivate::postMoreData() +{ if (pendingPost) return; if (!postDevice) return; + // the following is backported code from Qt 4.6 QNetworkAccessManager. + // We also have to check the encryptedBytesToWrite() if it is an SSL socket. +#ifndef QT_NO_OPENSSL + QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket); + // if it is really an ssl socket, check more than just bytesToWrite() + if ((socket->bytesToWrite() + (sslSocket ? sslSocket->encryptedBytesToWrite() : 0)) == 0) { +#else if (socket->bytesToWrite() == 0) { +#endif int max = qMin<qint64>(4096, postDevice->size() - postDevice->pos()); QByteArray arr; arr.resize(max); @@ -3097,6 +3123,8 @@ void QHttpPrivate::setSock(QTcpSocket *sock) if (qobject_cast<QSslSocket *>(socket)) { QObject::connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), q, SIGNAL(sslErrors(const QList<QSslError> &))); + QObject::connect(socket, SIGNAL(encryptedBytesWritten(qint64)), + q, SLOT(_q_slotEncryptedBytesWritten(qint64))); } #endif } diff --git a/src/network/access/qhttp.h b/src/network/access/qhttp.h index e5061ca..f30def2 100644 --- a/src/network/access/qhttp.h +++ b/src/network/access/qhttp.h @@ -290,6 +290,9 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_slotError(QAbstractSocket::SocketError)) Q_PRIVATE_SLOT(d_func(), void _q_slotClosed()) Q_PRIVATE_SLOT(d_func(), void _q_slotBytesWritten(qint64 numBytes)) +#ifndef QT_NO_OPENSSL + Q_PRIVATE_SLOT(d_func(), void _q_slotEncryptedBytesWritten(qint64 numBytes)) +#endif Q_PRIVATE_SLOT(d_func(), void _q_slotDoFinished()) Q_PRIVATE_SLOT(d_func(), void _q_slotSendRequest()) Q_PRIVATE_SLOT(d_func(), void _q_continuePost()) diff --git a/tests/auto/qhttp/tst_qhttp.cpp b/tests/auto/qhttp/tst_qhttp.cpp index f6d5e3e..0ea0d15 100644 --- a/tests/auto/qhttp/tst_qhttp.cpp +++ b/tests/auto/qhttp/tst_qhttp.cpp @@ -484,6 +484,7 @@ void tst_QHttp::post_data() QTest::addColumn<bool>("useProxy"); QTest::addColumn<QString>("host"); QTest::addColumn<int>("port"); + QTest::addColumn<bool>("ssl"); QTest::addColumn<QString>("path"); QTest::addColumn<QByteArray>("result"); @@ -491,25 +492,48 @@ void tst_QHttp::post_data() md5sum = "d41d8cd98f00b204e9800998ecf8427e"; QTest::newRow("empty-data") << QString() << false << false - << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" << md5sum; + << QtNetworkSettings::serverName() << 80 << false << "/qtest/cgi-bin/md5sum.cgi" << md5sum; QTest::newRow("empty-device") << QString() << true << false - << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" << md5sum; + << QtNetworkSettings::serverName() << 80 << false << "/qtest/cgi-bin/md5sum.cgi" << md5sum; QTest::newRow("proxy-empty-data") << QString() << false << true - << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" << md5sum; + << QtNetworkSettings::serverName() << 80 << false << "/qtest/cgi-bin/md5sum.cgi" << md5sum; md5sum = "b3e32ac459b99d3f59318f3ac31e4bee"; QTest::newRow("data") << "rfc3252.txt" << false << false - << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" + << QtNetworkSettings::serverName() << 80 << false << "/qtest/cgi-bin/md5sum.cgi" << md5sum; QTest::newRow("device") << "rfc3252.txt" << true << false - << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" + << QtNetworkSettings::serverName() << 80 << false << "/qtest/cgi-bin/md5sum.cgi" << md5sum; QTest::newRow("proxy-data") << "rfc3252.txt" << false << true - << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" + << QtNetworkSettings::serverName() << 80 << false << "/qtest/cgi-bin/md5sum.cgi" << md5sum; +#ifndef QT_NO_OPENSSL + md5sum = "d41d8cd98f00b204e9800998ecf8427e"; + QTest::newRow("empty-data-ssl") + << QString() << false << false + << QtNetworkSettings::serverName() << 443 << true << "/qtest/cgi-bin/md5sum.cgi" << md5sum; + QTest::newRow("empty-device-ssl") + << QString() << true << false + << QtNetworkSettings::serverName() << 443 << true << "/qtest/cgi-bin/md5sum.cgi" << md5sum; + QTest::newRow("proxy-empty-data-ssl") + << QString() << false << true + << QtNetworkSettings::serverName() << 443 << true << "/qtest/cgi-bin/md5sum.cgi" << md5sum; + md5sum = "b3e32ac459b99d3f59318f3ac31e4bee"; + QTest::newRow("data-ssl") << "rfc3252.txt" << false << false + << QtNetworkSettings::serverName() << 443 << true << "/qtest/cgi-bin/md5sum.cgi" + << md5sum; + QTest::newRow("device-ssl") << "rfc3252.txt" << true << false + << QtNetworkSettings::serverName() << 443 << true << "/qtest/cgi-bin/md5sum.cgi" + << md5sum; + QTest::newRow("proxy-data-ssl") << "rfc3252.txt" << false << true + << QtNetworkSettings::serverName() << 443 << true << "/qtest/cgi-bin/md5sum.cgi" + << md5sum; +#endif + // the following test won't work. See task 185996 /* QTest::newRow("proxy-device") << "rfc3252.txt" << true << true @@ -525,14 +549,19 @@ void tst_QHttp::post() QFETCH(bool, useProxy); QFETCH(QString, host); QFETCH(int, port); + QFETCH(bool, ssl); QFETCH(QString, path); http = newHttp(useProxy); +#ifndef QT_NO_OPENSSL + QObject::connect(http, SIGNAL(sslErrors(const QList<QSslError> &)), + http, SLOT(ignoreSslErrors())); +#endif QCOMPARE(http->currentId(), 0); QCOMPARE((int)http->state(), (int)QHttp::Unconnected); if (useProxy) addRequest(QHttpRequestHeader(), http->setProxy(QtNetworkSettings::serverName(), 3129)); - addRequest(QHttpRequestHeader(), http->setHost(host, port)); + addRequest(QHttpRequestHeader(), http->setHost(host, (ssl ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp), port)); // add the POST request QFile file(SRCDIR + source); |