diff options
Diffstat (limited to 'tests/auto/network/access/qhttp/tst_qhttp.cpp')
-rw-r--r-- | tests/auto/network/access/qhttp/tst_qhttp.cpp | 1565 |
1 files changed, 0 insertions, 1565 deletions
diff --git a/tests/auto/network/access/qhttp/tst_qhttp.cpp b/tests/auto/network/access/qhttp/tst_qhttp.cpp deleted file mode 100644 index dd57aba85c..0000000000 --- a/tests/auto/network/access/qhttp/tst_qhttp.cpp +++ /dev/null @@ -1,1565 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include <QtTest/QtTest> - -#include <qbuffer.h> -#include <qcoreapplication.h> -#include <qfile.h> -#include <qhostinfo.h> -#include <qhttp.h> -#include <qlist.h> -#include <qpointer.h> -#include <qtcpsocket.h> -#include <qtcpserver.h> -#include <qauthenticator.h> -#include <QNetworkProxy> -#ifndef QT_NO_OPENSSL -# include <qsslsocket.h> -#endif - -#include "../../../network-settings.h" - -Q_DECLARE_METATYPE(QHttpResponseHeader) - -class tst_QHttp : public QObject -{ - Q_OBJECT - -public: - tst_QHttp(); - virtual ~tst_QHttp(); - - -public slots: - void initTestCase_data(); - void initTestCase(); - void cleanupTestCase(); - void init(); - void cleanup(); -private slots: - void constructing(); - void invalidRequests(); - void get_data(); - void get(); - void head_data(); - void head(); - void post_data(); - void post(); - void request_data(); - void request(); - void authorization_data(); - void authorization(); - void proxy_data(); - void proxy(); - void proxy2(); - void proxy3(); - void postAuthNtlm(); -#ifndef QT_NO_OPENSSL - void proxyAndSsl(); - void cachingProxyAndSsl(); -#endif - void reconnect(); - void setSocket(); - void unexpectedRemoteClose(); - void pctEncodedPath(); - void caseInsensitiveKeys(); - void emptyBodyInReply(); - void abortInReadyRead(); - void abortInResponseHeaderReceived(); - void nestedEventLoop(); - void connectionClose(); - -protected slots: - void stateChanged( int ); - void responseHeaderReceived( const QHttpResponseHeader & ); - void readyRead( const QHttpResponseHeader& ); - void dataSendProgress( int, int ); - void dataReadProgress( int , int ); - - void requestStarted( int ); - void requestFinished( int, bool ); - void done( bool ); - - void reconnect_state(int state); - void proxy2_slot(); - void nestedEventLoop_slot(int id); - - void abortSender(); - void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth); - -private: - QHttp *newHttp(bool withAuth = false); - void addRequest( QHttpRequestHeader, int ); - bool headerAreEqual( const QHttpHeader&, const QHttpHeader& ); - - QHttp *http; - - struct RequestResult - { - QHttpRequestHeader req; - QHttpResponseHeader resp; - int success; - }; - QMap< int, RequestResult > resultMap; - typedef QMap<int,RequestResult>::Iterator ResMapIt; - QList<int> ids; // helper to make sure that all expected signals are emitted - - int current_id; - int cur_state; - int done_success; - - QByteArray readyRead_ba; - - int bytesTotalSend; - int bytesDoneSend; - int bytesTotalRead; - int bytesDoneRead; - - int getId; - int headId; - int postId; - - int reconnect_state_connect_count; - - bool connectionWithAuth; - bool proxyAuthCalled; -}; - -class ClosingServer: public QTcpServer -{ - Q_OBJECT -public: - ClosingServer() - { - connect(this, SIGNAL(newConnection()), SLOT(handleConnection())); - listen(); - } - -public slots: - void handleConnection() - { - delete nextPendingConnection(); - } -}; - -//#define DUMP_SIGNALS - -const int bytesTotal_init = -10; -const int bytesDone_init = -10; - -tst_QHttp::tst_QHttp() -{ -} - -tst_QHttp::~tst_QHttp() -{ -} - -void tst_QHttp::initTestCase_data() -{ - QTest::addColumn<bool>("setProxy"); - QTest::addColumn<int>("proxyType"); - - QTest::newRow("WithoutProxy") << false << 0; - QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy); -} - -void tst_QHttp::initTestCase() -{ - QVERIFY(QtNetworkSettings::verifyTestNetworkSettings()); -} - -void tst_QHttp::cleanupTestCase() -{ -} - -void tst_QHttp::init() -{ - QFETCH_GLOBAL(bool, setProxy); - if (setProxy) { - QFETCH_GLOBAL(int, proxyType); - if (proxyType == QNetworkProxy::Socks5Proxy) { - QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080)); - } - } - - http = 0; - - resultMap.clear(); - ids.clear(); - - current_id = 0; - cur_state = QHttp::Unconnected; - done_success = -1; - - readyRead_ba = QByteArray(); - - getId = -1; - headId = -1; - postId = -1; -} - -void tst_QHttp::cleanup() -{ - delete http; - http = 0; - - QCoreApplication::processEvents(); - - QFETCH_GLOBAL(bool, setProxy); - if (setProxy) { - QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy); - } -} - -void tst_QHttp::constructing() -{ - //QHeader - { - QHttpRequestHeader header; - header.addValue("key1", "val1"); - header.addValue("key2", "val2"); - header.addValue("key1", "val3"); - QCOMPARE(header.values().size(), 3); - QCOMPARE(header.allValues("key1").size(), 2); - QVERIFY(header.hasKey("key2")); - QCOMPARE(header.keys().count(), 2); - - } - - { - QHttpResponseHeader header(200); - } -} - -void tst_QHttp::invalidRequests() -{ - QHttp http; - http.setHost("localhost"); // we will not actually connect - - QTest::ignoreMessage(QtWarningMsg, "QHttp: empty path requested is invalid -- using '/'"); - http.get(QString()); - - QTest::ignoreMessage(QtWarningMsg, "QHttp: empty path requested is invalid -- using '/'"); - http.head(QString()); - - QTest::ignoreMessage(QtWarningMsg, "QHttp: empty path requested is invalid -- using '/'"); - http.post(QString(), QByteArray()); - - QTest::ignoreMessage(QtWarningMsg, "QHttp: empty path requested is invalid -- using '/'"); - http.request(QHttpRequestHeader("PROPFIND", QString())); -} - -void tst_QHttp::get_data() -{ - QTest::addColumn<QString>("host"); - QTest::addColumn<uint>("port"); - QTest::addColumn<QString>("path"); - QTest::addColumn<int>("success"); - QTest::addColumn<int>("statusCode"); - QTest::addColumn<QByteArray>("res"); - QTest::addColumn<bool>("useIODevice"); - - // ### move this into external testdata - QFile file( SRCDIR "rfc3252.txt" ); - QVERIFY( file.open( QIODevice::ReadOnly ) ); - QByteArray rfc3252 = file.readAll(); - file.close(); - - file.setFileName( SRCDIR "testhtml" ); - QVERIFY( file.open( QIODevice::ReadOnly ) ); - QByteArray testhtml = file.readAll(); - file.close(); - - // test the two get() modes in one routine - for ( int i=0; i<2; i++ ) { - QTest::newRow(QString("path_01_%1").arg(i).toLatin1()) << QtNetworkSettings::serverName() << 80u - << QString("/qtest/rfc3252.txt") << 1 << 200 << rfc3252 << (bool)(i==1); - QTest::newRow( QString("path_02_%1").arg(i).toLatin1() ) << QString("www.ietf.org") << 80u - << QString("/rfc/rfc3252.txt") << 1 << 200 << rfc3252 << (bool)(i==1); - - QTest::newRow( QString("uri_01_%1").arg(i).toLatin1() ) << QtNetworkSettings::serverName() << 80u - << QString("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") << 1 << 200 << rfc3252 << (bool)(i==1); - QTest::newRow( QString("uri_02_%1").arg(i).toLatin1() ) << "www.ietf.org" << 80u - << QString("http://www.ietf.org/rfc/rfc3252.txt") << 1 << 200 << rfc3252 << (bool)(i==1); - - QTest::newRow( QString("fail_01_%1").arg(i).toLatin1() ) << QString("this-host-will-not-exist.") << 80u - << QString("/qtest/rfc3252.txt") << 0 << 0 << QByteArray() << (bool)(i==1); - - QTest::newRow( QString("failprot_01_%1").arg(i).toLatin1() ) << QtNetworkSettings::serverName() << 80u - << QString("/t") << 1 << 404 << QByteArray() << (bool)(i==1); - QTest::newRow( QString("failprot_02_%1").arg(i).toLatin1() ) << QtNetworkSettings::serverName() << 80u - << QString("qtest/rfc3252.txt") << 1 << 400 << QByteArray() << (bool)(i==1); - - // qt.nokia.com/doc uses transfer-encoding=chunked - /* qt.nokia.com/doc no longer seams to be using chuncked encodig. - QTest::newRow( QString("chunked_01_%1").arg(i).toLatin1() ) << QString("test.troll.no") << 80u - << QString("/") << 1 << 200 << testhtml << (bool)(i==1); - */ - QTest::newRow( QString("chunked_02_%1").arg(i).toLatin1() ) << QtNetworkSettings::serverName() << 80u - << QString("/qtest/cgi-bin/rfc.cgi") << 1 << 200 << rfc3252 << (bool)(i==1); - } -} - -void tst_QHttp::get() -{ - // for the overload that takes a QIODevice - QByteArray buf_ba; - QBuffer buf( &buf_ba ); - - QFETCH( QString, host ); - QFETCH( uint, port ); - QFETCH( QString, path ); - QFETCH( bool, useIODevice ); - - http = newHttp(); - QCOMPARE( http->currentId(), 0 ); - QCOMPARE( (int)http->state(), (int)QHttp::Unconnected ); - - addRequest( QHttpRequestHeader(), http->setHost( host, port ) ); - if ( useIODevice ) { - buf.open( QIODevice::WriteOnly ); - getId = http->get( path, &buf ); - } else { - getId = http->get( path ); - } - addRequest( QHttpRequestHeader(), getId ); - - QTestEventLoop::instance().enterLoop( 50 ); - - if ( QTestEventLoop::instance().timeout() ) - QFAIL( "Network operation timed out" ); - - ResMapIt res = resultMap.find( getId ); - QVERIFY( res != resultMap.end() ); - if ( res.value().success!=1 && host=="www.ietf.org" ) { - // The nightly tests fail from time to time. In order to make them more - // stable, add some debug output that might help locate the problem (I - // can't reproduce the problem in the non-nightly builds). - qDebug( "Error %d: %s", http->error(), http->errorString().toLatin1().constData() ); - } - QTEST( res.value().success, "success" ); - if ( res.value().success ) { - QTEST( res.value().resp.statusCode(), "statusCode" ); - - QFETCH( QByteArray, res ); - if ( res.count() > 0 ) { - if ( useIODevice ) { - QCOMPARE(buf_ba, res); - if ( bytesDoneRead != bytesDone_init ) - QVERIFY( (int)buf_ba.size() == bytesDoneRead ); - } else { - QCOMPARE(readyRead_ba, res); - if ( bytesDoneRead != bytesDone_init ) - QVERIFY( (int)readyRead_ba.size() == bytesDoneRead ); - } - } - QVERIFY( bytesTotalRead != bytesTotal_init ); - if ( bytesTotalRead > 0 ) - QVERIFY( bytesDoneRead == bytesTotalRead ); - } else { - QVERIFY( !res.value().resp.isValid() ); - } -} - -void tst_QHttp::head_data() -{ - QTest::addColumn<QString>("host"); - QTest::addColumn<uint>("port"); - QTest::addColumn<QString>("path"); - QTest::addColumn<int>("success"); - QTest::addColumn<int>("statusCode"); - QTest::addColumn<uint>("contentLength"); - - QTest::newRow( "path_01" ) << QtNetworkSettings::serverName() << 80u - << QString("/qtest/rfc3252.txt") << 1 << 200 << 25962u; - - QTest::newRow( "path_02" ) << QString("www.ietf.org") << 80u - << QString("/rfc/rfc3252.txt") << 1 << 200 << 25962u; - - QTest::newRow( "uri_01" ) << QtNetworkSettings::serverName() << 80u - << QString("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") << 1 << 200 << 25962u; - - QTest::newRow( "uri_02" ) << QString("www.ietf.org") << 80u - << QString("http://www.ietf.org/rfc/rfc3252.txt") << 1 << 200 << 25962u; - - QTest::newRow( "fail_01" ) << QString("this-host-will-not-exist.") << 80u - << QString("/qtest/rfc3252.txt") << 0 << 0 << 0u; - - QTest::newRow( "failprot_01" ) << QtNetworkSettings::serverName() << 80u - << QString("/t") << 1 << 404 << 0u; - - QTest::newRow( "failprot_02" ) << QtNetworkSettings::serverName() << 80u - << QString("qtest/rfc3252.txt") << 1 << 400 << 0u; - - /* qt.nokia.com/doc no longer seams to be using chuncked encodig. - QTest::newRow( "chunked_01" ) << QString("qt.nokia.com/doc") << 80u - << QString("/index.html") << 1 << 200 << 0u; - */ - QTest::newRow( "chunked_02" ) << QtNetworkSettings::serverName() << 80u - << QString("/qtest/cgi-bin/rfc.cgi") << 1 << 200 << 0u; -} - -void tst_QHttp::head() -{ - QFETCH( QString, host ); - QFETCH( uint, port ); - QFETCH( QString, path ); - - http = newHttp(); - QCOMPARE( http->currentId(), 0 ); - QCOMPARE( (int)http->state(), (int)QHttp::Unconnected ); - - addRequest( QHttpRequestHeader(), http->setHost( host, port ) ); - headId = http->head( path ); - addRequest( QHttpRequestHeader(), headId ); - - QTestEventLoop::instance().enterLoop( 30 ); - if ( QTestEventLoop::instance().timeout() ) - QFAIL( "Network operation timed out" ); - - ResMapIt res = resultMap.find( headId ); - QVERIFY( res != resultMap.end() ); - if ( res.value().success!=1 && host=="www.ietf.org" ) { - // The nightly tests fail from time to time. In order to make them more - // stable, add some debug output that might help locate the problem (I - // can't reproduce the problem in the non-nightly builds). - qDebug( "Error %d: %s", http->error(), http->errorString().toLatin1().constData() ); - } - QTEST( res.value().success, "success" ); - if ( res.value().success ) { - QTEST( res.value().resp.statusCode(), "statusCode" ); - QTEST( res.value().resp.contentLength(), "contentLength" ); - - QCOMPARE( (uint)readyRead_ba.size(), 0u ); - QVERIFY( bytesTotalRead == bytesTotal_init ); - QVERIFY( bytesDoneRead == bytesDone_init ); - } else { - QVERIFY( !res.value().resp.isValid() ); - } -} - -void tst_QHttp::post_data() -{ - QTest::addColumn<QString>("source"); - QTest::addColumn<bool>("useIODevice"); - QTest::addColumn<bool>("useProxy"); - QTest::addColumn<QString>("host"); - QTest::addColumn<int>("port"); - QTest::addColumn<bool>("ssl"); - QTest::addColumn<QString>("path"); - QTest::addColumn<QByteArray>("result"); - - QByteArray md5sum; - md5sum = "d41d8cd98f00b204e9800998ecf8427e"; - QTest::newRow("empty-data") - << QString() << false << false - << QtNetworkSettings::serverName() << 80 << false << "/qtest/cgi-bin/md5sum.cgi" << md5sum; - QTest::newRow("empty-device") - << QString() << true << false - << QtNetworkSettings::serverName() << 80 << false << "/qtest/cgi-bin/md5sum.cgi" << md5sum; - QTest::newRow("proxy-empty-data") - << QString() << false << true - << QtNetworkSettings::serverName() << 80 << false << "/qtest/cgi-bin/md5sum.cgi" << md5sum; - - md5sum = "b3e32ac459b99d3f59318f3ac31e4bee"; - QTest::newRow("data") << "rfc3252.txt" << false << false - << QtNetworkSettings::serverName() << 80 << false << "/qtest/cgi-bin/md5sum.cgi" - << md5sum; - QTest::newRow("device") << "rfc3252.txt" << true << false - << QtNetworkSettings::serverName() << 80 << false << "/qtest/cgi-bin/md5sum.cgi" - << md5sum; - QTest::newRow("proxy-data") << "rfc3252.txt" << false << true - << 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 - << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" - << md5sum; -*/ -} - -void tst_QHttp::post() -{ - QFETCH(QString, source); - QFETCH(bool, useIODevice); - 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, (ssl ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp), port)); - - // add the POST request - QFile file(SRCDIR + source); - QBuffer emptyBuffer; - QIODevice *dev; - if (!source.isEmpty()) { - QVERIFY(file.open(QIODevice::ReadOnly)); - dev = &file; - } else { - emptyBuffer.open(QIODevice::ReadOnly); - dev = &emptyBuffer; - } - - if (useIODevice) - postId = http->post(path, dev); - else - postId = http->post(path, dev->readAll()); - addRequest(QHttpRequestHeader(), postId); - - // run request - connect(http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), - SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - QTestEventLoop::instance().enterLoop( 30 ); - - if ( QTestEventLoop::instance().timeout() ) - QFAIL( "Network operation timed out" ); - - ResMapIt res = resultMap.find(postId); - QVERIFY(res != resultMap.end()); - QVERIFY(res.value().success); - QCOMPARE(res.value().resp.statusCode(), 200); - QTEST(readyRead_ba.trimmed(), "result"); -} - -void tst_QHttp::request_data() -{ - QTest::addColumn<QString>("source"); - QTest::addColumn<bool>("useIODevice"); - QTest::addColumn<bool>("useProxy"); - QTest::addColumn<QString>("host"); - QTest::addColumn<int>("port"); - QTest::addColumn<QString>("method"); - QTest::addColumn<QString>("path"); - QTest::addColumn<QByteArray>("result"); - - QFile source(SRCDIR "rfc3252.txt"); - if (!source.open(QIODevice::ReadOnly)) - return; - - QByteArray contents = source.readAll(); - QByteArray md5sum = QCryptographicHash::hash(contents, QCryptographicHash::Md5).toHex() + '\n'; - QByteArray emptyMd5sum = "d41d8cd98f00b204e9800998ecf8427e\n"; - - QTest::newRow("head") << QString() << false << false << QtNetworkSettings::serverName() << 80 - << "HEAD" << "/qtest/rfc3252.txt" - << QByteArray(); - QTest::newRow("get") << QString() << false << false << QtNetworkSettings::serverName() << 80 - << "GET" << "/qtest/rfc3252.txt" - << contents; - QTest::newRow("post-empty-data") << QString() << false << false - << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" - << emptyMd5sum; - QTest::newRow("post-empty-device") << QString() << true << false - << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" - << emptyMd5sum; - QTest::newRow("post-data") << "rfc3252.txt" << false << false - << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" - << md5sum; - QTest::newRow("post-device") << "rfc3252.txt" << true << false - << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" - << md5sum; - - QTest::newRow("proxy-head") << QString() << false << true << QtNetworkSettings::serverName() << 80 - << "HEAD" << "/qtest/rfc3252.txt" - << QByteArray(); - QTest::newRow("proxy-get") << QString() << false << true << QtNetworkSettings::serverName() << 80 - << "GET" << "/qtest/rfc3252.txt" - << contents; - QTest::newRow("proxy-post-empty-data") << QString() << false << true - << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" - << emptyMd5sum; - QTest::newRow("proxy-post-data") << "rfc3252.txt" << false << true - << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" - << md5sum; - // the following test won't work. See task 185996 -/* - QTest::newRow("proxy-post-device") << "rfc3252.txt" << true << true - << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" - << md5sum; -*/ -} - -void tst_QHttp::request() -{ - QFETCH(QString, source); - QFETCH(bool, useIODevice); - QFETCH(bool, useProxy); - QFETCH(QString, host); - QFETCH(int, port); - QFETCH(QString, method); - QFETCH(QString, path); - - http = newHttp(useProxy); - 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)); - - QFile file(SRCDIR + source); - QBuffer emptyBuffer; - QIODevice *dev; - if (!source.isEmpty()) { - QVERIFY(file.open(QIODevice::ReadOnly)); - dev = &file; - } else { - emptyBuffer.open(QIODevice::ReadOnly); - dev = &emptyBuffer; - } - - // prepare the request - QHttpRequestHeader request; - request.setRequest(method, path, 1,1); - request.addValue("Host", host); - int *theId; - - if (method == "POST") - theId = &postId; - else if (method == "GET") - theId = &getId; - else if (method == "HEAD") - theId = &headId; - else - QFAIL("You're lazy! Please implement your test!"); - - // now send the request - if (useIODevice) - *theId = http->request(request, dev); - else - *theId = http->request(request, dev->readAll()); - addRequest(QHttpRequestHeader(), *theId); - - // run request - connect(http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), - SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - QTestEventLoop::instance().enterLoop( 30 ); - - if ( QTestEventLoop::instance().timeout() ) - QFAIL( "Network operation timed out" ); - - ResMapIt res = resultMap.find(*theId); - QVERIFY(res != resultMap.end()); - QVERIFY(res.value().success); - QCOMPARE(res.value().resp.statusCode(), 200); - QTEST(readyRead_ba, "result"); -} - -void tst_QHttp::authorization_data() -{ - QTest::addColumn<QString>("host"); - QTest::addColumn<QString>("path"); - QTest::addColumn<QString>("user"); - QTest::addColumn<QString>("pass"); - QTest::addColumn<int>("result"); - - QTest::newRow("correct password") << QtNetworkSettings::serverName() - << QString::fromLatin1("/qtest/rfcs-auth/index.html") - << QString::fromLatin1("httptest") - << QString::fromLatin1("httptest") - << 200; - - QTest::newRow("no password") << QtNetworkSettings::serverName() - << QString::fromLatin1("/qtest/rfcs-auth/index.html") - << QString::fromLatin1("") - << QString::fromLatin1("") - << 401; - - QTest::newRow("wrong password") << QtNetworkSettings::serverName() - << QString::fromLatin1("/qtest/rfcs-auth/index.html") - << QString::fromLatin1("maliciu0s") - << QString::fromLatin1("h4X0r") - << 401; -} - -void tst_QHttp::authorization() -{ - QFETCH(QString, host); - QFETCH(QString, path); - QFETCH(QString, user); - QFETCH(QString, pass); - QFETCH(int, result); - - QEventLoop loop; - - QHttp http; - connect(&http, SIGNAL(done(bool)), &loop, SLOT(quit())); - - if (!user.isEmpty()) - http.setUser(user, pass); - http.setHost(host); - int id = http.get(path); - Q_UNUSED(id); - - QTimer::singleShot(5000, &loop, SLOT(quit())); - loop.exec(); - - QCOMPARE(http.lastResponse().statusCode(), result); -} - -void tst_QHttp::proxy_data() -{ - QTest::addColumn<QString>("proxyhost"); - QTest::addColumn<int>("port"); - QTest::addColumn<QString>("host"); - QTest::addColumn<QString>("path"); - QTest::addColumn<QString>("proxyuser"); - QTest::addColumn<QString>("proxypass"); - - QTest::newRow("qt-test-server") << QtNetworkSettings::serverName() << 3128 - << QString::fromLatin1("qt.nokia.com") << QString::fromLatin1("/") - << QString::fromLatin1("") << QString::fromLatin1(""); - QTest::newRow("qt-test-server pct") << QtNetworkSettings::serverName() << 3128 - << QString::fromLatin1("qt.nokia.com") << QString::fromLatin1("/%64eveloper") - << QString::fromLatin1("") << QString::fromLatin1(""); - QTest::newRow("qt-test-server-basic") << QtNetworkSettings::serverName() << 3129 - << QString::fromLatin1("qt.nokia.com") << QString::fromLatin1("/") - << QString::fromLatin1("qsockstest") << QString::fromLatin1("password"); - -#if 0 - // NTLM requires sending the same request three times for it to work - // the tst_QHttp class is too strict to handle the byte counts sent by dataSendProgress - // So don't run this test: - QTest::newRow("qt-test-server-ntlm") << QtNetworkSettings::serverName() << 3130 - << QString::fromLatin1("qt.nokia.com") << QString::fromLatin1("/") - << QString::fromLatin1("qsockstest") << QString::fromLatin1("password"); -#endif -} - -void tst_QHttp::proxy() -{ - QFETCH(QString, proxyhost); - QFETCH(int, port); - QFETCH(QString, host); - QFETCH(QString, path); - QFETCH(QString, proxyuser); - QFETCH(QString, proxypass); - - http = newHttp(!proxyuser.isEmpty()); - - QCOMPARE(http->currentId(), 0); - QCOMPARE((int)http->state(), (int)QHttp::Unconnected); - - addRequest(QHttpRequestHeader(), http->setProxy(proxyhost, port, proxyuser, proxypass)); - addRequest(QHttpRequestHeader(), http->setHost(host)); - getId = http->get(path); - addRequest(QHttpRequestHeader(), getId); - - QTestEventLoop::instance().enterLoop(30); - if (QTestEventLoop::instance().timeout()) - QFAIL("Network operation timed out"); - - ResMapIt res = resultMap.find(getId); - QVERIFY(res != resultMap.end()); - QVERIFY(res.value().success); - QCOMPARE(res.value().resp.statusCode(), 200); -} - -void tst_QHttp::proxy2() -{ - QFETCH_GLOBAL(bool, setProxy); - if (setProxy) - return; - - readyRead_ba.clear(); - - QHttp http; - http.setProxy(QtNetworkSettings::serverName(), 3128); - http.setHost(QtNetworkSettings::serverName()); - http.get("/index.html"); - http.get("/index.html"); - - connect(&http, SIGNAL(requestFinished(int, bool)), - this, SLOT(proxy2_slot())); - QTestEventLoop::instance().enterLoop(30); - QVERIFY(!QTestEventLoop::instance().timeout()); - - QCOMPARE(readyRead_ba.count("Welcome to qt-test-server"), 2); - - readyRead_ba.clear(); -} - -void tst_QHttp::proxy2_slot() -{ - QHttp *http = static_cast<QHttp *>(sender()); - readyRead_ba.append(http->readAll()); - if (!http->hasPendingRequests()) - QTestEventLoop::instance().exitLoop(); -} - -void tst_QHttp::proxy3() -{ - QFETCH_GLOBAL(bool, setProxy); - if (setProxy) - return; - - readyRead_ba.clear(); - - QTcpSocket socket; - socket.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128)); - - QHttp http; - http.setSocket(&socket); - http.setHost(QtNetworkSettings::serverName()); - http.get("/index.html"); - http.get("/index.html"); - - connect(&http, SIGNAL(requestFinished(int, bool)), - this, SLOT(proxy2_slot())); - QTestEventLoop::instance().enterLoop(30); - QVERIFY(!QTestEventLoop::instance().timeout()); - - QCOMPARE(readyRead_ba.count("Welcome to qt-test-server"), 2); - - readyRead_ba.clear(); -} - -// test QHttp::currentId() and QHttp::currentRequest() -#define CURRENTREQUEST_TEST \ - { \ - ResMapIt res = resultMap.find( http->currentId() ); \ - QVERIFY( res != resultMap.end() ); \ - if ( http->currentId() == getId ) { \ - QCOMPARE( http->currentRequest().method(), QString("GET") ); \ - } else if ( http->currentId() == headId ) { \ - QCOMPARE( http->currentRequest().method(), QString("HEAD") ); \ - } else if ( http->currentId() == postId ) { \ - QCOMPARE( http->currentRequest().method(), QString("POST") ); \ - } else { \ - QVERIFY( headerAreEqual( http->currentRequest(), res.value().req ) ); \ - } \ - } - -void tst_QHttp::requestStarted( int id ) -{ -#if defined( DUMP_SIGNALS ) - qDebug( "%d:requestStarted( %d )", http->currentId(), id ); -#endif - // make sure that the requestStarted and requestFinished are nested correctly - QVERIFY( current_id == 0 ); - current_id = id; - - QVERIFY( !ids.isEmpty() ); - QVERIFY( ids.first() == id ); - if ( ids.count() > 1 ) { - QVERIFY( http->hasPendingRequests() ); - } else { - QVERIFY( !http->hasPendingRequests() ); - } - - QVERIFY( http->currentId() == id ); - QVERIFY( cur_state == http->state() ); - - - - - CURRENTREQUEST_TEST; - - QVERIFY( http->error() == QHttp::NoError ); -} - -void tst_QHttp::requestFinished( int id, bool error ) -{ -#if defined( DUMP_SIGNALS ) - qDebug( "%d:requestFinished( %d, %d ) -- errorString: '%s'", - http->currentId(), id, (int)error, http->errorString().toAscii().data() ); -#endif - // make sure that the requestStarted and requestFinished are nested correctly - QVERIFY( current_id == id ); - current_id = 0; - - QVERIFY( !ids.isEmpty() ); - QVERIFY( ids.first() == id ); - if ( ids.count() > 1 ) { - QVERIFY( http->hasPendingRequests() ); - } else { - QVERIFY( !http->hasPendingRequests() ); - } - - if ( error ) { - QVERIFY( http->error() != QHttp::NoError ); - ids.clear(); - } else { - QVERIFY( http->error() == QHttp::NoError ); - ids.pop_front(); - } - - QVERIFY( http->currentId() == id ); - QVERIFY( cur_state == http->state() ); - CURRENTREQUEST_TEST; - - ResMapIt res = resultMap.find( http->currentId() ); - QVERIFY( res != resultMap.end() ); - QVERIFY( res.value().success == -1 ); - if ( error ) - res.value().success = 0; - else - res.value().success = 1; -} - -void tst_QHttp::done( bool error ) -{ -#if defined( DUMP_SIGNALS ) - qDebug( "%d:done( %d )", http->currentId(), (int)error ); -#endif - QVERIFY( http->currentId() == 0 ); - QVERIFY( current_id == 0 ); - QVERIFY( ids.isEmpty() ); - QVERIFY( cur_state == http->state() ); - QVERIFY( !http->hasPendingRequests() ); - - QVERIFY( done_success == -1 ); - if ( error ) { - QVERIFY( http->error() != QHttp::NoError ); - done_success = 0; - } else { - QVERIFY( http->error() == QHttp::NoError ); - done_success = 1; - } - QTestEventLoop::instance().exitLoop(); -} - -void tst_QHttp::stateChanged( int state ) -{ -#if defined( DUMP_SIGNALS ) - qDebug( "%d: stateChanged( %d )", http->currentId(), state ); -#endif - QCOMPARE( http->currentId(), current_id ); - if ( ids.count() > 0 ) - CURRENTREQUEST_TEST; - - QVERIFY( state != cur_state ); - QVERIFY( state == http->state() ); - if ( state != QHttp::Unconnected && !connectionWithAuth ) { - // make sure that the states are always emitted in the right order (for - // this, we assume an ordering on the enum values, which they have at - // the moment) - // connections with authentication will possibly reconnect, so ignore them - QVERIFY( cur_state < state ); - } - cur_state = state; - - if (state == QHttp::Connecting) { - bytesTotalSend = bytesTotal_init; - bytesDoneSend = bytesDone_init; - bytesTotalRead = bytesTotal_init; - bytesDoneRead = bytesDone_init; - } -} - -void tst_QHttp::responseHeaderReceived( const QHttpResponseHeader &header ) -{ -#if defined( DUMP_SIGNALS ) - qDebug( "%d: responseHeaderReceived(\n---{\n%s}---)", http->currentId(), header.toString().toAscii().data() ); -#endif - QCOMPARE( http->currentId(), current_id ); - if ( ids.count() > 1 ) { - QVERIFY( http->hasPendingRequests() ); - } else { - QVERIFY( !http->hasPendingRequests() ); - } - CURRENTREQUEST_TEST; - - resultMap[ http->currentId() ].resp = header; -} - -void tst_QHttp::readyRead( const QHttpResponseHeader & ) -{ -#if defined( DUMP_SIGNALS ) - qDebug( "%d: readyRead()", http->currentId() ); -#endif - QCOMPARE( http->currentId(), current_id ); - if ( ids.count() > 1 ) { - QVERIFY( http->hasPendingRequests() ); - } else { - QVERIFY( !http->hasPendingRequests() ); - } - QVERIFY( cur_state == http->state() ); - CURRENTREQUEST_TEST; - - if ( QTest::currentTestFunction() != QLatin1String("bytesAvailable") ) { - int oldSize = readyRead_ba.size(); - quint64 bytesAvail = http->bytesAvailable(); - QByteArray ba = http->readAll(); - QVERIFY( (quint64) ba.size() == bytesAvail ); - readyRead_ba.resize( oldSize + ba.size() ); - memcpy( readyRead_ba.data()+oldSize, ba.data(), ba.size() ); - - if ( bytesTotalRead > 0 ) { - QVERIFY( (int)readyRead_ba.size() <= bytesTotalRead ); - } - QVERIFY( (int)readyRead_ba.size() == bytesDoneRead ); - } -} - -void tst_QHttp::dataSendProgress( int done, int total ) -{ -#if defined( DUMP_SIGNALS ) - qDebug( "%d: dataSendProgress( %d, %d )", http->currentId(), done, total ); -#endif - QCOMPARE( http->currentId(), current_id ); - if ( ids.count() > 1 ) { - QVERIFY( http->hasPendingRequests() ); - } else { - QVERIFY( !http->hasPendingRequests() ); - } - QVERIFY( cur_state == http->state() ); - CURRENTREQUEST_TEST; - - if ( bytesTotalSend == bytesTotal_init ) { - bytesTotalSend = total; - } else { - QCOMPARE( bytesTotalSend, total ); - } - - QVERIFY( bytesTotalSend != bytesTotal_init ); - QVERIFY( bytesDoneSend <= done ); - bytesDoneSend = done; - if ( bytesTotalSend > 0 ) { - QVERIFY( bytesDoneSend <= bytesTotalSend ); - } - - if ( QTest::currentTestFunction() == QLatin1String("abort") ) { - // ### it would be nice if we could specify in our testdata when to do - // the abort - if ( done >= total/100000 ) { - if ( ids.count() != 1 ) { - // do abort only once - int tmpId = ids.first(); - ids.clear(); - ids << tmpId; - http->abort(); - } - } - } -} - -void tst_QHttp::dataReadProgress( int done, int total ) -{ -#if defined( DUMP_SIGNALS ) - qDebug( "%d: dataReadProgress( %d, %d )", http->currentId(), done, total ); -#endif - QCOMPARE( http->currentId(), current_id ); - if ( ids.count() > 1 ) { - QVERIFY( http->hasPendingRequests() ); - } else { - QVERIFY( !http->hasPendingRequests() ); - } - QVERIFY( cur_state == http->state() ); - CURRENTREQUEST_TEST; - - if ( bytesTotalRead == bytesTotal_init ) - bytesTotalRead = total; - else { - QVERIFY( bytesTotalRead == total ); - } - - QVERIFY( bytesTotalRead != bytesTotal_init ); - QVERIFY( bytesDoneRead <= done ); - bytesDoneRead = done; - if ( bytesTotalRead > 0 ) { - QVERIFY( bytesDoneRead <= bytesTotalRead ); - } - - if ( QTest::currentTestFunction() == QLatin1String("abort") ) { - // ### it would be nice if we could specify in our testdata when to do - // the abort - if ( done >= total/100000 ) { - if ( ids.count() != 1 ) { - // do abort only once - int tmpId = ids.first(); - ids.clear(); - ids << tmpId; - http->abort(); - } - } - } -} - - -QHttp *tst_QHttp::newHttp(bool withAuth) -{ - QHttp *nHttp = new QHttp( 0 ); - connect( nHttp, SIGNAL(requestStarted(int)), - SLOT(requestStarted(int)) ); - connect( nHttp, SIGNAL(requestFinished(int,bool)), - SLOT(requestFinished(int,bool)) ); - connect( nHttp, SIGNAL(done(bool)), - SLOT(done(bool)) ); - connect( nHttp, SIGNAL(stateChanged(int)), - SLOT(stateChanged(int)) ); - connect( nHttp, SIGNAL(responseHeaderReceived(const QHttpResponseHeader&)), - SLOT(responseHeaderReceived(const QHttpResponseHeader&)) ); - connect( nHttp, SIGNAL(readyRead(const QHttpResponseHeader&)), - SLOT(readyRead(const QHttpResponseHeader&)) ); - connect( nHttp, SIGNAL(dataSendProgress(int,int)), - SLOT(dataSendProgress(int,int)) ); - connect( nHttp, SIGNAL(dataReadProgress(int,int)), - SLOT(dataReadProgress(int,int)) ); - - connectionWithAuth = withAuth; - return nHttp; -} - -void tst_QHttp::addRequest( QHttpRequestHeader header, int id ) -{ - ids << id; - RequestResult res; - res.req = header; - res.success = -1; - resultMap[ id ] = res; -} - -bool tst_QHttp::headerAreEqual( const QHttpHeader &h1, const QHttpHeader &h2 ) -{ - if ( !h1.isValid() ) - return !h2.isValid(); - if ( !h2.isValid() ) - return !h1.isValid(); - - return h1.toString() == h2.toString(); -} - - -void tst_QHttp::reconnect() -{ - reconnect_state_connect_count = 0; - - QHttp http; - - QObject::connect(&http, SIGNAL(stateChanged(int)), this, SLOT(reconnect_state(int))); - http.setHost("trolltech.com", 80); - http.get("/company/index.html"); - http.setHost("trolltech.com", 8080); - http.get("/company/index.html"); - - QTestEventLoop::instance().enterLoop(60); - if (QTestEventLoop::instance().timeout()) - QFAIL("Network operation timed out"); - - QCOMPARE(reconnect_state_connect_count, 1); - - QTestEventLoop::instance().enterLoop(60); - if (QTestEventLoop::instance().timeout()) - QFAIL("Network operation timed out"); - - QCOMPARE(reconnect_state_connect_count, 2); -} - -void tst_QHttp::reconnect_state(int state) -{ - if (state == QHttp::Connecting) { - ++reconnect_state_connect_count; - QTestEventLoop::instance().exitLoop(); - } -} - -void tst_QHttp::setSocket() -{ - QHttp *http = new QHttp; - QPointer<QTcpSocket> replacementSocket = new QTcpSocket; - http->setSocket(replacementSocket); - QCoreApplication::processEvents(); - delete http; - QVERIFY(replacementSocket); - delete replacementSocket; -} - -class Server : public QTcpServer -{ - Q_OBJECT -public: - Server() - { - connect(this, SIGNAL(newConnection()), - this, SLOT(serveConnection())); - } - -private slots: - void serveConnection() - { - QTcpSocket *socket = nextPendingConnection(); - socket->write("HTTP/1.1 404 Not found\r\n" - "content-length: 4\r\n\r\nabcd"); - socket->disconnectFromHost(); - }; -}; - -void tst_QHttp::unexpectedRemoteClose() -{ - QFETCH_GLOBAL(int, proxyType); - if (proxyType == QNetworkProxy::Socks5Proxy) { - // This test doesn't make sense for SOCKS5 - return; - } - - Server server; - server.listen(); - QCoreApplication::instance()->processEvents(); - - QEventLoop loop; - QTimer::singleShot(3000, &loop, SLOT(quit())); - - QHttp http; - QObject::connect(&http, SIGNAL(done(bool)), &loop, SLOT(quit())); - QSignalSpy finishedSpy(&http, SIGNAL(requestFinished(int, bool))); - QSignalSpy doneSpy(&http, SIGNAL(done(bool))); - - http.setHost("localhost", server.serverPort()); - http.get("/"); - http.get("/"); - http.get("/"); - - loop.exec(); - - QCOMPARE(finishedSpy.count(), 4); - QVERIFY(!finishedSpy.at(1).at(1).toBool()); - QVERIFY(!finishedSpy.at(2).at(1).toBool()); - QVERIFY(!finishedSpy.at(3).at(1).toBool()); - QCOMPARE(doneSpy.count(), 1); - QVERIFY(!doneSpy.at(0).at(0).toBool()); -} - -void tst_QHttp::pctEncodedPath() -{ - QHttpRequestHeader header; - header.setRequest("GET", "/index.asp/a=%20&b=%20&c=%20"); - QCOMPARE(header.toString(), QString("GET /index.asp/a=%20&b=%20&c=%20 HTTP/1.1\r\n\r\n")); -} - -void tst_QHttp::caseInsensitiveKeys() -{ - QHttpResponseHeader header("HTTP/1.1 200 OK\r\nContent-Length: 213\r\nX-Been-There: True\r\nLocation: http://www.TrollTech.com/\r\n\r\n"); - QVERIFY(header.hasKey("Content-Length")); - QVERIFY(header.hasKey("X-Been-There")); - QVERIFY(header.hasKey("Location")); - QVERIFY(header.hasKey("content-length")); - QVERIFY(header.hasKey("x-been-there")); - QVERIFY(header.hasKey("location")); - QCOMPARE(header.value("Content-Length"), QString("213")); - QCOMPARE(header.value("X-Been-There"), QString("True")); - QCOMPARE(header.value("Location"), QString("http://www.TrollTech.com/")); - QCOMPARE(header.value("content-length"), QString("213")); - QCOMPARE(header.value("x-been-there"), QString("True")); - QCOMPARE(header.value("location"), QString("http://www.TrollTech.com/")); - QCOMPARE(header.allValues("location"), QStringList("http://www.TrollTech.com/")); - - header.addValue("Content-Length", "213"); - header.addValue("Content-Length", "214"); - header.addValue("Content-Length", "215"); - qDebug() << header.toString(); -} - -void tst_QHttp::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth) -{ - proxyAuthCalled = true; - auth->setUser("qsockstest"); - auth->setPassword("password"); -} - -void tst_QHttp::postAuthNtlm() -{ - QSKIP("NTLM not working"); - - QHostInfo info = QHostInfo::fromName(QHostInfo::localHostName()); - QByteArray postData("Hello World"); - QHttp http; - - http.setHost(QtNetworkSettings::serverName()); - http.setProxy(QtNetworkSettings::serverName(), 3130); - http.post("/", postData); - - proxyAuthCalled = false; - connect(&http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), - SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - - QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(3); - QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - - QVERIFY(proxyAuthCalled); - QVERIFY(!QTestEventLoop::instance().timeout()); -}; - -#ifndef QT_NO_OPENSSL -void tst_QHttp::proxyAndSsl() -{ - QFETCH_GLOBAL(bool, setProxy); - if (setProxy) - return; - - QHttp http; - - http.setHost(QtNetworkSettings::serverName(), QHttp::ConnectionModeHttps); - http.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3129)); - http.get("/"); - - proxyAuthCalled = false; - connect(&http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), - SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - connect(&http, SIGNAL(sslErrors(QList<QSslError>)), - &http, SLOT(ignoreSslErrors())); - - QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(3); - QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - - QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(proxyAuthCalled); - - QHttpResponseHeader header = http.lastResponse(); - QVERIFY(header.isValid()); - QVERIFY(header.statusCode() < 400); // Should be 200, but as long as it's not an error, we're happy -} -#endif - -#ifndef QT_NO_OPENSSL -void tst_QHttp::cachingProxyAndSsl() -{ - QFETCH_GLOBAL(bool, setProxy); - if (setProxy) - return; - - QHttp http; - - http.setHost(QtNetworkSettings::serverName(), QHttp::ConnectionModeHttps); - http.setProxy(QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)); - http.get("/"); - - proxyAuthCalled = false; - connect(&http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), - SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - - QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(3); - QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - - QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(!proxyAuthCalled); // NOT called! QHttp should get a socket error - QVERIFY(http.state() != QHttp::Connected); - - QHttpResponseHeader header = http.lastResponse(); - QVERIFY(!header.isValid()); -} -#endif - -void tst_QHttp::emptyBodyInReply() -{ - // Note: if this test starts failing, please verify the date on the file - // returned by Apache on http://netiks.troll.no/ - // It is right now hard-coded to the date below - QHttp http; - http.setHost(QtNetworkSettings::serverName()); - - QHttpRequestHeader headers("GET", "/"); - headers.addValue("If-Modified-Since", "Sun, 16 Nov 2008 12:29:51 GMT"); - headers.addValue("Host", QtNetworkSettings::serverName()); - http.request(headers); - - QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - - QVERIFY(!QTestEventLoop::instance().timeout()); - - // check the reply - if (http.lastResponse().statusCode() != 304) { - qWarning() << http.lastResponse().statusCode() << qPrintable(http.lastResponse().reasonPhrase()); - qWarning() << "Last-Modified:" << qPrintable(http.lastResponse().value("last-modified")); - QFAIL("Server replied with the wrong status code; see warning output"); - } -} - -void tst_QHttp::abortSender() -{ - QHttp *http = qobject_cast<QHttp *>(sender()); - if (http) - http->abort(); -} - -void tst_QHttp::abortInReadyRead() -{ - QHttp http; - http.setHost(QtNetworkSettings::serverName()); - http.get("/qtest/bigfile"); - - qRegisterMetaType<QHttpResponseHeader>(); - QSignalSpy spy(&http, SIGNAL(readyRead(QHttpResponseHeader))); - - QObject::connect(&http, SIGNAL(readyRead(QHttpResponseHeader)), this, SLOT(abortSender())); - QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - - QVERIFY2(!QTestEventLoop::instance().timeout(), "Network timeout"); - QVERIFY(http.state() != QHttp::Connected); - - QCOMPARE(spy.count(), 1); -} - -void tst_QHttp::abortInResponseHeaderReceived() -{ - QHttp http; - http.setHost(QtNetworkSettings::serverName()); - http.get("/qtest/bigfile"); - - qRegisterMetaType<QHttpResponseHeader>(); - QSignalSpy spy(&http, SIGNAL(readyRead(QHttpResponseHeader))); - - QObject::connect(&http, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), this, SLOT(abortSender())); - QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(10); - QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - - QVERIFY2(!QTestEventLoop::instance().timeout(), "Network timeout"); - QVERIFY(http.state() != QHttp::Connected); - - QCOMPARE(spy.count(), 0); -} - -void tst_QHttp::connectionClose() -{ - // This was added in response to bug 176822 - QFETCH_GLOBAL(bool, setProxy); - if (setProxy) - return; - - QHttp http; - ClosingServer server; - http.setHost("localhost", QHttp::ConnectionModeHttps, server.serverPort()); - http.get("/login/gateway/processLogin"); - - // another possibility: - //http.setHost("nexus.passport.com", QHttp::ConnectionModeHttps, 443); - //http.get("/rdr/pprdr.asp"); - - QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(900); - QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); - - QVERIFY(!QTestEventLoop::instance().timeout()); -} - -void tst_QHttp::nestedEventLoop_slot(int id) -{ - if (!ids.contains(id)) - return; - QEventLoop subloop; - - // 16 seconds: fluke times out in 15 seconds, which triggers a QTcpSocket error - QTimer::singleShot(16000, &subloop, SLOT(quit())); - subloop.exec(); - - QTestEventLoop::instance().exitLoop(); -} - -void tst_QHttp::nestedEventLoop() -{ - QFETCH_GLOBAL(bool, setProxy); - if (setProxy) - return; - - http = new QHttp; - http->setHost(QtNetworkSettings::serverName()); - int getId = http->get("/"); - - ids.clear(); - ids << getId; - - QSignalSpy spy(http, SIGNAL(requestStarted(int))); - QSignalSpy spy2(http, SIGNAL(done(bool))); - - connect(http, SIGNAL(requestFinished(int,bool)), SLOT(nestedEventLoop_slot(int))); - QTestEventLoop::instance().enterLoop(20); - - QVERIFY2(!QTestEventLoop::instance().timeout(), "Network timeout"); - - // Find out how many signals with the first argument equalling our id were found - int spyCount = 0; - for (int i = 0; i < spy.count(); ++i) - if (spy.at(i).at(0).toInt() == getId) - ++spyCount; - - // each signal spied should have been emitted only once - QCOMPARE(spyCount, 1); - QCOMPARE(spy2.count(), 1); -} - -QTEST_MAIN(tst_QHttp) -#include "tst_qhttp.moc" |