tests/auto/qhttpsocketengine/tst_qhttpsocketengine.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 
       
    45 #include <qcoreapplication.h>
       
    46 
       
    47 #include <private/qhttpsocketengine_p.h>
       
    48 #include <qhostinfo.h>
       
    49 #include <qhostaddress.h>
       
    50 #include <qtcpsocket.h>
       
    51 #include <qhttp.h>
       
    52 #include <qdebug.h>
       
    53 #include <qtcpserver.h>
       
    54 
       
    55 #include "../network-settings.h"
       
    56 
       
    57 class tst_QHttpSocketEngine : public QObject
       
    58 {
       
    59     Q_OBJECT
       
    60 
       
    61 public:
       
    62     tst_QHttpSocketEngine();
       
    63     virtual ~tst_QHttpSocketEngine();
       
    64 
       
    65 
       
    66 public slots:
       
    67     void init();
       
    68     void cleanup();
       
    69 private slots:
       
    70     void construction();
       
    71     void errorTest_data();
       
    72     void errorTest();
       
    73     void simpleConnectToIMAP();
       
    74     void simpleErrorsAndStates();
       
    75 
       
    76     void tcpSocketBlockingTest();
       
    77     void tcpSocketNonBlockingTest();
       
    78     void downloadBigFile();
       
    79    // void tcpLoopbackPerformance();
       
    80     void passwordAuth();
       
    81 
       
    82 protected slots:
       
    83     void tcpSocketNonBlocking_hostFound();
       
    84     void tcpSocketNonBlocking_connected();
       
    85     void tcpSocketNonBlocking_closed();
       
    86     void tcpSocketNonBlocking_readyRead();
       
    87     void tcpSocketNonBlocking_bytesWritten(qint64);
       
    88     void exitLoopSlot();
       
    89     void downloadBigFileSlot();
       
    90 
       
    91 private:
       
    92     QTcpSocket *tcpSocketNonBlocking_socket;
       
    93     QStringList tcpSocketNonBlocking_data;
       
    94     qint64 tcpSocketNonBlocking_totalWritten;
       
    95     QTcpSocket *tmpSocket;
       
    96     qint64 bytesAvailable;
       
    97 };
       
    98 
       
    99 class MiniHttpServer: public QTcpServer
       
   100 {
       
   101     Q_OBJECT
       
   102     QTcpSocket *client;
       
   103     QList<QByteArray> dataToTransmit;
       
   104 
       
   105 public:
       
   106     QByteArray receivedData;
       
   107 
       
   108     MiniHttpServer(const QList<QByteArray> &data) : client(0), dataToTransmit(data)
       
   109     {
       
   110         listen();
       
   111         connect(this, SIGNAL(newConnection()), this, SLOT(doAccept()));
       
   112     }
       
   113 
       
   114 public slots:
       
   115     void doAccept()
       
   116     {
       
   117         client = nextPendingConnection();
       
   118         connect(client, SIGNAL(readyRead()), this, SLOT(sendData()));
       
   119     }
       
   120 
       
   121     void sendData()
       
   122     {
       
   123         receivedData += client->readAll();
       
   124         int idx = client->property("dataTransmitionIdx").toInt();
       
   125         if (receivedData.contains("\r\n\r\n") ||
       
   126             receivedData.contains("\n\n")) {
       
   127             if (idx < dataToTransmit.length())
       
   128                 client->write(dataToTransmit.at(idx++));
       
   129             if (idx == dataToTransmit.length()) {
       
   130                 client->disconnectFromHost();
       
   131                 disconnect(client, 0, this, 0);
       
   132                 client = 0;
       
   133             } else {
       
   134                 client->setProperty("dataTransmitionIdx", idx);
       
   135             }
       
   136         }
       
   137     }
       
   138 };
       
   139 
       
   140 tst_QHttpSocketEngine::tst_QHttpSocketEngine()
       
   141 {
       
   142     Q_SET_DEFAULT_IAP
       
   143 }
       
   144 
       
   145 tst_QHttpSocketEngine::~tst_QHttpSocketEngine()
       
   146 {
       
   147 }
       
   148 
       
   149 
       
   150 void tst_QHttpSocketEngine::init()
       
   151 {
       
   152     tmpSocket = 0;
       
   153     bytesAvailable = 0;
       
   154 }
       
   155 
       
   156 void tst_QHttpSocketEngine::cleanup()
       
   157 {
       
   158 }
       
   159 
       
   160 //---------------------------------------------------------------------------
       
   161 void tst_QHttpSocketEngine::construction()
       
   162 {
       
   163     QHttpSocketEngine socketDevice;
       
   164 
       
   165     QVERIFY(!socketDevice.isValid());
       
   166 
       
   167     // Initialize device
       
   168     QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
       
   169     QVERIFY(socketDevice.isValid());
       
   170     QVERIFY(socketDevice.protocol() == QAbstractSocket::IPv4Protocol);
       
   171     QVERIFY(socketDevice.socketType() == QAbstractSocket::TcpSocket);
       
   172     QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState);
       
   173    // QVERIFY(socketDevice.socketDescriptor() != -1);
       
   174     QVERIFY(socketDevice.localAddress() == QHostAddress());
       
   175     QVERIFY(socketDevice.localPort() == 0);
       
   176     QVERIFY(socketDevice.peerAddress() == QHostAddress());
       
   177     QVERIFY(socketDevice.peerPort() == 0);
       
   178     QVERIFY(socketDevice.error() == QAbstractSocket::UnknownSocketError);
       
   179 
       
   180     //QTest::ignoreMessage(QtWarningMsg, "QSocketLayer::bytesAvailable() was called in QAbstractSocket::UnconnectedState");
       
   181     QVERIFY(socketDevice.bytesAvailable() == 0);
       
   182 
       
   183     //QTest::ignoreMessage(QtWarningMsg, "QSocketLayer::hasPendingDatagrams() was called in QAbstractSocket::UnconnectedState");
       
   184     QVERIFY(!socketDevice.hasPendingDatagrams());
       
   185 }
       
   186 
       
   187 //---------------------------------------------------------------------------
       
   188 void tst_QHttpSocketEngine::errorTest_data()
       
   189 {
       
   190     QTest::addColumn<QString>("hostname");
       
   191     QTest::addColumn<int>("port");
       
   192     QTest::addColumn<QString>("username");
       
   193     QTest::addColumn<QString>("response");
       
   194     QTest::addColumn<int>("expectedError");
       
   195 
       
   196     QQueue<QByteArray> responses;
       
   197     QTest::newRow("proxy-host-not-found") << "this-host-does-not-exist." << 1080 << QString()
       
   198                                           << QString()
       
   199                                           << int(QAbstractSocket::ProxyNotFoundError);
       
   200     QTest::newRow("proxy-connection-refused") << QtNetworkSettings::serverName() << 2 << QString()
       
   201                                               << QString()
       
   202                                               << int(QAbstractSocket::ProxyConnectionRefusedError);
       
   203 
       
   204     QTest::newRow("garbage1") << QString() << 0 << QString()
       
   205                               << "This is not HTTP\r\n\r\n"
       
   206                               << int(QAbstractSocket::ProxyProtocolError);
       
   207 
       
   208     QTest::newRow("garbage2") << QString() << 0 << QString()
       
   209                               << "This is not HTTP"
       
   210                               << int(QAbstractSocket::ProxyConnectionClosedError);
       
   211 
       
   212     QTest::newRow("garbage3") << QString() << 0 << QString()
       
   213                               << ""
       
   214                               << int(QAbstractSocket::ProxyConnectionClosedError);
       
   215 
       
   216     QTest::newRow("forbidden") << QString() << 0 << QString()
       
   217                                << "HTTP/1.0 403 Forbidden\r\n\r\n"
       
   218                                << int(QAbstractSocket::SocketAccessError);
       
   219 
       
   220     QTest::newRow("method-not-allowed") << QString() << 0 << QString()
       
   221                                         << "HTTP/1.0 405 Method Not Allowed\r\n\r\n"
       
   222                                         << int(QAbstractSocket::SocketAccessError);
       
   223 
       
   224     QTest::newRow("proxy-authentication-too-short")
       
   225         << QString() << 0 << "foo"
       
   226         << "HTTP/1.0 407 Proxy Authentication Required\r\n\r\n"
       
   227         << int(QAbstractSocket::ProxyProtocolError);
       
   228 
       
   229     QTest::newRow("proxy-authentication-invalid-method")
       
   230         << QString() << 0 << "foo"
       
   231         << "HTTP/1.0 407 Proxy Authentication Required\r\n"
       
   232            "Proxy-Authenticate: Frobnicator\r\n\r\n"
       
   233         << int(QAbstractSocket::ProxyProtocolError);
       
   234 
       
   235     QTest::newRow("proxy-authentication-required")
       
   236         << QString() << 0 << "foo"
       
   237         << "HTTP/1.0 407 Proxy Authentication Required\r\n"
       
   238            "Proxy-Connection: close\r\n"
       
   239            "Proxy-Authenticate: Basic, realm=wonderland\r\n\r\n"
       
   240         << int(QAbstractSocket::ProxyAuthenticationRequiredError);
       
   241 
       
   242     QTest::newRow("proxy-authentication-required2")
       
   243         << QString() << 0 << "foo"
       
   244         << "HTTP/1.0 407 Proxy Authentication Required\r\n"
       
   245            "Proxy-Connection: keep-alive\r\n"
       
   246            "Proxy-Authenticate: Basic, realm=wonderland\r\n\r\n"
       
   247            "\1"
       
   248            "HTTP/1.0 407 Proxy Authentication Required\r\n"
       
   249            "Proxy-Authenticate: Basic, realm=wonderland\r\n\r\n"
       
   250         << int(QAbstractSocket::ProxyAuthenticationRequiredError);
       
   251 
       
   252     QTest::newRow("proxy-authentication-required-noclose")
       
   253         << QString() << 0 << "foo"
       
   254         << "HTTP/1.0 407 Proxy Authentication Required\r\n"
       
   255            "Proxy-Authenticate: Basic\r\n"
       
   256            "\r\n"
       
   257         << int(QAbstractSocket::ProxyAuthenticationRequiredError);
       
   258 
       
   259     QTest::newRow("connection-refused") << QString() << 0 << QString()
       
   260                                         << "HTTP/1.0 503 Service Unavailable\r\n\r\n"
       
   261                                         << int(QAbstractSocket::ConnectionRefusedError);
       
   262 
       
   263     QTest::newRow("host-not-found") << QString() << 0 << QString()
       
   264                                     << "HTTP/1.0 404 Not Found\r\n\r\n"
       
   265                                     << int(QAbstractSocket::HostNotFoundError);
       
   266 
       
   267     QTest::newRow("weird-http-reply") << QString() << 0 << QString()
       
   268                                       << "HTTP/1.0 206 Partial Content\r\n\r\n"
       
   269                                       << int(QAbstractSocket::ProxyProtocolError);
       
   270 }
       
   271 
       
   272 void tst_QHttpSocketEngine::errorTest()
       
   273 {
       
   274     QFETCH(QString, hostname);
       
   275     QFETCH(int, port);
       
   276     QFETCH(QString, username);
       
   277     QFETCH(QString, response);
       
   278     QFETCH(int, expectedError);
       
   279 
       
   280     MiniHttpServer server(response.toLatin1().split('\1'));
       
   281 
       
   282     if (hostname.isEmpty()) {
       
   283         hostname = "127.0.0.1";
       
   284         port = server.serverPort();
       
   285     }
       
   286     QTcpSocket socket;
       
   287     socket.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, hostname, port, username, username));
       
   288     socket.connectToHost("0.1.2.3", 12345);
       
   289 
       
   290     connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)),
       
   291             &QTestEventLoop::instance(), SLOT(exitLoop()));
       
   292     QTestEventLoop::instance().enterLoop(5);
       
   293     QVERIFY(!QTestEventLoop::instance().timeout());
       
   294 
       
   295     QCOMPARE(int(socket.error()), expectedError);
       
   296 }
       
   297 
       
   298 //---------------------------------------------------------------------------
       
   299 void tst_QHttpSocketEngine::simpleConnectToIMAP()
       
   300 {
       
   301     QHttpSocketEngine socketDevice;
       
   302 
       
   303     // Initialize device
       
   304     QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
       
   305     QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState);
       
   306 
       
   307     socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128));
       
   308 
       
   309     QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143));
       
   310     QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState);
       
   311     QVERIFY(socketDevice.waitForWrite());
       
   312     QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState);
       
   313     QVERIFY(socketDevice.peerAddress() == QtNetworkSettings::serverIP());
       
   314     QVERIFY(!socketDevice.localAddress().isNull());
       
   315     QVERIFY(socketDevice.localPort() > 0);
       
   316 
       
   317     // Wait for the greeting
       
   318     QVERIFY(socketDevice.waitForRead());
       
   319 
       
   320     // Read the greeting
       
   321     qint64 available = socketDevice.bytesAvailable();
       
   322     QVERIFY(available > 0);
       
   323     QByteArray array;
       
   324     array.resize(available);
       
   325     QVERIFY(socketDevice.read(array.data(), array.size()) == available);
       
   326 
       
   327     // Check that the greeting is what we expect it to be
       
   328     QCOMPARE(array.constData(), QtNetworkSettings::expectedReplyIMAP().constData());
       
   329 
       
   330 
       
   331     // Write a logout message
       
   332     QByteArray array2 = "XXXX LOGOUT\r\n";
       
   333     QVERIFY(socketDevice.write(array2.data(),
       
   334                               array2.size()) == array2.size());
       
   335 
       
   336     // Wait for the response
       
   337     QVERIFY(socketDevice.waitForRead());
       
   338 
       
   339     available = socketDevice.bytesAvailable();
       
   340     QVERIFY(available > 0);
       
   341     array.resize(available);
       
   342     QVERIFY(socketDevice.read(array.data(), array.size()) == available);
       
   343 
       
   344     // Check that the greeting is what we expect it to be
       
   345     QCOMPARE(array.constData(), "* BYE LOGOUT received\r\nXXXX OK Completed\r\n");
       
   346 
       
   347     // Wait for the response
       
   348     QVERIFY(socketDevice.waitForRead());
       
   349     char c;
       
   350     QCOMPARE(socketDevice.read(&c, sizeof(c)), (qint64) -1);
       
   351     QVERIFY(socketDevice.error() == QAbstractSocket::RemoteHostClosedError);
       
   352     QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState);
       
   353 }
       
   354 
       
   355 //---------------------------------------------------------------------------
       
   356 void tst_QHttpSocketEngine::simpleErrorsAndStates()
       
   357 {
       
   358     {
       
   359         QHttpSocketEngine socketDevice;
       
   360 
       
   361         // Initialize device
       
   362         QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
       
   363 
       
   364         socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128));
       
   365 
       
   366         QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState);
       
   367         QVERIFY(!socketDevice.connectToHost(QHostAddress(QtNetworkSettings::serverName()), 8088));
       
   368         QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState);
       
   369         if (socketDevice.waitForWrite(15000)) {
       
   370             QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState ||
       
   371                     socketDevice.state() == QAbstractSocket::UnconnectedState);
       
   372         } else {
       
   373             QVERIFY(socketDevice.error() == QAbstractSocket::SocketTimeoutError);
       
   374         }
       
   375     }
       
   376 
       
   377 }
       
   378 
       
   379 /*
       
   380 //---------------------------------------------------------------------------
       
   381 void tst_QHttpSocketEngine::tcpLoopbackPerformance()
       
   382 {
       
   383     QTcpServer server;
       
   384 
       
   385     // Bind to any port on all interfaces
       
   386     QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0));
       
   387     QVERIFY(server.state() == QAbstractSocket::BoundState);
       
   388     quint16 port = server.localPort();
       
   389 
       
   390     // Listen for incoming connections
       
   391     QVERIFY(server.listen());
       
   392     QVERIFY(server.state() == QAbstractSocket::ListeningState);
       
   393 
       
   394     // Initialize a Tcp socket
       
   395     QHttpSocketEngine client;
       
   396     QVERIFY(client.initialize(QAbstractSocket::TcpSocket));
       
   397 
       
   398     client.setProxy(QHostAddress("80.232.37.158"), 1081);
       
   399 
       
   400     // Connect to our server
       
   401     if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) {
       
   402         QVERIFY(client.waitForWrite());
       
   403         QVERIFY(client.connectToHost(QHostAddress("127.0.0.1"), port));
       
   404     }
       
   405 
       
   406     // The server accepts the connectio
       
   407     int socketDescriptor = server.accept();
       
   408     QVERIFY(socketDescriptor > 0);
       
   409 
       
   410     // A socket device is initialized on the server side, passing the
       
   411     // socket descriptor from accept(). It's pre-connected.
       
   412     QSocketLayer serverSocket;
       
   413     QVERIFY(serverSocket.initialize(socketDescriptor));
       
   414     QVERIFY(serverSocket.state() == QAbstractSocket::ConnectedState);
       
   415 
       
   416     const int messageSize = 1024 * 256;
       
   417     QByteArray message1(messageSize, '@');
       
   418     QByteArray answer(messageSize, '@');
       
   419 
       
   420     QTime timer;
       
   421     timer.start();
       
   422     qlonglong readBytes = 0;
       
   423     while (timer.elapsed() < 5000) {
       
   424         qlonglong written = serverSocket.write(message1.data(), message1.size());
       
   425         while (written > 0) {
       
   426             client.waitForRead();
       
   427             if (client.bytesAvailable() > 0) {
       
   428                 qlonglong readNow = client.read(answer.data(), answer.size());
       
   429                 written -= readNow;
       
   430                 readBytes += readNow;
       
   431             }
       
   432         }
       
   433     }
       
   434 
       
   435     qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
       
   436            readBytes / (1024.0 * 1024.0),
       
   437            timer.elapsed() / 1024.0,
       
   438            (readBytes / (timer.elapsed() / 1000.0)) / (1024 * 1024));
       
   439 }
       
   440 */
       
   441 
       
   442 
       
   443 
       
   444 void tst_QHttpSocketEngine::tcpSocketBlockingTest()
       
   445 {
       
   446     QHttpSocketEngineHandler http;
       
   447 
       
   448     QTcpSocket socket;
       
   449 
       
   450     // Connect
       
   451     socket.connectToHost(QtNetworkSettings::serverName(), 143);
       
   452     QVERIFY(socket.waitForConnected());
       
   453     QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
       
   454 
       
   455     // Read greeting
       
   456     QVERIFY(socket.waitForReadyRead(5000));
       
   457     QString s = socket.readLine();
       
   458     QCOMPARE(s.toLatin1().constData(), QtNetworkSettings::expectedReplyIMAP().constData());
       
   459 
       
   460     // Write NOOP
       
   461     QCOMPARE((int) socket.write("1 NOOP\r\n", 8), 8);
       
   462 
       
   463     if (!socket.canReadLine())
       
   464         QVERIFY(socket.waitForReadyRead(5000));
       
   465 
       
   466     // Read response
       
   467     s = socket.readLine();
       
   468     QCOMPARE(s.toLatin1().constData(), "1 OK Completed\r\n");
       
   469 
       
   470     // Write LOGOUT
       
   471     QCOMPARE((int) socket.write("2 LOGOUT\r\n", 10), 10);
       
   472 
       
   473     if (!socket.canReadLine())
       
   474         QVERIFY(socket.waitForReadyRead(5000));
       
   475 
       
   476     // Read two lines of respose
       
   477     s = socket.readLine();
       
   478     QCOMPARE(s.toLatin1().constData(), "* BYE LOGOUT received\r\n");
       
   479 
       
   480     if (!socket.canReadLine())
       
   481         QVERIFY(socket.waitForReadyRead(5000));
       
   482 
       
   483     s = socket.readLine();
       
   484     QCOMPARE(s.toLatin1().constData(), "2 OK Completed\r\n");
       
   485 
       
   486     // Close the socket
       
   487     socket.close();
       
   488 
       
   489     // Check that it's closed
       
   490     QCOMPARE(socket.state(), QTcpSocket::UnconnectedState);
       
   491 }
       
   492 
       
   493 //----------------------------------------------------------------------------------
       
   494 
       
   495 void tst_QHttpSocketEngine::tcpSocketNonBlockingTest()
       
   496 {
       
   497     QHttpSocketEngineHandler http;
       
   498 
       
   499     QTcpSocket socket;
       
   500     connect(&socket, SIGNAL(hostFound()), SLOT(tcpSocketNonBlocking_hostFound()));
       
   501     connect(&socket, SIGNAL(connected()), SLOT(tcpSocketNonBlocking_connected()));
       
   502     connect(&socket, SIGNAL(disconnected()), SLOT(tcpSocketNonBlocking_closed()));
       
   503     connect(&socket, SIGNAL(bytesWritten(qint64)), SLOT(tcpSocketNonBlocking_bytesWritten(qint64)));
       
   504     connect(&socket, SIGNAL(readyRead()), SLOT(tcpSocketNonBlocking_readyRead()));
       
   505     tcpSocketNonBlocking_socket = &socket;
       
   506 
       
   507     // Connect
       
   508     socket.connectToHost(QtNetworkSettings::serverName(), 143);
       
   509     QCOMPARE(socket.state(), QTcpSocket::HostLookupState);
       
   510 
       
   511     QTestEventLoop::instance().enterLoop(30);
       
   512     if (QTestEventLoop::instance().timeout()) {
       
   513         QFAIL("Timed out");
       
   514     }
       
   515 
       
   516     if (socket.state() == QTcpSocket::ConnectingState) {
       
   517         QTestEventLoop::instance().enterLoop(30);
       
   518         if (QTestEventLoop::instance().timeout()) {
       
   519             QFAIL("Timed out");
       
   520         }
       
   521     }
       
   522 
       
   523     QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
       
   524 
       
   525     QTestEventLoop::instance().enterLoop(30);
       
   526     if (QTestEventLoop::instance().timeout()) {
       
   527         QFAIL("Timed out");
       
   528     }
       
   529 
       
   530     // Read greeting
       
   531     QVERIFY(!tcpSocketNonBlocking_data.isEmpty());
       
   532     QCOMPARE(tcpSocketNonBlocking_data.at(0).toLatin1().constData(),
       
   533             QtNetworkSettings::expectedReplyIMAP().constData());
       
   534 
       
   535 
       
   536     tcpSocketNonBlocking_data.clear();
       
   537 
       
   538     tcpSocketNonBlocking_totalWritten = 0;
       
   539 
       
   540     // Write NOOP
       
   541     QCOMPARE((int) socket.write("1 NOOP\r\n", 8), 8);
       
   542 
       
   543 
       
   544     QTestEventLoop::instance().enterLoop(30);
       
   545     if (QTestEventLoop::instance().timeout()) {
       
   546         QFAIL("Timed out");
       
   547     }
       
   548 
       
   549     QVERIFY(tcpSocketNonBlocking_totalWritten == 8);
       
   550 
       
   551 
       
   552     QTestEventLoop::instance().enterLoop(30);
       
   553     if (QTestEventLoop::instance().timeout()) {
       
   554         QFAIL("Timed out");
       
   555     }
       
   556 
       
   557 
       
   558     // Read response
       
   559     QVERIFY(!tcpSocketNonBlocking_data.isEmpty());
       
   560     QCOMPARE(tcpSocketNonBlocking_data.at(0).toLatin1().constData(), "1 OK Completed\r\n");
       
   561     tcpSocketNonBlocking_data.clear();
       
   562 
       
   563 
       
   564     tcpSocketNonBlocking_totalWritten = 0;
       
   565 
       
   566     // Write LOGOUT
       
   567     QCOMPARE((int) socket.write("2 LOGOUT\r\n", 10), 10);
       
   568 
       
   569     QTestEventLoop::instance().enterLoop(30);
       
   570     if (QTestEventLoop::instance().timeout()) {
       
   571         QFAIL("Timed out");
       
   572     }
       
   573 
       
   574     QVERIFY(tcpSocketNonBlocking_totalWritten == 10);
       
   575 
       
   576     // Wait for greeting
       
   577     QTestEventLoop::instance().enterLoop(30);
       
   578     if (QTestEventLoop::instance().timeout()) {
       
   579         QFAIL("Timed out");
       
   580     }
       
   581 
       
   582     // Read two lines of respose
       
   583     QCOMPARE(tcpSocketNonBlocking_data.at(0).toLatin1().constData(), "* BYE LOGOUT received\r\n");
       
   584     QCOMPARE(tcpSocketNonBlocking_data.at(1).toLatin1().constData(), "2 OK Completed\r\n");
       
   585     tcpSocketNonBlocking_data.clear();
       
   586 
       
   587     // Close the socket
       
   588     socket.close();
       
   589 
       
   590     // Check that it's closed
       
   591     QCOMPARE(socket.state(), QTcpSocket::UnconnectedState);
       
   592 }
       
   593 
       
   594 void tst_QHttpSocketEngine::tcpSocketNonBlocking_hostFound()
       
   595 {
       
   596     QTestEventLoop::instance().exitLoop();
       
   597 }
       
   598 
       
   599 void tst_QHttpSocketEngine::tcpSocketNonBlocking_connected()
       
   600 {
       
   601     QTestEventLoop::instance().exitLoop();
       
   602 }
       
   603 
       
   604 void tst_QHttpSocketEngine::tcpSocketNonBlocking_readyRead()
       
   605 {
       
   606     while (tcpSocketNonBlocking_socket->canReadLine())
       
   607         tcpSocketNonBlocking_data.append(tcpSocketNonBlocking_socket->readLine());
       
   608 
       
   609     QTestEventLoop::instance().exitLoop();
       
   610 }
       
   611 
       
   612 void tst_QHttpSocketEngine::tcpSocketNonBlocking_bytesWritten(qint64 written)
       
   613 {
       
   614     tcpSocketNonBlocking_totalWritten += written;
       
   615     QTestEventLoop::instance().exitLoop();
       
   616 }
       
   617 
       
   618 void tst_QHttpSocketEngine::tcpSocketNonBlocking_closed()
       
   619 {
       
   620 }
       
   621 
       
   622 //----------------------------------------------------------------------------------
       
   623 
       
   624 void tst_QHttpSocketEngine::downloadBigFile()
       
   625 {
       
   626     QHttpSocketEngineHandler http;
       
   627 
       
   628     if (tmpSocket)
       
   629         delete tmpSocket;
       
   630     tmpSocket = new QTcpSocket;
       
   631 
       
   632     connect(tmpSocket, SIGNAL(connected()), SLOT(exitLoopSlot()));
       
   633     connect(tmpSocket, SIGNAL(readyRead()), SLOT(downloadBigFileSlot()));
       
   634 
       
   635     tmpSocket->connectToHost(QtNetworkSettings::serverName(), 80);
       
   636 
       
   637     QTestEventLoop::instance().enterLoop(30);
       
   638     if (QTestEventLoop::instance().timeout())
       
   639         QFAIL("Network operation timed out");
       
   640 
       
   641     QByteArray hostName = QtNetworkSettings::serverName().toLatin1();
       
   642     QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState);
       
   643     QVERIFY(tmpSocket->write("GET /mediumfile HTTP/1.0\r\n") > 0);
       
   644     QVERIFY(tmpSocket->write("Host: ") > 0);
       
   645     QVERIFY(tmpSocket->write(hostName.data()) > 0);
       
   646     QVERIFY(tmpSocket->write("\r\n") > 0);
       
   647     QVERIFY(tmpSocket->write("\r\n") > 0);
       
   648 
       
   649     bytesAvailable = 0;
       
   650 
       
   651     QTime stopWatch;
       
   652     stopWatch.start();
       
   653 
       
   654 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
       
   655     QTestEventLoop::instance().enterLoop(240);
       
   656 #else
       
   657     QTestEventLoop::instance().enterLoop(60);
       
   658 #endif
       
   659     if (QTestEventLoop::instance().timeout())
       
   660         QFAIL("Network operation timed out");
       
   661 
       
   662     QVERIFY(bytesAvailable >= 10000000);
       
   663 
       
   664     QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState);
       
   665 
       
   666     qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
       
   667            bytesAvailable / (1024.0 * 1024.0),
       
   668            stopWatch.elapsed() / 1024.0,
       
   669            (bytesAvailable / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));
       
   670 
       
   671     delete tmpSocket;
       
   672     tmpSocket = 0;
       
   673 }
       
   674 
       
   675 void tst_QHttpSocketEngine::exitLoopSlot()
       
   676 {
       
   677     QTestEventLoop::instance().exitLoop();
       
   678 }
       
   679 
       
   680 
       
   681 void tst_QHttpSocketEngine::downloadBigFileSlot()
       
   682 {
       
   683     bytesAvailable += tmpSocket->readAll().size();
       
   684     if (bytesAvailable >= 10000000)
       
   685         QTestEventLoop::instance().exitLoop();
       
   686 }
       
   687 
       
   688 void tst_QHttpSocketEngine::passwordAuth()
       
   689 {
       
   690     QHttpSocketEngine socketDevice;
       
   691 
       
   692     // Initialize device
       
   693     QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
       
   694     QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState);
       
   695 
       
   696     socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128, "qsockstest", "password"));
       
   697 
       
   698     QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143));
       
   699     QVERIFY(socketDevice.state() == QAbstractSocket::ConnectingState);
       
   700     QVERIFY(socketDevice.waitForWrite());
       
   701     QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState);
       
   702     QVERIFY(socketDevice.peerAddress() == QtNetworkSettings::serverIP());
       
   703 
       
   704     // Wait for the greeting
       
   705     QVERIFY(socketDevice.waitForRead());
       
   706 
       
   707     // Read the greeting
       
   708     qint64 available = socketDevice.bytesAvailable();
       
   709     QVERIFY(available > 0);
       
   710     QByteArray array;
       
   711     array.resize(available);
       
   712     QVERIFY(socketDevice.read(array.data(), array.size()) == available);
       
   713 
       
   714     // Check that the greeting is what we expect it to be
       
   715     QCOMPARE(array.constData(), QtNetworkSettings::expectedReplyIMAP().constData());
       
   716 
       
   717 
       
   718     // Write a logout message
       
   719     QByteArray array2 = "XXXX LOGOUT\r\n";
       
   720     QVERIFY(socketDevice.write(array2.data(),
       
   721                               array2.size()) == array2.size());
       
   722 
       
   723     // Wait for the response
       
   724     QVERIFY(socketDevice.waitForRead());
       
   725 
       
   726     available = socketDevice.bytesAvailable();
       
   727     QVERIFY(available > 0);
       
   728     array.resize(available);
       
   729     QVERIFY(socketDevice.read(array.data(), array.size()) == available);
       
   730 
       
   731     // Check that the greeting is what we expect it to be
       
   732     QCOMPARE(array.constData(), "* BYE LOGOUT received\r\nXXXX OK Completed\r\n");
       
   733 
       
   734     // Wait for the response
       
   735     QVERIFY(socketDevice.waitForRead());
       
   736     char c;
       
   737     QVERIFY(socketDevice.read(&c, sizeof(c)) == -1);
       
   738     QVERIFY(socketDevice.error() == QAbstractSocket::RemoteHostClosedError);
       
   739     QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState);
       
   740 }
       
   741 
       
   742 //----------------------------------------------------------------------------------
       
   743 
       
   744 QTEST_MAIN(tst_QHttpSocketEngine)
       
   745 #include "tst_qhttpsocketengine.moc"