tests/auto/qtcpsocket/tst_qtcpsocket.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
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 // Just to get Q_OS_SYMBIAN
       
    44 #include <qglobal.h>
       
    45 
       
    46 #if defined(_WIN32) && !defined(Q_OS_SYMBIAN)
       
    47 #include <winsock2.h>
       
    48 #else
       
    49 #include <sys/types.h>
       
    50 #include <sys/socket.h>
       
    51 #include <fcntl.h>
       
    52 #include <unistd.h>
       
    53 #define SOCKET int
       
    54 #define INVALID_SOCKET -1
       
    55 #endif
       
    56 
       
    57 #include <qplatformdefs.h>
       
    58 
       
    59 #include <QtTest/QtTest>
       
    60 
       
    61 #include <QAuthenticator>
       
    62 #include <QCoreApplication>
       
    63 #include <QEventLoop>
       
    64 #include <QFile>
       
    65 #include <QHostAddress>
       
    66 #include <QHostInfo>
       
    67 #include <QMap>
       
    68 #ifndef Q_OS_VXWORKS
       
    69 #include <QMessageBox>
       
    70 #include <QPushButton>
       
    71 #endif
       
    72 #include <QPointer>
       
    73 #include <QProcess>
       
    74 #include <QStringList>
       
    75 #include <QTcpServer>
       
    76 #include <QTcpSocket>
       
    77 #ifndef QT_NO_OPENSSL
       
    78 #include <QSslSocket>
       
    79 #endif
       
    80 #include <QTextStream>
       
    81 #include <QThread>
       
    82 #include <QTime>
       
    83 #include <QTimer>
       
    84 #include <QDebug>
       
    85 #ifndef TEST_QNETWORK_PROXY
       
    86 #define TEST_QNETWORK_PROXY
       
    87 #endif
       
    88 // RVCT compiles also unused inline methods
       
    89 # include <QNetworkProxy>
       
    90 
       
    91 #ifdef Q_OS_LINUX
       
    92 #include <stdio.h>
       
    93 #include <stdlib.h>
       
    94 #include <sys/stat.h>
       
    95 #include <unistd.h>
       
    96 #endif
       
    97 
       
    98 #include "../network-settings.h"
       
    99 
       
   100 Q_DECLARE_METATYPE(QAbstractSocket::SocketError)
       
   101 Q_DECLARE_METATYPE(QAbstractSocket::SocketState)
       
   102 Q_DECLARE_METATYPE(QNetworkProxy)
       
   103 Q_DECLARE_METATYPE(QList<QNetworkProxy>)
       
   104 
       
   105 //TESTED_CLASS=
       
   106 //TESTED_FILES=
       
   107 
       
   108 QT_FORWARD_DECLARE_CLASS(QTcpSocket)
       
   109 
       
   110 class tst_QTcpSocket : public QObject
       
   111 {
       
   112     Q_OBJECT
       
   113 
       
   114 public:
       
   115     tst_QTcpSocket();
       
   116     virtual ~tst_QTcpSocket();
       
   117 
       
   118     static void enterLoop(int secs)
       
   119     {
       
   120         ++loopLevel;
       
   121         QTestEventLoop::instance().enterLoop(secs);
       
   122         --loopLevel;
       
   123     }
       
   124     static void exitLoop()
       
   125     {
       
   126         // Safe exit - if we aren't in an event loop, don't
       
   127         // exit one.
       
   128         if (loopLevel > 0)
       
   129             QTestEventLoop::instance().exitLoop();
       
   130     }
       
   131     static bool timeout()
       
   132     {
       
   133         return QTestEventLoop::instance().timeout();
       
   134     }
       
   135 
       
   136 public slots:
       
   137     void initTestCase_data();
       
   138     void init();
       
   139     void cleanup();
       
   140 private slots:
       
   141     void constructing();
       
   142     void setInvalidSocketDescriptor();
       
   143     void setSocketDescriptor();
       
   144     void socketDescriptor();
       
   145     void blockingIMAP();
       
   146     void nonBlockingIMAP();
       
   147     void hostNotFound();
       
   148     void timeoutConnect();
       
   149     void delayedClose();
       
   150     void partialRead();
       
   151     void unget();
       
   152     void readAllAfterClose();
       
   153     void openCloseOpenClose();
       
   154     void connectDisconnectConnectDisconnect();
       
   155     void disconnectWhileConnecting_data();
       
   156     void disconnectWhileConnecting();
       
   157     void disconnectWhileConnectingNoEventLoop_data();
       
   158     void disconnectWhileConnectingNoEventLoop();
       
   159     void disconnectWhileLookingUp_data();
       
   160     void disconnectWhileLookingUp();
       
   161     void downloadBigFile();
       
   162     void readLine();
       
   163     void readLineString();
       
   164     void readChunks();
       
   165     void waitForBytesWritten();
       
   166     void waitForReadyRead();
       
   167     void flush();
       
   168     void synchronousApi();
       
   169     void dontCloseOnTimeout();
       
   170     void recursiveReadyRead();
       
   171     void atEnd();
       
   172     void socketInAThread();
       
   173     void socketsInThreads();
       
   174     void waitForReadyReadInASlot();
       
   175     void remoteCloseError();
       
   176     void openMessageBoxInErrorSlot();
       
   177 #ifndef Q_OS_WIN
       
   178     void connectToLocalHostNoService();
       
   179 #endif
       
   180     void waitForConnectedInHostLookupSlot();
       
   181     void waitForConnectedInHostLookupSlot2();
       
   182     void readyReadSignalsAfterWaitForReadyRead();
       
   183 #ifdef Q_OS_LINUX
       
   184     void linuxKernelBugLocalSocket();
       
   185 #endif
       
   186     void abortiveClose();
       
   187     void localAddressEmptyOnBSD();
       
   188     void zeroAndMinusOneReturns();
       
   189     void connectionRefused();
       
   190     void suddenRemoteDisconnect_data();
       
   191     void suddenRemoteDisconnect();
       
   192     void connectToMultiIP();
       
   193     void moveToThread0();
       
   194     void increaseReadBufferSize();
       
   195 #ifdef TEST_QNETWORK_PROXY
       
   196     void invalidProxy_data();
       
   197     void invalidProxy();
       
   198     void proxyFactory_data();
       
   199     void proxyFactory();
       
   200 #endif
       
   201 
       
   202 protected slots:
       
   203     void nonBlockingIMAP_hostFound();
       
   204     void nonBlockingIMAP_connected();
       
   205     void nonBlockingIMAP_closed();
       
   206     void nonBlockingIMAP_readyRead();
       
   207     void nonBlockingIMAP_bytesWritten(qint64);
       
   208     void readRegularFile_readyRead();
       
   209     void exitLoopSlot();
       
   210     void downloadBigFileSlot();
       
   211     void recursiveReadyReadSlot();
       
   212     void waitForReadyReadInASlotSlot();
       
   213     void messageBoxSlot();
       
   214     void hostLookupSlot();
       
   215     void abortiveClose_abortSlot();
       
   216     void remoteCloseErrorSlot();
       
   217     void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth);
       
   218 
       
   219 private:
       
   220     QTcpSocket *newSocket() const;
       
   221     QTcpSocket *nonBlockingIMAP_socket;
       
   222     QStringList nonBlockingIMAP_data;
       
   223     qint64 nonBlockingIMAP_totalWritten;
       
   224 
       
   225     QTcpSocket *tmpSocket;
       
   226     qint64 bytesAvailable;
       
   227     qint64 expectedLength;
       
   228     bool readingBody;
       
   229     QTime timer;
       
   230 
       
   231     mutable int proxyAuthCalled;
       
   232 
       
   233     bool gotClosedSignal;
       
   234     int numConnections;
       
   235     static int loopLevel;
       
   236 };
       
   237 
       
   238 enum ProxyTests {
       
   239     NoProxy = 0x00,
       
   240     Socks5Proxy = 0x01,
       
   241     HttpProxy = 0x02,
       
   242     TypeMask = 0x0f,
       
   243 
       
   244     NoAuth = 0x00,
       
   245     AuthBasic = 0x10,
       
   246     AuthNtlm = 0x20,
       
   247     AuthMask = 0xf0
       
   248 };
       
   249 
       
   250 int tst_QTcpSocket::loopLevel = 0;
       
   251 
       
   252 tst_QTcpSocket::tst_QTcpSocket()
       
   253 {
       
   254     Q_SET_DEFAULT_IAP
       
   255     tmpSocket = 0;
       
   256 }
       
   257 
       
   258 tst_QTcpSocket::~tst_QTcpSocket()
       
   259 {
       
   260 
       
   261 }
       
   262 
       
   263 void tst_QTcpSocket::initTestCase_data()
       
   264 {
       
   265     QTest::addColumn<bool>("setProxy");
       
   266     QTest::addColumn<int>("proxyType");
       
   267     QTest::addColumn<bool>("ssl");
       
   268 
       
   269     qDebug() << QtNetworkSettings::serverName();
       
   270     QTest::newRow("WithoutProxy") << false << 0 << false;
       
   271 #ifdef TEST_QNETWORK_PROXY
       
   272     QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy) << false;
       
   273     QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic) << false;
       
   274 
       
   275     QTest::newRow("WithHttpProxy") << true << int(HttpProxy) << false;
       
   276     QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic) << false;
       
   277 //    QTest::newRow("WithHttpProxyNtlmAuth") << true << int(HttpProxy | AuthNtlm) << false;
       
   278 #endif
       
   279 #ifndef QT_NO_OPENSSL
       
   280     QTest::newRow("WithoutProxy SSL") << false << 0 << true;
       
   281 #ifdef TEST_QNETWORK_PROXY
       
   282     QTest::newRow("WithSocks5Proxy SSL") << true << int(Socks5Proxy) << true;
       
   283     QTest::newRow("WithSocks5AuthProxy SSL") << true << int(Socks5Proxy | AuthBasic) << true;
       
   284 
       
   285     QTest::newRow("WithHttpProxy SSL") << true << int(HttpProxy) << true;
       
   286     QTest::newRow("WithHttpProxyBasicAuth SSL") << true << int(HttpProxy | AuthBasic) << true;
       
   287 //    QTest::newRow("WithHttpProxyNtlmAuth SSL") << true << int(HttpProxy | AuthNtlm) << true;
       
   288 #endif
       
   289 #endif
       
   290 }
       
   291 
       
   292 void tst_QTcpSocket::init()
       
   293 {
       
   294     QFETCH_GLOBAL(bool, setProxy);
       
   295     if (setProxy) {
       
   296 #ifdef TEST_QNETWORK_PROXY
       
   297         QFETCH_GLOBAL(int, proxyType);
       
   298         QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString();
       
   299         QNetworkProxy proxy;
       
   300 
       
   301         switch (proxyType) {
       
   302         case Socks5Proxy:
       
   303             proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1080);
       
   304             break;
       
   305 
       
   306         case Socks5Proxy | AuthBasic:
       
   307             proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1081);
       
   308             break;
       
   309 
       
   310         case HttpProxy | NoAuth:
       
   311             proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3128);
       
   312             break;
       
   313 
       
   314         case HttpProxy | AuthBasic:
       
   315             proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3129);
       
   316             break;
       
   317 
       
   318         case HttpProxy | AuthNtlm:
       
   319             proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3130);
       
   320             break;
       
   321         }
       
   322         QNetworkProxy::setApplicationProxy(proxy);
       
   323 #endif
       
   324     }
       
   325 }
       
   326 
       
   327 QTcpSocket *tst_QTcpSocket::newSocket() const
       
   328 {
       
   329     QTcpSocket *socket;
       
   330 #ifndef QT_NO_OPENSSL
       
   331     QFETCH_GLOBAL(bool, ssl);
       
   332     socket = ssl ? new QSslSocket : new QTcpSocket;
       
   333 #else
       
   334     socket = new QTcpSocket;
       
   335 #endif
       
   336 
       
   337     proxyAuthCalled = 0;
       
   338     connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
       
   339             SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
       
   340             Qt::DirectConnection);
       
   341     return socket;
       
   342 }
       
   343 
       
   344 void tst_QTcpSocket::cleanup()
       
   345 {
       
   346 #ifdef TEST_QNETWORK_PROXY
       
   347     QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
       
   348 #endif
       
   349 }
       
   350 
       
   351 void tst_QTcpSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
       
   352 {
       
   353     ++proxyAuthCalled;
       
   354     auth->setUser("qsockstest");
       
   355     auth->setPassword("password");
       
   356 }
       
   357 
       
   358 //----------------------------------------------------------------------------------
       
   359 
       
   360 void tst_QTcpSocket::constructing()
       
   361 {
       
   362     QTcpSocket *socket = newSocket();
       
   363 
       
   364     // Check the initial state of the QTcpSocket.
       
   365     QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
       
   366     QVERIFY(socket->isSequential());
       
   367     QVERIFY(!socket->isOpen());
       
   368     QVERIFY(!socket->isValid());
       
   369     QCOMPARE(socket->socketType(), QTcpSocket::TcpSocket);
       
   370 
       
   371     char c;
       
   372     QTest::ignoreMessage(QtWarningMsg, "QIODevice::getChar: Closed device");
       
   373     QCOMPARE(socket->getChar(&c), false);
       
   374     QCOMPARE((int) socket->bytesAvailable(), 0);
       
   375     QCOMPARE(socket->canReadLine(), false);
       
   376     QCOMPARE(socket->readLine(), QByteArray());
       
   377     QCOMPARE(socket->socketDescriptor(), -1);
       
   378     QCOMPARE((int) socket->localPort(), 0);
       
   379     QVERIFY(socket->localAddress() == QHostAddress());
       
   380     QCOMPARE((int) socket->peerPort(), 0);
       
   381     QVERIFY(socket->peerAddress() == QHostAddress());
       
   382     QCOMPARE(socket->error(), QTcpSocket::UnknownSocketError);
       
   383     QCOMPARE(socket->errorString(), QString("Unknown error"));
       
   384 
       
   385     // Check the state of the socket layer?
       
   386     delete socket;
       
   387 }
       
   388 
       
   389 //----------------------------------------------------------------------------------
       
   390 
       
   391 void tst_QTcpSocket::setInvalidSocketDescriptor()
       
   392 {
       
   393     QTcpSocket *socket = newSocket();
       
   394     QCOMPARE(socket->socketDescriptor(), -1);
       
   395     QVERIFY(!socket->setSocketDescriptor(-5, QTcpSocket::UnconnectedState));
       
   396     QCOMPARE(socket->socketDescriptor(), -1);
       
   397 
       
   398     QCOMPARE(socket->error(), QTcpSocket::UnsupportedSocketOperationError);
       
   399 
       
   400     delete socket;
       
   401 }
       
   402 
       
   403 //----------------------------------------------------------------------------------
       
   404 
       
   405 void tst_QTcpSocket::setSocketDescriptor()
       
   406 {
       
   407     QFETCH_GLOBAL(bool, setProxy);
       
   408     if (setProxy)
       
   409         return;                 // this test doesn't make sense with proxies
       
   410 
       
   411 #ifdef Q_OS_WIN
       
   412     // need the dummy to ensure winsock is started
       
   413     QTcpSocket *dummy = newSocket();
       
   414     dummy->connectToHost(QtNetworkSettings::serverName(), 143);
       
   415     QVERIFY(dummy->waitForConnected());
       
   416 
       
   417     SOCKET sock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
       
   418     if (sock == INVALID_SOCKET) {
       
   419         qErrnoWarning(WSAGetLastError(), "INVALID_SOCKET");
       
   420     }
       
   421 #else
       
   422     SOCKET sock = ::socket(AF_INET, SOCK_STREAM, 0);
       
   423 
       
   424     // artificially increase the value of sock
       
   425     SOCKET sock2 = ::fcntl(sock, F_DUPFD, sock + 50);
       
   426     ::close(sock);
       
   427     sock = sock2;
       
   428 #endif
       
   429 
       
   430     QVERIFY(sock != INVALID_SOCKET);
       
   431     QTcpSocket *socket = newSocket();
       
   432     QVERIFY(socket->setSocketDescriptor(sock, QTcpSocket::UnconnectedState));
       
   433     QCOMPARE(socket->socketDescriptor(), (int)sock);
       
   434 
       
   435     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
   436     QCOMPARE(socket->state(), QTcpSocket::HostLookupState);
       
   437     QCOMPARE(socket->socketDescriptor(), (int)sock);
       
   438     QVERIFY(socket->waitForConnected(10000));
       
   439     // skip this, it has been broken for years, see task 260735
       
   440     // if somebody complains, consider fixing it, but it might break existing applications.
       
   441     QEXPECT_FAIL("", "bug has been around for years, will not fix without need", Continue);
       
   442     QCOMPARE(socket->socketDescriptor(), (int)sock);
       
   443     delete socket;
       
   444 #ifdef Q_OS_WIN
       
   445     delete dummy;
       
   446 #endif
       
   447 }
       
   448 
       
   449 //----------------------------------------------------------------------------------
       
   450 
       
   451 void tst_QTcpSocket::socketDescriptor()
       
   452 {
       
   453     QTcpSocket *socket = newSocket();
       
   454 
       
   455     QCOMPARE(socket->socketDescriptor(), -1);
       
   456     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
   457     QVERIFY((socket->state() == QAbstractSocket::HostLookupState && socket->socketDescriptor() == -1) ||
       
   458             (socket->state() == QAbstractSocket::ConnectingState && socket->socketDescriptor() != -1));
       
   459     QVERIFY(socket->waitForConnected(10000));
       
   460     QVERIFY(socket->state() == QAbstractSocket::ConnectedState);
       
   461     QVERIFY(socket->socketDescriptor() != -1);
       
   462 
       
   463     delete socket;
       
   464 }
       
   465 
       
   466 //----------------------------------------------------------------------------------
       
   467 
       
   468 void tst_QTcpSocket::blockingIMAP()
       
   469 {
       
   470     QTcpSocket *socket = newSocket();
       
   471 
       
   472     // Connect
       
   473     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
   474     QVERIFY(socket->waitForConnected(10000));
       
   475     QCOMPARE(socket->state(), QTcpSocket::ConnectedState);
       
   476     QVERIFY(socket->isValid());
       
   477 
       
   478     // Read greeting
       
   479     QVERIFY(socket->waitForReadyRead(5000));
       
   480     QString s = socket->readLine();
       
   481     // only test if an OK was returned, to make the test compatible between different
       
   482     // IMAP server versions
       
   483     QCOMPARE(s.left(4).toLatin1().constData(), "* OK");
       
   484 
       
   485     // Write NOOP
       
   486     QCOMPARE((int) socket->write("1 NOOP\r\n", 8), 8);
       
   487     QCOMPARE((int) socket->write("2 NOOP\r\n", 8), 8);
       
   488 
       
   489     if (!socket->canReadLine())
       
   490         QVERIFY(socket->waitForReadyRead(5000));
       
   491 
       
   492     // Read response
       
   493     s = socket->readLine();
       
   494     QCOMPARE(s.toLatin1().constData(), "1 OK Completed\r\n");
       
   495 
       
   496     // Write a third NOOP to verify that write doesn't clear the read buffer
       
   497     QCOMPARE((int) socket->write("3 NOOP\r\n", 8), 8);
       
   498 
       
   499     // Read second response
       
   500     if (!socket->canReadLine())
       
   501         QVERIFY(socket->waitForReadyRead(5000));
       
   502     s = socket->readLine();
       
   503     QCOMPARE(s.toLatin1().constData(), "2 OK Completed\r\n");
       
   504 
       
   505     // Read third response
       
   506     if (!socket->canReadLine())
       
   507         QVERIFY(socket->waitForReadyRead(5000));
       
   508     s = socket->readLine();
       
   509     QCOMPARE(s.toLatin1().constData(), "3 OK Completed\r\n");
       
   510 
       
   511 
       
   512     // Write LOGOUT
       
   513     QCOMPARE((int) socket->write("4 LOGOUT\r\n", 10), 10);
       
   514 
       
   515     if (!socket->canReadLine())
       
   516         QVERIFY(socket->waitForReadyRead(5000));
       
   517 
       
   518     // Read two lines of respose
       
   519     s = socket->readLine();
       
   520     QCOMPARE(s.toLatin1().constData(), "* BYE LOGOUT received\r\n");
       
   521 
       
   522     if (!socket->canReadLine())
       
   523         QVERIFY(socket->waitForReadyRead(5000));
       
   524 
       
   525     s = socket->readLine();
       
   526     QCOMPARE(s.toLatin1().constData(), "4 OK Completed\r\n");
       
   527 
       
   528     // Close the socket
       
   529     socket->close();
       
   530 
       
   531     // Check that it's closed
       
   532     QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
       
   533 
       
   534     delete socket;
       
   535 }
       
   536 
       
   537 //----------------------------------------------------------------------------------
       
   538 
       
   539 void tst_QTcpSocket::hostNotFound()
       
   540 {
       
   541     QTcpSocket *socket = newSocket();
       
   542 
       
   543     socket->connectToHost("nosuchserver.troll.no", 80);
       
   544     QVERIFY(!socket->waitForConnected());
       
   545     QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
       
   546     QCOMPARE(int(socket->error()), int(QTcpSocket::HostNotFoundError));
       
   547 
       
   548     delete socket;
       
   549 }
       
   550 
       
   551 //----------------------------------------------------------------------------------
       
   552 
       
   553 void tst_QTcpSocket::timeoutConnect()
       
   554 {
       
   555     QTcpSocket *socket = newSocket();
       
   556 
       
   557     // Outgoing port 53 is firewalled in the Oslo office.
       
   558     socket->connectToHost("cisco.com", 53);
       
   559     QVERIFY(!socket->waitForConnected(200));
       
   560     QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
       
   561     QCOMPARE(int(socket->error()), int(QTcpSocket::SocketTimeoutError));
       
   562 
       
   563     socket->connectToHost("cisco.com", 53);
       
   564     QTest::qSleep(50);
       
   565     socket->abort();
       
   566     QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
       
   567     QCOMPARE(socket->openMode(), QIODevice::NotOpen);
       
   568 
       
   569     delete socket;
       
   570 }
       
   571 
       
   572 //----------------------------------------------------------------------------------
       
   573 
       
   574 void tst_QTcpSocket::nonBlockingIMAP()
       
   575 {
       
   576     QTcpSocket *socket = newSocket();
       
   577     connect(socket, SIGNAL(hostFound()), SLOT(nonBlockingIMAP_hostFound()));
       
   578     connect(socket, SIGNAL(connected()), SLOT(nonBlockingIMAP_connected()));
       
   579     connect(socket, SIGNAL(disconnected()), SLOT(nonBlockingIMAP_closed()));
       
   580     connect(socket, SIGNAL(bytesWritten(qint64)), SLOT(nonBlockingIMAP_bytesWritten(qint64)));
       
   581     connect(socket, SIGNAL(readyRead()), SLOT(nonBlockingIMAP_readyRead()));
       
   582     nonBlockingIMAP_socket = socket;
       
   583 
       
   584     // Connect
       
   585     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
   586     QVERIFY(socket->state() == QTcpSocket::HostLookupState ||
       
   587             socket->state() == QTcpSocket::ConnectingState);
       
   588 
       
   589     enterLoop(30);
       
   590     if (timeout()) {
       
   591         QFAIL("Timed out");
       
   592     }
       
   593 
       
   594     if (socket->state() == QTcpSocket::ConnectingState) {
       
   595         enterLoop(30);
       
   596         if (timeout()) {
       
   597             QFAIL("Timed out");
       
   598         }
       
   599     }
       
   600 
       
   601     QCOMPARE(socket->state(), QTcpSocket::ConnectedState);
       
   602 
       
   603     enterLoop(30);
       
   604     if (timeout()) {
       
   605         QFAIL("Timed out");
       
   606     }
       
   607 
       
   608     // Read greeting
       
   609     QVERIFY(!nonBlockingIMAP_data.isEmpty());
       
   610 //    QCOMPARE(nonBlockingIMAP_data.at(0).toLatin1().constData(),
       
   611 //            "* OK fluke Cyrus IMAP4 v2.2.12 server ready\r\n");
       
   612     QCOMPARE(nonBlockingIMAP_data.at(0).left(4).toLatin1().constData(), "* OK");
       
   613     nonBlockingIMAP_data.clear();
       
   614 
       
   615     nonBlockingIMAP_totalWritten = 0;
       
   616 
       
   617     // Write NOOP
       
   618     QCOMPARE((int) socket->write("1 NOOP\r\n", 8), 8);
       
   619 
       
   620 
       
   621     enterLoop(30);
       
   622     if (timeout()) {
       
   623         QFAIL("Timed out");
       
   624     }
       
   625 
       
   626     QVERIFY(nonBlockingIMAP_totalWritten == 8);
       
   627 
       
   628 
       
   629     enterLoop(30);
       
   630     if (timeout()) {
       
   631         QFAIL("Timed out");
       
   632     }
       
   633 
       
   634 
       
   635     // Read response
       
   636     QVERIFY(!nonBlockingIMAP_data.isEmpty());
       
   637     QCOMPARE(nonBlockingIMAP_data.at(0).toLatin1().constData(), "1 OK Completed\r\n");
       
   638     nonBlockingIMAP_data.clear();
       
   639 
       
   640 
       
   641     nonBlockingIMAP_totalWritten = 0;
       
   642 
       
   643     // Write LOGOUT
       
   644     QCOMPARE((int) socket->write("2 LOGOUT\r\n", 10), 10);
       
   645 
       
   646     enterLoop(30);
       
   647     if (timeout()) {
       
   648         QFAIL("Timed out");
       
   649     }
       
   650 
       
   651     QVERIFY(nonBlockingIMAP_totalWritten == 10);
       
   652 
       
   653     // Wait for greeting
       
   654     enterLoop(30);
       
   655     if (timeout()) {
       
   656         QFAIL("Timed out");
       
   657     }
       
   658 
       
   659     // Read two lines of respose
       
   660     QCOMPARE(nonBlockingIMAP_data.at(0).toLatin1().constData(), "* BYE LOGOUT received\r\n");
       
   661     QCOMPARE(nonBlockingIMAP_data.at(1).toLatin1().constData(), "2 OK Completed\r\n");
       
   662     nonBlockingIMAP_data.clear();
       
   663 
       
   664     // Close the socket
       
   665     socket->close();
       
   666 
       
   667     // Check that it's closed
       
   668     QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
       
   669 
       
   670     delete socket;
       
   671 }
       
   672 
       
   673 void tst_QTcpSocket::nonBlockingIMAP_hostFound()
       
   674 {
       
   675     exitLoop();
       
   676 }
       
   677 
       
   678 void tst_QTcpSocket::nonBlockingIMAP_connected()
       
   679 {
       
   680     exitLoop();
       
   681 }
       
   682 
       
   683 void tst_QTcpSocket::nonBlockingIMAP_readyRead()
       
   684 {
       
   685     while (nonBlockingIMAP_socket->canReadLine())
       
   686         nonBlockingIMAP_data.append(nonBlockingIMAP_socket->readLine());
       
   687 
       
   688     exitLoop();
       
   689 }
       
   690 
       
   691 void tst_QTcpSocket::nonBlockingIMAP_bytesWritten(qint64 written)
       
   692 {
       
   693     nonBlockingIMAP_totalWritten += written;
       
   694     exitLoop();
       
   695 }
       
   696 
       
   697 void tst_QTcpSocket::nonBlockingIMAP_closed()
       
   698 {
       
   699 }
       
   700 
       
   701 //----------------------------------------------------------------------------------
       
   702 
       
   703 void tst_QTcpSocket::delayedClose()
       
   704 {
       
   705     QTcpSocket *socket = newSocket();
       
   706     connect(socket, SIGNAL(connected()), SLOT(nonBlockingIMAP_connected()));
       
   707     connect(socket, SIGNAL(disconnected()), SLOT(exitLoopSlot()));
       
   708 
       
   709     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
   710 
       
   711     enterLoop(30);
       
   712     if (timeout())
       
   713         QFAIL("Timed out");
       
   714 
       
   715     QCOMPARE(socket->state(), QTcpSocket::ConnectedState);
       
   716 
       
   717     QCOMPARE((int) socket->write("1 LOGOUT\r\n", 10), 10);
       
   718 
       
   719     // Add a huge bulk of data to be written after the logout
       
   720     // command. The server will shut down after receiving the LOGOUT,
       
   721     // so this data will not be read. But our close call should
       
   722     // schedule a delayed close because all the data can not be
       
   723     // written in one go.
       
   724     QCOMPARE((int) socket->write(QByteArray(100000, '\n'), 100000), 100000);
       
   725 
       
   726     socket->close();
       
   727 
       
   728     QCOMPARE((int) socket->state(), (int) QTcpSocket::ClosingState);
       
   729 
       
   730     enterLoop(10);
       
   731     if (timeout())
       
   732         QFAIL("Timed out");
       
   733 
       
   734     QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
       
   735 
       
   736     delete socket;
       
   737 }
       
   738 
       
   739 //----------------------------------------------------------------------------------
       
   740 
       
   741 void tst_QTcpSocket::partialRead()
       
   742 {
       
   743     QTcpSocket *socket = newSocket();
       
   744     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
   745     QVERIFY(socket->waitForConnected(10000));
       
   746     QVERIFY(socket->state() == QTcpSocket::ConnectedState);
       
   747     char buf[512];
       
   748 
       
   749 //    QByteArray greeting = "* OK fluke Cyrus IMAP4 v2.2.12 server ready";
       
   750     QByteArray greeting = "* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE";
       
   751 
       
   752     for (int i = 0; i < 10; i += 2) {
       
   753         while (socket->bytesAvailable() < 2)
       
   754             QVERIFY(socket->waitForReadyRead(5000));
       
   755         QVERIFY(socket->read(buf, 2) == 2);
       
   756         buf[2] = '\0';
       
   757         QCOMPARE((char *)buf, greeting.mid(i, 2).data());
       
   758     }
       
   759 
       
   760     delete socket;
       
   761 }
       
   762 
       
   763 //----------------------------------------------------------------------------------
       
   764 
       
   765 void tst_QTcpSocket::unget()
       
   766 {
       
   767     QTcpSocket *socket = newSocket();
       
   768     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
   769     QVERIFY(socket->waitForConnected(10000));
       
   770     QVERIFY(socket->state() == QTcpSocket::ConnectedState);
       
   771     char buf[512];
       
   772 
       
   773 //    QByteArray greeting = "* OK fluke Cyrus IMAP4 v2.2.12 server ready";
       
   774     QByteArray greeting = "* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE";
       
   775 
       
   776     for (int i = 0; i < 10; i += 2) {
       
   777         while (socket->bytesAvailable() < 2)
       
   778             QVERIFY(socket->waitForReadyRead(5000));
       
   779         int bA = socket->bytesAvailable();
       
   780         QVERIFY(socket->read(buf, 2) == 2);
       
   781         buf[2] = '\0';
       
   782         QCOMPARE((char *)buf, greeting.mid(i, 2).data());
       
   783         QCOMPARE((int)socket->bytesAvailable(), bA - 2);
       
   784         socket->ungetChar(buf[1]);
       
   785         socket->ungetChar(buf[0]);
       
   786         QCOMPARE((int)socket->bytesAvailable(), bA);
       
   787         QVERIFY(socket->read(buf, 2) == 2);
       
   788         buf[2] = '\0';
       
   789         QCOMPARE((char *)buf, greeting.mid(i, 2).data());
       
   790     }
       
   791 
       
   792     delete socket;
       
   793 }
       
   794 
       
   795 //----------------------------------------------------------------------------------
       
   796 void tst_QTcpSocket::readRegularFile_readyRead()
       
   797 {
       
   798     exitLoop();
       
   799 }
       
   800 
       
   801 //----------------------------------------------------------------------------------
       
   802 void tst_QTcpSocket::readAllAfterClose()
       
   803 {
       
   804     QTcpSocket *socket = newSocket();
       
   805     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
   806     connect(socket, SIGNAL(readyRead()), SLOT(readRegularFile_readyRead()));
       
   807     enterLoop(10);
       
   808     if (timeout())
       
   809         QFAIL("Network operation timed out");
       
   810 
       
   811     socket->close();
       
   812     QByteArray array = socket->readAll();
       
   813     QCOMPARE(array.size(), 0);
       
   814 
       
   815     delete socket;
       
   816 }
       
   817 
       
   818 //----------------------------------------------------------------------------------
       
   819 void tst_QTcpSocket::openCloseOpenClose()
       
   820 {
       
   821     QTcpSocket *socket = newSocket();
       
   822 
       
   823     for (int i = 0; i < 3; ++i) {
       
   824         QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
       
   825         QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
       
   826         QVERIFY(socket->isSequential());
       
   827         QVERIFY(!socket->isOpen());
       
   828         QVERIFY(socket->socketType() == QTcpSocket::TcpSocket);
       
   829 
       
   830         char c;
       
   831         QTest::ignoreMessage(QtWarningMsg, "QIODevice::getChar: Closed device");
       
   832         QCOMPARE(socket->getChar(&c), false);
       
   833         QCOMPARE((int) socket->bytesAvailable(), 0);
       
   834         QCOMPARE(socket->canReadLine(), false);
       
   835         QCOMPARE(socket->readLine(), QByteArray());
       
   836         QCOMPARE(socket->socketDescriptor(), -1);
       
   837         QCOMPARE((int) socket->localPort(), 0);
       
   838         QVERIFY(socket->localAddress() == QHostAddress());
       
   839         QCOMPARE((int) socket->peerPort(), 0);
       
   840         QVERIFY(socket->peerAddress() == QHostAddress());
       
   841         QCOMPARE(socket->error(), QTcpSocket::UnknownSocketError);
       
   842         QCOMPARE(socket->errorString(), QString("Unknown error"));
       
   843 
       
   844         QVERIFY(socket->state() == QTcpSocket::UnconnectedState);
       
   845 
       
   846         socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
   847         QVERIFY(socket->waitForConnected(10000));
       
   848         socket->close();
       
   849     }
       
   850 
       
   851     delete socket;
       
   852 }
       
   853 
       
   854 //----------------------------------------------------------------------------------
       
   855 void tst_QTcpSocket::connectDisconnectConnectDisconnect()
       
   856 {
       
   857     QTcpSocket *socket = newSocket();
       
   858 
       
   859     for (int i = 0; i < 3; ++i) {
       
   860         QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
       
   861         QVERIFY(socket->socketType() == QTcpSocket::TcpSocket);
       
   862 
       
   863         socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
   864         QVERIFY(socket->waitForReadyRead(10000));
       
   865         QCOMPARE(QString::fromLatin1(socket->read(4)), QString("* OK"));
       
   866 
       
   867         socket->disconnectFromHost();
       
   868         if (socket->state() != QTcpSocket::UnconnectedState)
       
   869             QVERIFY(socket->waitForDisconnected(10000));
       
   870         QCOMPARE(int(socket->openMode()), int(QIODevice::ReadWrite));
       
   871     }
       
   872 
       
   873     delete socket;
       
   874 }
       
   875 
       
   876 //----------------------------------------------------------------------------------
       
   877 void tst_QTcpSocket::disconnectWhileConnecting_data()
       
   878 {
       
   879     QTest::addColumn<QByteArray>("data");
       
   880     QTest::addColumn<bool>("closeDirectly");
       
   881 
       
   882     QTest::newRow("without-data") << QByteArray() << false;
       
   883     QTest::newRow("without-data+close") << QByteArray() << true;
       
   884     QTest::newRow("with-data") << QByteArray("Hello, world!") << false;
       
   885     QTest::newRow("with-data+close") << QByteArray("Hello, world!") << true;
       
   886 
       
   887     QByteArray bigData(1024*1024, '@');
       
   888     QTest::newRow("with-big-data") << bigData << false;
       
   889     QTest::newRow("with-big-data+close") << bigData << true;
       
   890 }
       
   891 
       
   892 void tst_QTcpSocket::disconnectWhileConnecting()
       
   893 {
       
   894     QFETCH(QByteArray, data);
       
   895 
       
   896     QTcpServer server;
       
   897     QVERIFY(server.listen(QHostAddress::LocalHost));
       
   898 
       
   899     // proceed to the connect-write-disconnect
       
   900     QTcpSocket *socket = newSocket();
       
   901     socket->connectToHost("127.0.0.1", server.serverPort());
       
   902     if (!data.isEmpty())
       
   903         socket->write(data);
       
   904     if (socket->state() == QAbstractSocket::ConnectedState)
       
   905         QSKIP("localhost connections are immediate, test case is invalid", SkipSingle);
       
   906 
       
   907     QFETCH(bool, closeDirectly);
       
   908     if (closeDirectly) {
       
   909         socket->close();
       
   910         QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
       
   911     } else {
       
   912         socket->disconnectFromHost();
       
   913     }
       
   914 
       
   915     connect(socket, SIGNAL(disconnected()), SLOT(exitLoopSlot()));
       
   916 #ifndef Q_OS_SYMBIAN
       
   917     enterLoop(10);
       
   918 #else
       
   919     enterLoop(30);
       
   920 #endif
       
   921     QVERIFY2(!timeout(), "Network timeout");
       
   922     QVERIFY(socket->state() == QAbstractSocket::UnconnectedState);
       
   923     if (!closeDirectly) {
       
   924         QCOMPARE(int(socket->openMode()), int(QIODevice::ReadWrite));
       
   925         socket->close();
       
   926     }
       
   927     QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
       
   928 
       
   929     // accept the other side and verify that it was sent properly:
       
   930     QVERIFY(server.hasPendingConnections() || server.waitForNewConnection(0));
       
   931     QTcpSocket *othersocket = server.nextPendingConnection();
       
   932     if (othersocket->state() != QAbstractSocket::UnconnectedState)
       
   933         QVERIFY2(othersocket->waitForDisconnected(10000), "Network timeout");
       
   934     QVERIFY(othersocket->state() == QAbstractSocket::UnconnectedState);
       
   935     QCOMPARE(othersocket->readAll(), data);
       
   936 
       
   937     delete socket;
       
   938     delete othersocket;
       
   939 }
       
   940 
       
   941 //----------------------------------------------------------------------------------
       
   942 class ReceiverThread: public QThread
       
   943 {
       
   944     QTcpServer *server;
       
   945 public:
       
   946     int serverPort;
       
   947     bool ok;
       
   948     QByteArray receivedData;
       
   949     volatile bool quit;
       
   950 
       
   951     ReceiverThread()
       
   952         : server(0), ok(false), quit(false)
       
   953     { }
       
   954 
       
   955     ~ReceiverThread() { /*delete server;*/ terminate(); wait();  }
       
   956 
       
   957     bool listen()
       
   958     {
       
   959         server = new QTcpServer;
       
   960         if (!server->listen(QHostAddress::LocalHost))
       
   961             return false;
       
   962         serverPort = server->serverPort();
       
   963         server->moveToThread(this);
       
   964         return true;
       
   965     }
       
   966 
       
   967 protected:
       
   968     void run()
       
   969     {
       
   970         bool timedOut = false;
       
   971         while (!quit) {
       
   972 #ifndef Q_OS_SYMBIAN
       
   973             if (server->waitForNewConnection(500, &timedOut))
       
   974 #else
       
   975             if (server->waitForNewConnection(5000, &timedOut))
       
   976 #endif
       
   977                 break;
       
   978             if (!timedOut)
       
   979                 return;
       
   980         }
       
   981 
       
   982         QTcpSocket *socket = server->nextPendingConnection();
       
   983         while (!quit) {
       
   984 #ifndef Q_OS_SYMBIAN
       
   985             if (socket->waitForDisconnected(500))
       
   986 #else
       
   987             if (socket->waitForDisconnected(5000))
       
   988 #endif
       
   989                 break;
       
   990             if (socket->error() != QAbstractSocket::SocketTimeoutError)
       
   991                 return;
       
   992         }
       
   993 
       
   994         if (!quit) {
       
   995             receivedData = socket->readAll();
       
   996             ok = true;
       
   997         }
       
   998         delete socket;
       
   999         delete server;
       
  1000         server = 0;
       
  1001     }
       
  1002 };
       
  1003 
       
  1004 void tst_QTcpSocket::disconnectWhileConnectingNoEventLoop_data()
       
  1005 {
       
  1006     disconnectWhileConnecting_data();
       
  1007 }
       
  1008 
       
  1009 void tst_QTcpSocket::disconnectWhileConnectingNoEventLoop()
       
  1010 {
       
  1011     QFETCH(QByteArray, data);
       
  1012 
       
  1013     ReceiverThread thread;
       
  1014     QVERIFY(thread.listen());
       
  1015     thread.start();
       
  1016 
       
  1017     // proceed to the connect-write-disconnect
       
  1018     QTcpSocket *socket = newSocket();
       
  1019     socket->connectToHost("127.0.0.1", thread.serverPort);
       
  1020     if (!data.isEmpty())
       
  1021         socket->write(data);
       
  1022     if (socket->state() == QAbstractSocket::ConnectedState) {
       
  1023         thread.quit = true;
       
  1024         thread.wait();
       
  1025         QSKIP("localhost connections are immediate, test case is invalid", SkipSingle);
       
  1026     }
       
  1027 
       
  1028     QFETCH(bool, closeDirectly);
       
  1029     if (closeDirectly) {
       
  1030         socket->close();
       
  1031         QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
       
  1032     } else {
       
  1033         socket->disconnectFromHost();
       
  1034     }
       
  1035 
       
  1036 #ifndef Q_OS_SYMBIAN
       
  1037     QVERIFY2(socket->waitForDisconnected(10000), "Network timeout");
       
  1038 #else
       
  1039     QVERIFY2(socket->waitForDisconnected(30000), "Network timeout");
       
  1040 #endif
       
  1041     QVERIFY(socket->state() == QAbstractSocket::UnconnectedState);
       
  1042     if (!closeDirectly) {
       
  1043         QCOMPARE(int(socket->openMode()), int(QIODevice::ReadWrite));
       
  1044         socket->close();
       
  1045     }
       
  1046     QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
       
  1047     delete socket;
       
  1048 
       
  1049     // check if the other side received everything ok
       
  1050     QVERIFY(thread.wait(30000));
       
  1051     QVERIFY(thread.ok);
       
  1052     QCOMPARE(thread.receivedData, data);
       
  1053 }
       
  1054 
       
  1055 //----------------------------------------------------------------------------------
       
  1056 void tst_QTcpSocket::disconnectWhileLookingUp_data()
       
  1057 {
       
  1058     QTest::addColumn<bool>("doClose");
       
  1059 
       
  1060     QTest::newRow("disconnect") << false;
       
  1061     QTest::newRow("close") << true;
       
  1062 }
       
  1063 
       
  1064 void tst_QTcpSocket::disconnectWhileLookingUp()
       
  1065 {
       
  1066     QFETCH_GLOBAL(bool, setProxy);
       
  1067     if (setProxy)
       
  1068         return;                 // we let the proxies do the lookup now
       
  1069 
       
  1070     // just connect and disconnect, then make sure nothing weird happened
       
  1071     QTcpSocket *socket = newSocket();
       
  1072     socket->connectToHost(QtNetworkSettings::serverName(), 21);
       
  1073     QVERIFY(socket->state() == QAbstractSocket::HostLookupState);
       
  1074 
       
  1075     QFETCH(bool, doClose);
       
  1076     if (doClose) {
       
  1077         socket->close();
       
  1078         QVERIFY(socket->openMode() == QIODevice::NotOpen);
       
  1079     } else {
       
  1080         socket->disconnectFromHost();
       
  1081         QVERIFY(socket->openMode() == QIODevice::ReadWrite);
       
  1082     }
       
  1083 
       
  1084     // let anything queued happen
       
  1085     QEventLoop loop;
       
  1086 #ifndef Q_OS_SYMBIAN
       
  1087     QTimer::singleShot(50, &loop, SLOT(quit()));
       
  1088 #else
       
  1089     QTimer::singleShot(5000, &loop, SLOT(quit()));
       
  1090 #endif
       
  1091     loop.exec();
       
  1092 
       
  1093     // recheck
       
  1094     if (doClose) {
       
  1095         QVERIFY(socket->openMode() == QIODevice::NotOpen);
       
  1096     } else {
       
  1097         QVERIFY(socket->openMode() == QIODevice::ReadWrite);
       
  1098     }
       
  1099 
       
  1100     QVERIFY(socket->state() == QAbstractSocket::UnconnectedState);
       
  1101 }
       
  1102 
       
  1103 //----------------------------------------------------------------------------------
       
  1104 void tst_QTcpSocket::downloadBigFile()
       
  1105 {
       
  1106     if (tmpSocket)
       
  1107         delete tmpSocket;
       
  1108     tmpSocket = newSocket();
       
  1109 
       
  1110     connect(tmpSocket, SIGNAL(connected()), SLOT(exitLoopSlot()));
       
  1111     connect(tmpSocket, SIGNAL(readyRead()), SLOT(downloadBigFileSlot()));
       
  1112 
       
  1113     tmpSocket->connectToHost(QtNetworkSettings::serverName(), 80);
       
  1114 
       
  1115     enterLoop(30);
       
  1116     if (timeout()) {
       
  1117         delete tmpSocket;
       
  1118         tmpSocket = 0;
       
  1119         QFAIL("Network operation timed out");
       
  1120     }
       
  1121 
       
  1122     QByteArray hostName = QtNetworkSettings::serverName().toLatin1();
       
  1123     QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState);
       
  1124     QVERIFY(tmpSocket->write("GET /mediumfile HTTP/1.0\r\n") > 0);
       
  1125     QVERIFY(tmpSocket->write("HOST: ") > 0);
       
  1126     QVERIFY(tmpSocket->write(hostName.data()) > 0);
       
  1127     QVERIFY(tmpSocket->write("\r\n") > 0);
       
  1128     QVERIFY(tmpSocket->write("\r\n") > 0);
       
  1129 
       
  1130     bytesAvailable = 0;
       
  1131     expectedLength = 0;
       
  1132     readingBody = false;
       
  1133 
       
  1134     QTime stopWatch;
       
  1135     stopWatch.start();
       
  1136 
       
  1137     enterLoop(600);
       
  1138     if (timeout()) {
       
  1139         delete tmpSocket;
       
  1140         tmpSocket = 0;
       
  1141         if (bytesAvailable > 0)
       
  1142             qDebug("Slow Connection, only downloaded %ld of %d", long(bytesAvailable), 10000281);
       
  1143         QFAIL("Network operation timed out");
       
  1144     }
       
  1145 
       
  1146     QCOMPARE(bytesAvailable, expectedLength);
       
  1147 
       
  1148     qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
       
  1149            bytesAvailable / (1024.0 * 1024.0),
       
  1150            stopWatch.elapsed() / 1024.0,
       
  1151            (bytesAvailable / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));
       
  1152 
       
  1153     delete tmpSocket;
       
  1154     tmpSocket = 0;
       
  1155 }
       
  1156 
       
  1157 //----------------------------------------------------------------------------------
       
  1158 void tst_QTcpSocket::exitLoopSlot()
       
  1159 {
       
  1160     exitLoop();
       
  1161 }
       
  1162 
       
  1163 //----------------------------------------------------------------------------------
       
  1164 void tst_QTcpSocket::downloadBigFileSlot()
       
  1165 {
       
  1166     if (!readingBody) {
       
  1167         while (tmpSocket->canReadLine()) {
       
  1168             QByteArray array = tmpSocket->readLine();
       
  1169             if (array.startsWith("Content-Length"))
       
  1170                 expectedLength = array.simplified().split(' ').at(1).toInt();
       
  1171             if (array == "\r\n") {
       
  1172                 readingBody = true;
       
  1173                 break;
       
  1174             }
       
  1175         }
       
  1176     }
       
  1177     if (readingBody) {
       
  1178         bytesAvailable += tmpSocket->readAll().size();
       
  1179         if (bytesAvailable == expectedLength)
       
  1180             exitLoop();
       
  1181     }
       
  1182 }
       
  1183 
       
  1184 //----------------------------------------------------------------------------------
       
  1185 void tst_QTcpSocket::readLine()
       
  1186 {
       
  1187     QTcpSocket *socket = newSocket();
       
  1188     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
  1189     QVERIFY(socket->waitForConnected(5000));
       
  1190 
       
  1191     while (!socket->canReadLine())
       
  1192         QVERIFY(socket->waitForReadyRead(10000));
       
  1193 
       
  1194     char buffer[1024];
       
  1195     int expectedReplySize = QtNetworkSettings::expectedReplyIMAP().size();
       
  1196     Q_ASSERT(expectedReplySize >= 3);
       
  1197     QCOMPARE(socket->readLine(buffer, sizeof(buffer)), qint64(expectedReplySize));
       
  1198 
       
  1199     QCOMPARE((int) buffer[expectedReplySize-2], (int) '\r');
       
  1200     QCOMPARE((int) buffer[expectedReplySize-1], (int) '\n');
       
  1201     QCOMPARE((int) buffer[expectedReplySize], (int) '\0');
       
  1202 
       
  1203     QCOMPARE(socket->write("1 NOOP\r\n"), qint64(8));
       
  1204 
       
  1205     while (socket->bytesAvailable() < 10)
       
  1206         QVERIFY(socket->waitForReadyRead(10000));
       
  1207 
       
  1208     QCOMPARE(socket->readLine(buffer, 11), qint64(10));
       
  1209     QCOMPARE((const char *)buffer, "1 OK Compl");
       
  1210 
       
  1211     while (socket->bytesAvailable() < 6)
       
  1212         QVERIFY(socket->waitForReadyRead(10000));
       
  1213 
       
  1214     QCOMPARE(socket->readLine(buffer, 11), qint64(6));
       
  1215     QCOMPARE((const char *)buffer, "eted\r\n");
       
  1216 
       
  1217     QVERIFY(!socket->waitForReadyRead(100));
       
  1218     QCOMPARE(socket->readLine(buffer, sizeof(buffer)), qint64(0));
       
  1219     QVERIFY(socket->error() == QAbstractSocket::SocketTimeoutError
       
  1220             || socket->error() == QAbstractSocket::RemoteHostClosedError);
       
  1221     QCOMPARE(socket->bytesAvailable(), qint64(0));
       
  1222 
       
  1223     socket->close();
       
  1224     QCOMPARE(socket->readLine(buffer, sizeof(buffer)), qint64(-1));
       
  1225 
       
  1226     delete socket;
       
  1227 }
       
  1228 
       
  1229 //----------------------------------------------------------------------------------
       
  1230 void tst_QTcpSocket::readLineString()
       
  1231 {
       
  1232     QTcpSocket *socket = newSocket();
       
  1233 //    QByteArray expected("* OK fluke Cyrus IMAP4 v2.2.12 server ready\r\n");
       
  1234     QByteArray expected("* OK [CAPABILITY IMAP4 IMAP4rev1 LITERAL+ ID STARTTLS LOGINDISABLED] qt-test-server.qt-test-net Cyrus IMAP4 v2.3.11-Mandriva-RPM-2.3.11-6mdv2008.1 server ready\r\n");
       
  1235     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
  1236     QVERIFY(socket->waitForReadyRead(10000));
       
  1237 
       
  1238     QByteArray arr = socket->readLine();
       
  1239     QCOMPARE(arr, QtNetworkSettings::expectedReplyIMAP());
       
  1240 
       
  1241     delete socket;
       
  1242 }
       
  1243 
       
  1244 //----------------------------------------------------------------------------------
       
  1245 void tst_QTcpSocket::readChunks()
       
  1246 {
       
  1247     QTcpSocket *socket = newSocket();
       
  1248     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
  1249     QVERIFY(socket->waitForConnected(10000));
       
  1250     QVERIFY(socket->waitForReadyRead(5000));
       
  1251 
       
  1252     char buf[4096];
       
  1253     memset(buf, '@', sizeof(buf));
       
  1254     qint64 dataLength = socket->read(buf, sizeof(buf));
       
  1255     QVERIFY(dataLength > 0);
       
  1256 
       
  1257     QCOMPARE(buf[dataLength - 2], '\r');
       
  1258     QCOMPARE(buf[dataLength - 1], '\n');
       
  1259     QCOMPARE(buf[dataLength], '@');
       
  1260 
       
  1261     delete socket;
       
  1262 }
       
  1263 
       
  1264 //----------------------------------------------------------------------------------
       
  1265 void tst_QTcpSocket::waitForBytesWritten()
       
  1266 {
       
  1267     QTcpSocket *socket = newSocket();
       
  1268     socket->connectToHost(QtNetworkSettings::serverName(), 22);
       
  1269     QVERIFY(socket->waitForConnected(10000));
       
  1270 
       
  1271     socket->write(QByteArray(10000, '@'));
       
  1272     qint64 toWrite = socket->bytesToWrite();
       
  1273     QVERIFY(socket->waitForBytesWritten(5000));
       
  1274     QVERIFY(toWrite > socket->bytesToWrite());
       
  1275 
       
  1276     delete socket;
       
  1277 }
       
  1278 
       
  1279 //----------------------------------------------------------------------------------
       
  1280 void tst_QTcpSocket::waitForReadyRead()
       
  1281 {
       
  1282     QTcpSocket *socket = newSocket();
       
  1283     socket->connectToHost(QtNetworkSettings::serverName(), 22);
       
  1284     socket->waitForReadyRead(0);
       
  1285     delete socket;
       
  1286 }
       
  1287 
       
  1288 //----------------------------------------------------------------------------------
       
  1289 void tst_QTcpSocket::flush()
       
  1290 {
       
  1291     QTcpSocket *socket = newSocket();
       
  1292     socket->flush();
       
  1293 
       
  1294     connect(socket, SIGNAL(connected()), SLOT(exitLoopSlot()));
       
  1295     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
  1296     enterLoop(5000);
       
  1297     QVERIFY(socket->isOpen());
       
  1298 
       
  1299     socket->write("1 LOGOUT\r\n");
       
  1300     QCOMPARE(socket->bytesToWrite(), qint64(10));
       
  1301     socket->flush();
       
  1302     QCOMPARE(socket->bytesToWrite(), qint64(0));
       
  1303     socket->close();
       
  1304 
       
  1305     delete socket;
       
  1306 }
       
  1307 
       
  1308 //----------------------------------------------------------------------------------
       
  1309 void tst_QTcpSocket::synchronousApi()
       
  1310 {
       
  1311     QTcpSocket *ftpSocket = newSocket();
       
  1312     ftpSocket->connectToHost(QtNetworkSettings::serverName(), 21);
       
  1313     ftpSocket->write("QUIT\r\n");
       
  1314     QVERIFY(ftpSocket->waitForDisconnected(10000));
       
  1315     QVERIFY(ftpSocket->bytesAvailable() > 0);
       
  1316     QByteArray arr = ftpSocket->readAll();
       
  1317     QVERIFY(arr.size() > 0);
       
  1318     delete ftpSocket;
       
  1319 }
       
  1320 
       
  1321 //----------------------------------------------------------------------------------
       
  1322 void tst_QTcpSocket::dontCloseOnTimeout()
       
  1323 {
       
  1324     QTcpServer server;
       
  1325 #ifdef TEST_QNETWORK_PROXY
       
  1326     server.setProxy(QNetworkProxy(QNetworkProxy::NoProxy));
       
  1327 #endif
       
  1328     QVERIFY(server.listen());
       
  1329 
       
  1330     QHostAddress serverAddress = QHostAddress::LocalHost;
       
  1331     if (!(server.serverAddress() == QHostAddress::Any))
       
  1332         serverAddress = server.serverAddress();
       
  1333 
       
  1334     QTcpSocket *socket = newSocket();
       
  1335     socket->connectToHost(serverAddress, server.serverPort());
       
  1336 #ifndef Q_OS_SYMBIAN
       
  1337     QVERIFY(!socket->waitForReadyRead(100));
       
  1338 #else
       
  1339     QVERIFY(!socket->waitForReadyRead(5000));
       
  1340 #endif
       
  1341     QCOMPARE(socket->error(), QTcpSocket::SocketTimeoutError);
       
  1342     QVERIFY(socket->isOpen());
       
  1343 
       
  1344 #ifndef Q_OS_SYMBIAN
       
  1345     QVERIFY(!socket->waitForDisconnected(100));
       
  1346 #else
       
  1347     QVERIFY(!socket->waitForDisconnected(5000));
       
  1348 #endif
       
  1349     QCOMPARE(socket->error(), QTcpSocket::SocketTimeoutError);
       
  1350     QVERIFY(socket->isOpen());
       
  1351 
       
  1352     delete socket;
       
  1353 }
       
  1354 
       
  1355 //----------------------------------------------------------------------------------
       
  1356 void tst_QTcpSocket::recursiveReadyRead()
       
  1357 {
       
  1358     QTcpSocket *smtp = newSocket();
       
  1359     connect(smtp, SIGNAL(connected()), SLOT(exitLoopSlot()));
       
  1360     connect(smtp, SIGNAL(readyRead()), SLOT(recursiveReadyReadSlot()));
       
  1361     tmpSocket = smtp;
       
  1362 
       
  1363     QSignalSpy spy(smtp, SIGNAL(readyRead()));
       
  1364 
       
  1365     smtp->connectToHost("smtp.trolltech.com", 25);
       
  1366     enterLoop(30);
       
  1367     QVERIFY2(!timeout(),
       
  1368             "Timed out when connecting to smtp.trolltech.com:25");
       
  1369 
       
  1370     enterLoop(30);
       
  1371     QVERIFY2(!timeout(),
       
  1372             "Timed out when waiting for the readyRead() signal");
       
  1373 
       
  1374     QCOMPARE(spy.count(), 1);
       
  1375 
       
  1376     delete smtp;
       
  1377 }
       
  1378 
       
  1379 void tst_QTcpSocket::recursiveReadyReadSlot()
       
  1380 {
       
  1381     // make sure the server spits out more data
       
  1382     tmpSocket->write("NOOP\r\n");
       
  1383     tmpSocket->flush();
       
  1384 
       
  1385     // indiscriminately enter the event loop and start processing
       
  1386     // events again. but oops! future socket notifications will cause
       
  1387     // undesired recursive behavior. Unless QTcpSocket is smart, which
       
  1388     // it of course is. :-)
       
  1389     QEventLoop loop;
       
  1390     for (int i = 0; i < 100; ++i)
       
  1391         loop.processEvents();
       
  1392 
       
  1393     // all we really wanted to do was process some events, then exit
       
  1394     // the loop
       
  1395     exitLoop();
       
  1396 }
       
  1397 
       
  1398 //----------------------------------------------------------------------------------
       
  1399 void tst_QTcpSocket::atEnd()
       
  1400 {
       
  1401     QTcpSocket *socket = newSocket();
       
  1402     socket->connectToHost(QtNetworkSettings::serverName(), 21);
       
  1403 
       
  1404     QVERIFY(socket->waitForReadyRead(15000));
       
  1405     QTextStream stream(socket);
       
  1406     QVERIFY(!stream.atEnd());
       
  1407     QString greeting = stream.readLine();
       
  1408     QVERIFY(stream.atEnd());
       
  1409 //    QCOMPARE(greeting, QString("220 (vsFTPd 2.0.4)"));
       
  1410     QCOMPARE(greeting, QString("220 (vsFTPd 2.0.5)"));
       
  1411 
       
  1412     delete socket;
       
  1413 }
       
  1414 
       
  1415 class TestThread : public QThread
       
  1416 {
       
  1417     Q_OBJECT
       
  1418 
       
  1419 public:
       
  1420     inline QByteArray data() const
       
  1421     {
       
  1422         return socketData;
       
  1423     }
       
  1424 
       
  1425 protected:
       
  1426     inline void run()
       
  1427     {
       
  1428 #ifndef QT_NO_OPENSSL
       
  1429         QFETCH_GLOBAL(bool, ssl);
       
  1430         if (ssl)
       
  1431             socket = new QSslSocket;
       
  1432         else
       
  1433 #endif
       
  1434         socket = new QTcpSocket;
       
  1435         connect(socket, SIGNAL(readyRead()), this, SLOT(getData()), Qt::DirectConnection);
       
  1436         connect(socket, SIGNAL(disconnected()), this, SLOT(closed()), Qt::DirectConnection);
       
  1437         connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
       
  1438                 SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), Qt::DirectConnection);
       
  1439 
       
  1440         socket->connectToHost(QtNetworkSettings::serverName(), 21);
       
  1441         socket->write("QUIT\r\n");
       
  1442         exec();
       
  1443 
       
  1444         delete socket;
       
  1445     }
       
  1446 
       
  1447 private slots:
       
  1448     inline void getData()
       
  1449     {
       
  1450         socketData += socket->readAll();
       
  1451     }
       
  1452 
       
  1453     inline void closed()
       
  1454     {
       
  1455         quit();
       
  1456     }
       
  1457     inline void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
       
  1458     {
       
  1459         auth->setUser("qsockstest");
       
  1460         auth->setPassword("password");
       
  1461     }
       
  1462 private:
       
  1463     int exitCode;
       
  1464     QTcpSocket *socket;
       
  1465     QByteArray socketData;
       
  1466 };
       
  1467 
       
  1468 //----------------------------------------------------------------------------------
       
  1469 void tst_QTcpSocket::socketInAThread()
       
  1470 {
       
  1471     for (int i = 0; i < 3; ++i) {
       
  1472         TestThread thread;
       
  1473         thread.start();
       
  1474         QVERIFY(thread.wait(15000));
       
  1475         QCOMPARE(thread.data(), QtNetworkSettings::expectedReplyFtp());
       
  1476     }
       
  1477 }
       
  1478 
       
  1479 //----------------------------------------------------------------------------------
       
  1480 void tst_QTcpSocket::socketsInThreads()
       
  1481 {
       
  1482     for (int i = 0; i < 3; ++i) {
       
  1483         TestThread thread1;
       
  1484         TestThread thread2;
       
  1485         TestThread thread3;
       
  1486 
       
  1487         thread1.start();
       
  1488         thread2.start();
       
  1489         thread3.start();
       
  1490 
       
  1491         QVERIFY(thread2.wait(15000));
       
  1492         QVERIFY(thread3.wait(15000));
       
  1493         QVERIFY(thread1.wait(15000));
       
  1494 
       
  1495         QCOMPARE(thread1.data(),QtNetworkSettings::expectedReplyFtp());
       
  1496         QCOMPARE(thread2.data(),QtNetworkSettings::expectedReplyFtp());
       
  1497         QCOMPARE(thread3.data(),QtNetworkSettings::expectedReplyFtp());
       
  1498     }
       
  1499 }
       
  1500 
       
  1501 //----------------------------------------------------------------------------------
       
  1502 void tst_QTcpSocket::waitForReadyReadInASlot()
       
  1503 {
       
  1504     QTcpSocket *socket = newSocket();
       
  1505     tmpSocket = socket;
       
  1506     connect(socket, SIGNAL(connected()), this, SLOT(waitForReadyReadInASlotSlot()));
       
  1507 
       
  1508     socket->connectToHost(QtNetworkSettings::serverName(), 80);
       
  1509     socket->write("GET / HTTP/1.0\r\n\r\n");
       
  1510 
       
  1511     enterLoop(30);
       
  1512     QVERIFY(!timeout());
       
  1513 
       
  1514     delete socket;
       
  1515 }
       
  1516 
       
  1517 void tst_QTcpSocket::waitForReadyReadInASlotSlot()
       
  1518 {
       
  1519     QVERIFY(tmpSocket->waitForReadyRead(10000));
       
  1520     exitLoop();
       
  1521 }
       
  1522 
       
  1523 class RemoteCloseErrorServer : public QTcpServer
       
  1524 {
       
  1525     Q_OBJECT
       
  1526 public:
       
  1527     RemoteCloseErrorServer()
       
  1528     {
       
  1529         connect(this, SIGNAL(newConnection()),
       
  1530                 this, SLOT(getConnection()));
       
  1531     }
       
  1532 
       
  1533 private slots:
       
  1534     void getConnection()
       
  1535     {
       
  1536         tst_QTcpSocket::exitLoop();
       
  1537     }
       
  1538 };
       
  1539 
       
  1540 //----------------------------------------------------------------------------------
       
  1541 void tst_QTcpSocket::remoteCloseError()
       
  1542 {
       
  1543     RemoteCloseErrorServer server;
       
  1544     QVERIFY(server.listen(QHostAddress::LocalHost));
       
  1545 
       
  1546     QCoreApplication::instance()->processEvents();
       
  1547 
       
  1548     QTcpSocket *clientSocket = newSocket();
       
  1549     connect(clientSocket, SIGNAL(readyRead()), this, SLOT(exitLoopSlot()));
       
  1550 
       
  1551     clientSocket->connectToHost(server.serverAddress(), server.serverPort());
       
  1552 
       
  1553     enterLoop(30);
       
  1554     QVERIFY(!timeout());
       
  1555 
       
  1556     QVERIFY(server.hasPendingConnections());
       
  1557     QTcpSocket *serverSocket = server.nextPendingConnection();
       
  1558     connect(clientSocket, SIGNAL(disconnected()), this, SLOT(exitLoopSlot()));
       
  1559 
       
  1560     serverSocket->write("Hello");
       
  1561 
       
  1562     enterLoop(30);
       
  1563     QVERIFY(!timeout());
       
  1564 
       
  1565     QCOMPARE(clientSocket->bytesAvailable(), qint64(5));
       
  1566 
       
  1567     qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
       
  1568     QSignalSpy errorSpy(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)));
       
  1569     QSignalSpy disconnectedSpy(clientSocket, SIGNAL(disconnected()));
       
  1570 
       
  1571     clientSocket->write("World");
       
  1572     serverSocket->disconnectFromHost();
       
  1573 
       
  1574     tmpSocket = clientSocket;
       
  1575     connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
       
  1576             this, SLOT(remoteCloseErrorSlot()));
       
  1577 
       
  1578     enterLoop(30);
       
  1579     QVERIFY(!timeout());
       
  1580 
       
  1581     QCOMPARE(disconnectedSpy.count(), 1);
       
  1582     QCOMPARE(errorSpy.count(), 1);
       
  1583     QCOMPARE(clientSocket->error(), QAbstractSocket::RemoteHostClosedError);
       
  1584 
       
  1585     delete serverSocket;
       
  1586 
       
  1587     clientSocket->connectToHost(server.serverAddress(), server.serverPort());
       
  1588 
       
  1589     enterLoop(30);
       
  1590     QVERIFY(!timeout());
       
  1591 
       
  1592     QVERIFY(server.hasPendingConnections());
       
  1593     serverSocket = server.nextPendingConnection();
       
  1594     serverSocket->disconnectFromHost();
       
  1595 
       
  1596     enterLoop(30);
       
  1597     QVERIFY(!timeout());
       
  1598 
       
  1599     QCOMPARE(clientSocket->state(), QAbstractSocket::UnconnectedState);
       
  1600 
       
  1601     delete clientSocket;
       
  1602 }
       
  1603 
       
  1604 void tst_QTcpSocket::remoteCloseErrorSlot()
       
  1605 {
       
  1606     QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState);
       
  1607     static_cast<QTcpSocket *>(sender())->close();
       
  1608 }
       
  1609 
       
  1610 void tst_QTcpSocket::messageBoxSlot()
       
  1611 {
       
  1612 #if !defined(Q_OS_VXWORKS) // no gui
       
  1613     QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
       
  1614     socket->deleteLater();
       
  1615     QMessageBox box;
       
  1616     QTimer::singleShot(100, &box, SLOT(close()));
       
  1617 
       
  1618     // This should not delete the socket
       
  1619     box.exec();
       
  1620 
       
  1621     // Fire a non-0 singleshot to leave time for the delete
       
  1622     QTimer::singleShot(250, this, SLOT(exitLoopSlot()));
       
  1623 #endif
       
  1624 }
       
  1625 //----------------------------------------------------------------------------------
       
  1626 void tst_QTcpSocket::openMessageBoxInErrorSlot()
       
  1627 {
       
  1628 #if defined(Q_OS_VXWORKS) // no gui
       
  1629     QSKIP("no default gui available on VxWorks", SkipAll);
       
  1630 #else
       
  1631     QTcpSocket *socket = newSocket();
       
  1632     QPointer<QTcpSocket> p(socket);
       
  1633     connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(messageBoxSlot()));
       
  1634 
       
  1635     socket->connectToHost("hostnotfoundhostnotfound.troll.no", 9999); // Host not found, fyi
       
  1636     enterLoop(30);
       
  1637     QVERIFY(!p);
       
  1638 #endif
       
  1639 }
       
  1640 
       
  1641 //----------------------------------------------------------------------------------
       
  1642 #ifndef Q_OS_WIN
       
  1643 void tst_QTcpSocket::connectToLocalHostNoService()
       
  1644 {
       
  1645     // This test was created after we received a report that claimed
       
  1646     // QTcpSocket would crash if trying to connect to "localhost" on a random
       
  1647     // port with no service listening.
       
  1648     QTcpSocket *socket = newSocket();
       
  1649     socket->connectToHost("localhost", 31415); // no service running here, one suspects
       
  1650 
       
  1651     while(socket->state() == QTcpSocket::HostLookupState || socket->state() == QTcpSocket::ConnectingState) {
       
  1652         QTest::qWait(100);
       
  1653     }
       
  1654     QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
       
  1655     delete socket;
       
  1656 }
       
  1657 #endif
       
  1658 
       
  1659 //----------------------------------------------------------------------------------
       
  1660 void tst_QTcpSocket::waitForConnectedInHostLookupSlot()
       
  1661 {
       
  1662     // This test tries to reproduce the problem where waitForConnected() is
       
  1663     // called at a point where the host lookup is already done. QTcpSocket
       
  1664     // will try to abort the "pending lookup", but since it's already done and
       
  1665     // the queued signal is already underway, we will receive the signal after
       
  1666     // waitForConnected() has returned, and control goes back to the event
       
  1667     // loop. When the signal has been received, the connection is torn down,
       
  1668     // then reopened. Yikes. If we reproduce this by calling
       
  1669     // waitForConnected() inside hostLookupSlot(), it will even crash.
       
  1670     tmpSocket = newSocket();
       
  1671     QEventLoop loop;
       
  1672     connect(tmpSocket, SIGNAL(connected()), &loop, SLOT(quit()));
       
  1673     QTimer timer;
       
  1674     connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
       
  1675     QSignalSpy timerSpy(&timer, SIGNAL(timeout()));
       
  1676     timer.start(15000);
       
  1677 
       
  1678     connect(tmpSocket, SIGNAL(hostFound()), this, SLOT(hostLookupSlot()));
       
  1679     tmpSocket->connectToHost(QtNetworkSettings::serverName(), 143);
       
  1680 
       
  1681     loop.exec();
       
  1682     QCOMPARE(timerSpy.count(), 0);
       
  1683 
       
  1684     delete tmpSocket;
       
  1685 }
       
  1686 
       
  1687 void tst_QTcpSocket::hostLookupSlot()
       
  1688 {
       
  1689     // This will fail to cancel the pending signal
       
  1690     QVERIFY(tmpSocket->waitForConnected(10000));
       
  1691 }
       
  1692 
       
  1693 class Foo : public QObject
       
  1694 {
       
  1695     Q_OBJECT
       
  1696     QTcpSocket *sock;
       
  1697 public:
       
  1698     bool attemptedToConnect;
       
  1699     bool networkTimeout;
       
  1700     int count;
       
  1701 
       
  1702     inline Foo(QObject *parent = 0) : QObject(parent)
       
  1703     {
       
  1704         attemptedToConnect = false;
       
  1705         networkTimeout = false;
       
  1706         count = 0;
       
  1707 #ifndef QT_NO_OPENSSL
       
  1708         QFETCH_GLOBAL(bool, ssl);
       
  1709         if (ssl)
       
  1710             sock = new QSslSocket;
       
  1711         else
       
  1712 #endif
       
  1713         sock = new QTcpSocket;
       
  1714         connect(sock, SIGNAL(connected()), this, SLOT(connectedToIt()));
       
  1715         connect(sock, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
       
  1716                 SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
       
  1717     }
       
  1718 
       
  1719     inline ~Foo()
       
  1720     {
       
  1721         delete sock;
       
  1722     }
       
  1723 
       
  1724 public slots:
       
  1725     inline void connectedToIt()
       
  1726     { count++; }
       
  1727 
       
  1728     inline void doIt()
       
  1729     {
       
  1730         attemptedToConnect = true;
       
  1731         sock->connectToHost(QtNetworkSettings::serverName(), 80);
       
  1732 
       
  1733 #ifdef Q_OS_MAC
       
  1734         pthread_yield_np();
       
  1735 #elif defined Q_OS_LINUX
       
  1736         pthread_yield();
       
  1737 #endif
       
  1738         if (!sock->waitForConnected()) {
       
  1739             networkTimeout = true;
       
  1740         }
       
  1741         tst_QTcpSocket::exitLoop();
       
  1742     }
       
  1743 
       
  1744     inline void exitLoop()
       
  1745     {
       
  1746         tst_QTcpSocket::exitLoop();
       
  1747     }
       
  1748 
       
  1749     inline void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
       
  1750     {
       
  1751         auth->setUser("qsockstest");
       
  1752         auth->setPassword("password");
       
  1753     }
       
  1754 };
       
  1755 
       
  1756 //----------------------------------------------------------------------------------
       
  1757 void tst_QTcpSocket::waitForConnectedInHostLookupSlot2()
       
  1758 {
       
  1759 #if defined(Q_OS_WIN) || defined(Q_OS_VXWORKS)
       
  1760     QSKIP("waitForConnectedInHostLookupSlot2 is not run on Windows and VxWorks", SkipAll);
       
  1761 #else
       
  1762 
       
  1763     Foo foo;
       
  1764     QPushButton top("Go", 0);
       
  1765     top.show();
       
  1766     connect(&top, SIGNAL(clicked()), &foo, SLOT(doIt()));
       
  1767 
       
  1768     QTimer::singleShot(100, &top, SLOT(animateClick()));
       
  1769     QTimer::singleShot(5000, &foo, SLOT(exitLoop()));
       
  1770 
       
  1771     enterLoop(30);
       
  1772     if (timeout() || foo.networkTimeout)
       
  1773         QFAIL("Network timeout");
       
  1774 
       
  1775     QVERIFY(foo.attemptedToConnect);
       
  1776     QCOMPARE(foo.count, 1);
       
  1777 #endif
       
  1778 }
       
  1779 
       
  1780 //----------------------------------------------------------------------------------
       
  1781 void tst_QTcpSocket::readyReadSignalsAfterWaitForReadyRead()
       
  1782 {
       
  1783     QTcpSocket *socket = newSocket();
       
  1784 
       
  1785     QSignalSpy readyReadSpy(socket, SIGNAL(readyRead()));
       
  1786 
       
  1787     // Connect
       
  1788     socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
  1789 
       
  1790     // Wait for the read
       
  1791     QVERIFY(socket->waitForReadyRead(10000));
       
  1792 
       
  1793     QCOMPARE(readyReadSpy.count(), 1);
       
  1794 
       
  1795     QString s = socket->readLine();
       
  1796 #ifdef TEST_QNETWORK_PROXY
       
  1797     QNetworkProxy::ProxyType proxyType = QNetworkProxy::applicationProxy().type();
       
  1798 #endif
       
  1799     QCOMPARE(s.toLatin1().constData(), QtNetworkSettings::expectedReplyIMAP().constData());
       
  1800     QCOMPARE(socket->bytesAvailable(), qint64(0));
       
  1801 
       
  1802     QCoreApplication::instance()->processEvents();
       
  1803     QCOMPARE(socket->bytesAvailable(), qint64(0));
       
  1804     QCOMPARE(readyReadSpy.count(), 1);
       
  1805 
       
  1806     delete socket;
       
  1807 }
       
  1808 
       
  1809 class TestThread2 : public QThread
       
  1810 {
       
  1811     Q_OBJECT
       
  1812 public:
       
  1813     void run()
       
  1814     {
       
  1815         QFile fileWriter("fifo");
       
  1816         QVERIFY(fileWriter.open(QFile::WriteOnly));
       
  1817         QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
       
  1818         QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
       
  1819         QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
       
  1820         QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
       
  1821     }
       
  1822 };
       
  1823 
       
  1824 //----------------------------------------------------------------------------------
       
  1825 #ifdef Q_OS_LINUX
       
  1826 void tst_QTcpSocket::linuxKernelBugLocalSocket()
       
  1827 {
       
  1828     QFile::remove("fifo");
       
  1829     mkfifo("fifo", 0666);
       
  1830 
       
  1831     TestThread2 test;
       
  1832     test.start();
       
  1833 
       
  1834     QFile fileReader("fifo");
       
  1835     QVERIFY(fileReader.open(QFile::ReadOnly));
       
  1836 
       
  1837     test.wait();
       
  1838 
       
  1839     QTcpSocket *socket = newSocket();
       
  1840     socket->setSocketDescriptor(fileReader.handle());
       
  1841     QVERIFY(socket->waitForReadyRead(5000));
       
  1842     QCOMPARE(socket->bytesAvailable(), qint64(128));
       
  1843 
       
  1844     QFile::remove("fifo");
       
  1845 
       
  1846     delete socket;
       
  1847 }
       
  1848 #endif
       
  1849 
       
  1850 //----------------------------------------------------------------------------------
       
  1851 void tst_QTcpSocket::abortiveClose()
       
  1852 {
       
  1853     QTcpServer server;
       
  1854     QVERIFY(server.listen(QHostAddress::LocalHost));
       
  1855     connect(&server, SIGNAL(newConnection()), this, SLOT(exitLoopSlot()));
       
  1856 
       
  1857     QTcpSocket *clientSocket = newSocket();
       
  1858     clientSocket->connectToHost(server.serverAddress(), server.serverPort());
       
  1859 
       
  1860     enterLoop(10);
       
  1861     QVERIFY(server.hasPendingConnections());
       
  1862 
       
  1863     QVERIFY(tmpSocket = server.nextPendingConnection());
       
  1864 
       
  1865     qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
       
  1866     QSignalSpy readyReadSpy(clientSocket, SIGNAL(readyRead()));
       
  1867     QSignalSpy errorSpy(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)));
       
  1868 
       
  1869     connect(clientSocket, SIGNAL(disconnected()), this, SLOT(exitLoopSlot()));
       
  1870     QTimer::singleShot(0, this, SLOT(abortiveClose_abortSlot()));
       
  1871 
       
  1872     enterLoop(5);
       
  1873 
       
  1874     QCOMPARE(readyReadSpy.count(), 0);
       
  1875     QCOMPARE(errorSpy.count(), 1);
       
  1876 
       
  1877     QCOMPARE(*static_cast<const int *>(errorSpy.at(0).at(0).constData()),
       
  1878              int(QAbstractSocket::RemoteHostClosedError));
       
  1879 
       
  1880     delete clientSocket;
       
  1881 }
       
  1882 
       
  1883 void tst_QTcpSocket::abortiveClose_abortSlot()
       
  1884 {
       
  1885     tmpSocket->abort();
       
  1886 }
       
  1887 
       
  1888 //----------------------------------------------------------------------------------
       
  1889 void tst_QTcpSocket::localAddressEmptyOnBSD()
       
  1890 {
       
  1891     QTcpServer server;
       
  1892     QVERIFY(server.listen(QHostAddress::LocalHost));
       
  1893 
       
  1894     QTcpSocket *tcpSocket = 0;
       
  1895     // we try 10 times, but note that this doesn't always provoke the bug
       
  1896     for (int i = 0; i < 10; ++i) {
       
  1897         delete tcpSocket;
       
  1898         tcpSocket = newSocket();
       
  1899         tcpSocket->connectToHost(QHostAddress::LocalHost, server.serverPort());
       
  1900         if (!tcpSocket->waitForConnected(0)) {
       
  1901             // to provoke the bug, we need a local socket that connects immediately
       
  1902             // --i;
       
  1903             tcpSocket->abort();
       
  1904             if (tcpSocket->state() != QTcpSocket::UnconnectedState)
       
  1905                 QVERIFY(tcpSocket->waitForDisconnected(-1));
       
  1906             continue;
       
  1907         }
       
  1908         QCOMPARE(tcpSocket->localAddress(), QHostAddress(QHostAddress::LocalHost));
       
  1909     }
       
  1910     delete tcpSocket;
       
  1911 }
       
  1912 
       
  1913 //----------------------------------------------------------------------------------
       
  1914 void tst_QTcpSocket::zeroAndMinusOneReturns()
       
  1915 {
       
  1916     QTcpSocket *socket = newSocket();
       
  1917     socket->connectToHost(QtNetworkSettings::serverName(), 80);
       
  1918     socket->write("GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n");
       
  1919     QVERIFY(socket->waitForReadyRead(15000));
       
  1920 
       
  1921     char c[16];
       
  1922     QVERIFY(socket->getChar(c));
       
  1923     QCOMPARE(socket->read(c, 16), qint64(16));
       
  1924     QVERIFY(socket->readLine(c, 16) > 0);
       
  1925     QVERIFY(!socket->readAll().isEmpty());
       
  1926 
       
  1927     // the last operation emptied the read buffer
       
  1928     // all read operations from this point on should fail
       
  1929     // with return 0 because the socket is still open
       
  1930     QVERIFY(socket->readAll().isEmpty());
       
  1931     QCOMPARE(socket->read(c, 16), qint64(0));
       
  1932     QCOMPARE(socket->readLine(c, 16), qint64(0));
       
  1933     QVERIFY(!socket->getChar(c));
       
  1934 
       
  1935     socket->write("GET / HTTP/1.0\r\n\r\n");
       
  1936     QVERIFY(socket->waitForDisconnected(15000));
       
  1937     QCOMPARE(socket->error(), QAbstractSocket::RemoteHostClosedError);
       
  1938 
       
  1939     QCOMPARE(socket->write("BLUBBER"), qint64(-1));
       
  1940     QVERIFY(socket->getChar(c));
       
  1941     QCOMPARE(socket->read(c, 16), qint64(16));
       
  1942     QVERIFY(socket->readLine(c, 16) > 0);
       
  1943     QVERIFY(!socket->readAll().isEmpty());
       
  1944 
       
  1945     // the last operation emptied the read buffer
       
  1946     // all read operations from this point on should fail
       
  1947     // with return -1 because the socket is not connected
       
  1948     QVERIFY(socket->readAll().isEmpty());
       
  1949     QCOMPARE(socket->read(c, 16), qint64(-1));
       
  1950     QCOMPARE(socket->readLine(c, 16), qint64(-1));
       
  1951     QVERIFY(!socket->getChar(c));
       
  1952     QVERIFY(!socket->putChar('a'));
       
  1953 
       
  1954     socket->close();
       
  1955 
       
  1956     // now the QIODevice is closed, which means getChar complains
       
  1957     QCOMPARE(socket->write("BLUBBER"), qint64(-1));
       
  1958     QCOMPARE(socket->read(c, 16), qint64(-1));
       
  1959     QCOMPARE(socket->readLine(c, 16), qint64(-1));
       
  1960     QTest::ignoreMessage(QtWarningMsg, "QIODevice::getChar: Closed device");
       
  1961     QVERIFY(!socket->getChar(c));
       
  1962     QVERIFY(!socket->putChar('a'));
       
  1963 
       
  1964     delete socket;
       
  1965 }
       
  1966 
       
  1967 //----------------------------------------------------------------------------------
       
  1968 void tst_QTcpSocket::connectionRefused()
       
  1969 {
       
  1970     qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
       
  1971     qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState");
       
  1972 
       
  1973     QTcpSocket *socket = newSocket();
       
  1974     QSignalSpy stateSpy(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)));
       
  1975     QSignalSpy errorSpy(socket, SIGNAL(error(QAbstractSocket::SocketError)));
       
  1976     connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
       
  1977             &QTestEventLoop::instance(), SLOT(exitLoop()));
       
  1978 
       
  1979     socket->connectToHost(QtNetworkSettings::serverName(), 144);
       
  1980 
       
  1981     enterLoop(10);
       
  1982     disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
       
  1983                &QTestEventLoop::instance(), SLOT(exitLoop()));
       
  1984     QVERIFY2(!timeout(), "Network timeout");
       
  1985 
       
  1986     QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
       
  1987     QCOMPARE(socket->error(), QAbstractSocket::ConnectionRefusedError);
       
  1988 
       
  1989     QCOMPARE(stateSpy.count(), 3);
       
  1990     QCOMPARE(qVariantValue<QAbstractSocket::SocketState>(stateSpy.at(0).at(0)), QAbstractSocket::HostLookupState);
       
  1991     QCOMPARE(qVariantValue<QAbstractSocket::SocketState>(stateSpy.at(1).at(0)), QAbstractSocket::ConnectingState);
       
  1992     QCOMPARE(qVariantValue<QAbstractSocket::SocketState>(stateSpy.at(2).at(0)), QAbstractSocket::UnconnectedState);
       
  1993     QCOMPARE(errorSpy.count(), 1);
       
  1994 
       
  1995     delete socket;
       
  1996 }
       
  1997 
       
  1998 //----------------------------------------------------------------------------------
       
  1999 void tst_QTcpSocket::suddenRemoteDisconnect_data()
       
  2000 {
       
  2001     QTest::addColumn<QString>("client");
       
  2002     QTest::addColumn<QString>("server");
       
  2003 
       
  2004 #ifdef QT3_SUPPORT
       
  2005     QTest::newRow("Qt3 Client <-> Qt3 Server") << QString::fromLatin1("qt3client") << QString::fromLatin1("qt3server");
       
  2006     QTest::newRow("Qt3 Client <-> Qt4 Server") << QString::fromLatin1("qt3client") << QString::fromLatin1("qt4server");
       
  2007     QTest::newRow("Qt4 Client <-> Qt3 Server") << QString::fromLatin1("qt4client") << QString::fromLatin1("qt3server");
       
  2008 #endif
       
  2009 
       
  2010     QTest::newRow("Qt4 Client <-> Qt4 Server") << QString::fromLatin1("qt4client") << QString::fromLatin1("qt4server");
       
  2011 }
       
  2012 
       
  2013 void tst_QTcpSocket::suddenRemoteDisconnect()
       
  2014 {
       
  2015 #if defined(Q_OS_WINCE) || defined(Q_OS_VXWORKS)
       
  2016     QSKIP("stressTest subprocess needs Qt3Support", SkipAll);
       
  2017 #elif defined( Q_OS_SYMBIAN )
       
  2018     QSKIP("Symbian: QProcess IO is not yet supported, fix when supported", SkipAll);
       
  2019 #else
       
  2020     QFETCH(QString, client);
       
  2021     QFETCH(QString, server);
       
  2022 
       
  2023     QFETCH_GLOBAL(bool, setProxy);
       
  2024     if (setProxy)
       
  2025         return;
       
  2026     QFETCH_GLOBAL(bool, ssl);
       
  2027     if (ssl)
       
  2028         return;
       
  2029 
       
  2030     // Start server
       
  2031     QProcess serverProcess;
       
  2032     serverProcess.setReadChannel(QProcess::StandardError);
       
  2033     serverProcess.start(QString::fromLatin1("stressTest/stressTest %1").arg(server),
       
  2034                         QIODevice::ReadWrite | QIODevice::Text);
       
  2035     while (!serverProcess.canReadLine())
       
  2036         QVERIFY(serverProcess.waitForReadyRead(10000));
       
  2037     QCOMPARE(serverProcess.readLine().data(), (server.toLatin1() + "\n").data());
       
  2038 
       
  2039     // Start client
       
  2040     QProcess clientProcess;
       
  2041     clientProcess.setReadChannel(QProcess::StandardError);
       
  2042     clientProcess.start(QString::fromLatin1("stressTest/stressTest %1").arg(client),
       
  2043                         QIODevice::ReadWrite | QIODevice::Text);
       
  2044     while (!clientProcess.canReadLine())
       
  2045         QVERIFY(clientProcess.waitForReadyRead(10000));
       
  2046     QCOMPARE(clientProcess.readLine().data(), (client.toLatin1() + "\n").data());
       
  2047 
       
  2048     // Let them play for a while
       
  2049     qDebug("Running stress test for 5 seconds");
       
  2050     QEventLoop loop;
       
  2051     connect(&serverProcess, SIGNAL(finished(int)), &loop, SLOT(quit()));
       
  2052     connect(&clientProcess, SIGNAL(finished(int)), &loop, SLOT(quit()));
       
  2053     QTime stopWatch;
       
  2054     stopWatch.start();
       
  2055     QTimer::singleShot(20000, &loop, SLOT(quit()));
       
  2056 
       
  2057     while ((serverProcess.state() == QProcess::Running
       
  2058            || clientProcess.state() == QProcess::Running) && stopWatch.elapsed() < 20000)
       
  2059         loop.exec();
       
  2060 
       
  2061     QVERIFY(stopWatch.elapsed() < 20000);
       
  2062 
       
  2063     // Check that both exited normally.
       
  2064     QCOMPARE(clientProcess.readAll().constData(), "SUCCESS\n");
       
  2065     QCOMPARE(serverProcess.readAll().constData(), "SUCCESS\n");
       
  2066 #endif
       
  2067 }
       
  2068 
       
  2069 //----------------------------------------------------------------------------------
       
  2070 void tst_QTcpSocket::connectToMultiIP()
       
  2071 {
       
  2072 	QSKIP("TODO: setup DNS in the new network", SkipAll);
       
  2073 
       
  2074 #if defined(Q_OS_VXWORKS)
       
  2075     QSKIP("VxSim in standard config doesn't even run a DNS resolver", SkipAll);
       
  2076 #else
       
  2077     QFETCH_GLOBAL(bool, ssl);
       
  2078     if (ssl)
       
  2079         return;
       
  2080     QFETCH_GLOBAL(bool, setProxy);
       
  2081     if (setProxy)
       
  2082         QSKIP("This test takes too long if we also add the proxies.", SkipSingle);
       
  2083 
       
  2084     qDebug("Please wait, this test can take a while...");
       
  2085 
       
  2086     QTcpSocket *socket = newSocket();
       
  2087     // rationale: this domain resolves to 3 A-records, 2 of them are
       
  2088     // invalid. QTcpSocket should never spend more than 30 seconds per IP, and
       
  2089     // 30s*2 = 60s.
       
  2090     QTime stopWatch;
       
  2091     stopWatch.start();
       
  2092     socket->connectToHost("multi.dev.troll.no", 80);
       
  2093     QVERIFY(socket->waitForConnected(60500));
       
  2094     QVERIFY(stopWatch.elapsed() < 70000);
       
  2095     socket->abort();
       
  2096 
       
  2097     stopWatch.restart();
       
  2098     socket->connectToHost("multi.dev.troll.no", 81);
       
  2099     QVERIFY(!socket->waitForConnected(1000));
       
  2100     QVERIFY(stopWatch.elapsed() < 2000);
       
  2101     QCOMPARE(socket->error(), QAbstractSocket::SocketTimeoutError);
       
  2102 
       
  2103     delete socket;
       
  2104 #endif
       
  2105 }
       
  2106 
       
  2107 //----------------------------------------------------------------------------------
       
  2108 void tst_QTcpSocket::moveToThread0()
       
  2109 {
       
  2110     QFETCH_GLOBAL(int, proxyType);
       
  2111     if (proxyType & AuthMask)
       
  2112         return;
       
  2113 
       
  2114     {
       
  2115         // Case 1: Moved after connecting, before waiting for connection.
       
  2116         QTcpSocket *socket = newSocket();;
       
  2117         socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
  2118         socket->moveToThread(0);
       
  2119         QVERIFY(socket->waitForConnected(1000));
       
  2120         socket->write("XXX LOGOUT\r\n");
       
  2121         QVERIFY(socket->waitForBytesWritten(5000));
       
  2122         QVERIFY(socket->waitForDisconnected());
       
  2123         delete socket;
       
  2124     }
       
  2125     {
       
  2126         // Case 2: Moved before connecting
       
  2127         QTcpSocket *socket = newSocket();
       
  2128         socket->moveToThread(0);
       
  2129         socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
  2130         QVERIFY(socket->waitForConnected(1000));
       
  2131         socket->write("XXX LOGOUT\r\n");
       
  2132         QVERIFY(socket->waitForBytesWritten(5000));
       
  2133         QVERIFY(socket->waitForDisconnected());
       
  2134         delete socket;
       
  2135     }
       
  2136     {
       
  2137         // Case 3: Moved after writing, while waiting for bytes to be written.
       
  2138         QTcpSocket *socket = newSocket();
       
  2139         socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
  2140         QVERIFY(socket->waitForConnected(1000));
       
  2141         socket->write("XXX LOGOUT\r\n");
       
  2142         socket->moveToThread(0);
       
  2143         QVERIFY(socket->waitForBytesWritten(5000));
       
  2144         QVERIFY(socket->waitForDisconnected());
       
  2145         delete socket;
       
  2146     }
       
  2147     {
       
  2148         // Case 4: Moved after writing, while waiting for response.
       
  2149         QTcpSocket *socket = newSocket();
       
  2150         socket->connectToHost(QtNetworkSettings::serverName(), 143);
       
  2151         QVERIFY(socket->waitForConnected(1000));
       
  2152         socket->write("XXX LOGOUT\r\n");
       
  2153         QVERIFY(socket->waitForBytesWritten(5000));
       
  2154         socket->moveToThread(0);
       
  2155         QVERIFY(socket->waitForDisconnected());
       
  2156         delete socket;
       
  2157     }
       
  2158 }
       
  2159 
       
  2160 void tst_QTcpSocket::increaseReadBufferSize()
       
  2161 {
       
  2162     QTcpServer server;
       
  2163     QTcpSocket *active = newSocket();
       
  2164     connect(active, SIGNAL(readyRead()), SLOT(exitLoopSlot()));
       
  2165 
       
  2166     // connect two sockets to each other:
       
  2167     QVERIFY(server.listen(QHostAddress::LocalHost));
       
  2168     active->connectToHost("127.0.0.1", server.serverPort());
       
  2169     QVERIFY(active->waitForConnected(5000));
       
  2170     QVERIFY(server.waitForNewConnection(5000));
       
  2171 
       
  2172     QTcpSocket *passive = server.nextPendingConnection();
       
  2173     QVERIFY(passive);
       
  2174 
       
  2175     // now write 512 bytes of data on one end
       
  2176     QByteArray data(512, 'a');
       
  2177     passive->write(data);
       
  2178     QVERIFY2(passive->waitForBytesWritten(5000), "Network timeout");
       
  2179 
       
  2180     // set the read buffer size to less than what was written and iterate:
       
  2181     active->setReadBufferSize(256);
       
  2182     enterLoop(10);
       
  2183     QVERIFY2(!timeout(), "Network timeout");
       
  2184     QCOMPARE(active->bytesAvailable(), active->readBufferSize());
       
  2185 
       
  2186     // increase the buffer size and iterate again:
       
  2187     active->setReadBufferSize(384);
       
  2188     enterLoop(10);
       
  2189     QVERIFY2(!timeout(), "Network timeout");
       
  2190     QCOMPARE(active->bytesAvailable(), active->readBufferSize());
       
  2191 
       
  2192     // once more, but now it should read everything there was to read
       
  2193     active->setReadBufferSize(1024);
       
  2194     enterLoop(10);
       
  2195     QVERIFY2(!timeout(), "Network timeout");
       
  2196     QCOMPARE(active->bytesAvailable(), qint64(data.size()));
       
  2197 
       
  2198     // drain it and compare
       
  2199     QCOMPARE(active->readAll(), data);
       
  2200 
       
  2201     // now one more test by setting the buffer size to unlimited:
       
  2202     passive->write(data);
       
  2203     QVERIFY2(passive->waitForBytesWritten(5000), "Network timeout");
       
  2204     active->setReadBufferSize(256);
       
  2205     enterLoop(10);
       
  2206     QVERIFY2(!timeout(), "Network timeout");
       
  2207     QCOMPARE(active->bytesAvailable(), active->readBufferSize());
       
  2208     active->setReadBufferSize(0);
       
  2209     enterLoop(10);
       
  2210     QVERIFY2(!timeout(), "Network timeout");
       
  2211     QCOMPARE(active->bytesAvailable(), qint64(data.size()));
       
  2212     QCOMPARE(active->readAll(), data);
       
  2213 
       
  2214     delete active;
       
  2215 }
       
  2216 
       
  2217 #ifdef TEST_QNETWORK_PROXY
       
  2218 void tst_QTcpSocket::invalidProxy_data()
       
  2219 {
       
  2220     QTest::addColumn<int>("type");
       
  2221     QTest::addColumn<QString>("host");
       
  2222     QTest::addColumn<int>("port");
       
  2223     QTest::addColumn<bool>("failsAtConnect");
       
  2224     QTest::addColumn<int>("expectedError");
       
  2225 
       
  2226     QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString();
       
  2227     QTest::newRow("ftp-proxy") << int(QNetworkProxy::FtpCachingProxy) << fluke << 21 << true
       
  2228                                << int(QAbstractSocket::UnsupportedSocketOperationError);
       
  2229     QTest::newRow("http-caching-proxy") << int(QNetworkProxy::HttpCachingProxy) << fluke << 3128 << true
       
  2230                                         << int(QAbstractSocket::UnsupportedSocketOperationError);
       
  2231     QTest::newRow("no-such-host-socks5") << int(QNetworkProxy::Socks5Proxy)
       
  2232                                          << "this-host-will-never-exist.troll.no" << 1080 << false
       
  2233                                          << int(QAbstractSocket::ProxyNotFoundError);
       
  2234     QTest::newRow("no-such-host-http") << int(QNetworkProxy::HttpProxy)
       
  2235                                        << "this-host-will-never-exist.troll.no" << 3128 << false
       
  2236                                        << int(QAbstractSocket::ProxyNotFoundError);
       
  2237 #if !defined(Q_OS_SYMBIAN)
       
  2238     QTest::newRow("http-on-socks5") << int(QNetworkProxy::HttpProxy) << fluke << 1080 << false
       
  2239                                     << int(QAbstractSocket::ProxyConnectionClosedError);
       
  2240     QTest::newRow("socks5-on-http") << int(QNetworkProxy::Socks5Proxy) << fluke << 3128 << false
       
  2241                                     << int(QAbstractSocket::SocketTimeoutError);
       
  2242 #endif
       
  2243 }
       
  2244 
       
  2245 void tst_QTcpSocket::invalidProxy()
       
  2246 {
       
  2247     QFETCH_GLOBAL(bool, setProxy);
       
  2248     if (setProxy)
       
  2249         return;
       
  2250 
       
  2251     QFETCH(int, type);
       
  2252     QFETCH(QString, host);
       
  2253     QFETCH(int, port);
       
  2254     QFETCH(bool, failsAtConnect);
       
  2255     QNetworkProxy::ProxyType proxyType = QNetworkProxy::ProxyType(type);
       
  2256     QNetworkProxy proxy(proxyType, host, port);
       
  2257 
       
  2258     QTcpSocket *socket = newSocket();
       
  2259     socket->setProxy(proxy);
       
  2260     socket->connectToHost(QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(), 80);
       
  2261 
       
  2262     if (failsAtConnect) {
       
  2263         QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
       
  2264     } else {
       
  2265         QCOMPARE(socket->state(), QAbstractSocket::ConnectingState);
       
  2266         QVERIFY(!socket->waitForConnected(1000));
       
  2267     }
       
  2268     QVERIFY(!socket->errorString().isEmpty());
       
  2269 
       
  2270     // note: the following test is not a hard failure.
       
  2271     // Sometimes, error codes change for the better
       
  2272     QTEST(int(socket->error()), "expectedError");
       
  2273 
       
  2274     delete socket;
       
  2275 }
       
  2276 
       
  2277 // copied from tst_qnetworkreply.cpp
       
  2278 class MyProxyFactory: public QNetworkProxyFactory
       
  2279 {
       
  2280 public:
       
  2281     int callCount;
       
  2282     QList<QNetworkProxy> toReturn;
       
  2283     QNetworkProxyQuery lastQuery;
       
  2284     inline MyProxyFactory() { clear(); }
       
  2285 
       
  2286     inline void clear()
       
  2287     {
       
  2288         callCount = 0;
       
  2289         toReturn = QList<QNetworkProxy>() << QNetworkProxy::DefaultProxy;
       
  2290         lastQuery = QNetworkProxyQuery();
       
  2291     }
       
  2292 
       
  2293     virtual QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query)
       
  2294     {
       
  2295         lastQuery = query;
       
  2296         ++callCount;
       
  2297         return toReturn;
       
  2298     }
       
  2299 };
       
  2300 
       
  2301 void tst_QTcpSocket::proxyFactory_data()
       
  2302 {
       
  2303     QTest::addColumn<QList<QNetworkProxy> >("proxyList");
       
  2304     QTest::addColumn<QNetworkProxy>("proxyUsed");
       
  2305     QTest::addColumn<bool>("failsAtConnect");
       
  2306     QTest::addColumn<int>("expectedError");
       
  2307 
       
  2308     QList<QNetworkProxy> proxyList;
       
  2309 
       
  2310     // tests that do connect
       
  2311 
       
  2312     proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3129);
       
  2313     QTest::newRow("http")
       
  2314         << proxyList << proxyList.at(0)
       
  2315         << false << int(QAbstractSocket::UnknownSocketError);
       
  2316 
       
  2317     proxyList.clear();
       
  2318     proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
       
  2319     QTest::newRow("socks5")
       
  2320         << proxyList << proxyList.at(0)
       
  2321         << false << int(QAbstractSocket::UnknownSocketError);
       
  2322 
       
  2323     proxyList.clear();
       
  2324     proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
       
  2325               << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
       
  2326     QTest::newRow("cachinghttp+socks5")
       
  2327         << proxyList << proxyList.at(1)
       
  2328         << false << int(QAbstractSocket::UnknownSocketError);
       
  2329 
       
  2330     proxyList.clear();
       
  2331     proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121)
       
  2332               << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
       
  2333               << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
       
  2334     QTest::newRow("ftp+cachinghttp+socks5")
       
  2335         << proxyList << proxyList.at(2)
       
  2336         << false << int(QAbstractSocket::UnknownSocketError);
       
  2337 
       
  2338     // tests that fail to connect
       
  2339     proxyList.clear();
       
  2340     proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
       
  2341     QTest::newRow("cachinghttp")
       
  2342         << proxyList << QNetworkProxy()
       
  2343         << true << int(QAbstractSocket::UnsupportedSocketOperationError);
       
  2344 
       
  2345     proxyList.clear();
       
  2346     proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121);
       
  2347     QTest::newRow("ftp")
       
  2348         << proxyList << QNetworkProxy()
       
  2349         << true << int(QAbstractSocket::UnsupportedSocketOperationError);
       
  2350 
       
  2351     proxyList.clear();
       
  2352     proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121)
       
  2353               << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
       
  2354     QTest::newRow("ftp+cachinghttp")
       
  2355         << proxyList << QNetworkProxy()
       
  2356         << true << int(QAbstractSocket::UnsupportedSocketOperationError);
       
  2357 }
       
  2358 
       
  2359 void tst_QTcpSocket::proxyFactory()
       
  2360 {
       
  2361     QFETCH_GLOBAL(bool, setProxy);
       
  2362     if (setProxy)
       
  2363         return;
       
  2364 
       
  2365     QFETCH(QList<QNetworkProxy>, proxyList);
       
  2366     QFETCH(QNetworkProxy, proxyUsed);
       
  2367     QFETCH(bool, failsAtConnect);
       
  2368 
       
  2369     MyProxyFactory *factory = new MyProxyFactory;
       
  2370     factory->toReturn = proxyList;
       
  2371     QNetworkProxyFactory::setApplicationProxyFactory(factory);
       
  2372 
       
  2373     QTcpSocket *socket = newSocket();
       
  2374     QString host = QtNetworkSettings::serverName();
       
  2375     socket->connectToHost(host, 80);
       
  2376 
       
  2377     // Verify that the factory was called properly
       
  2378     QCOMPARE(factory->callCount, 1);
       
  2379     QCOMPARE(factory->lastQuery, QNetworkProxyQuery(host, 80));
       
  2380 
       
  2381     if (failsAtConnect) {
       
  2382         QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
       
  2383     } else {
       
  2384         QCOMPARE(socket->state(), QAbstractSocket::ConnectingState);
       
  2385         QVERIFY(socket->waitForConnected(10000));
       
  2386         QCOMPARE(proxyAuthCalled, 1);
       
  2387     }
       
  2388     QVERIFY(!socket->errorString().isEmpty());
       
  2389 
       
  2390     // note: the following test is not a hard failure.
       
  2391     // Sometimes, error codes change for the better
       
  2392     QTEST(int(socket->error()), "expectedError");
       
  2393 
       
  2394     delete socket;
       
  2395 }
       
  2396 #endif
       
  2397 
       
  2398 
       
  2399 QTEST_MAIN(tst_QTcpSocket)
       
  2400 #include "tst_qtcpsocket.moc"