1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 // Just to get Q_OS_SYMBIAN
46 #if defined(_WIN32) && !defined(Q_OS_SYMBIAN)
49 #include <sys/types.h>
50 #include <sys/socket.h>
54 #define INVALID_SOCKET -1
57 #include <qplatformdefs.h>
59 #include <QtTest/QtTest>
61 #include <QAuthenticator>
62 #include <QCoreApplication>
65 #include <QHostAddress>
69 #include <QMessageBox>
70 #include <QPushButton>
74 #include <QStringList>
80 #include <QTextStream>
85 // RVCT compiles also unused inline methods
86 # include <QNetworkProxy>
95 #include "private/qhostinfo_p.h"
97 #include "../network-settings.h"
98 #include "../../shared/util.h"
100 Q_DECLARE_METATYPE(QAbstractSocket::SocketError)
101 Q_DECLARE_METATYPE(QAbstractSocket::SocketState)
102 Q_DECLARE_METATYPE(QNetworkProxy)
103 Q_DECLARE_METATYPE(QList<QNetworkProxy>)
108 QT_FORWARD_DECLARE_CLASS(QTcpSocket)
109 QT_FORWARD_DECLARE_CLASS(SocketPair)
111 class tst_QTcpSocket : public QObject
117 virtual ~tst_QTcpSocket();
119 static void enterLoop(int secs)
122 QTestEventLoop::instance().enterLoop(secs);
125 static void exitLoop()
127 // Safe exit - if we aren't in an event loop, don't
130 QTestEventLoop::instance().exitLoop();
132 static bool timeout()
134 return QTestEventLoop::instance().timeout();
138 void initTestCase_data();
142 void socketsConstructedBeforeEventLoop();
144 void setInvalidSocketDescriptor();
145 void setSocketDescriptor();
146 void socketDescriptor();
148 void nonBlockingIMAP();
150 void timeoutConnect_data();
151 void timeoutConnect();
155 void readAllAfterClose();
156 void openCloseOpenClose();
157 void connectDisconnectConnectDisconnect();
158 void disconnectWhileConnecting_data();
159 void disconnectWhileConnecting();
160 void disconnectWhileConnectingNoEventLoop_data();
161 void disconnectWhileConnectingNoEventLoop();
162 void disconnectWhileLookingUp_data();
163 void disconnectWhileLookingUp();
164 void downloadBigFile();
166 void readLineString();
168 void waitForBytesWritten();
169 void waitForBytesWrittenMinusOne();
170 void waitForReadyRead();
171 void waitForReadyReadMinusOne();
173 void synchronousApi();
174 void dontCloseOnTimeout();
175 void recursiveReadyRead();
177 void socketInAThread();
178 void socketsInThreads();
179 void waitForReadyReadInASlot();
180 void remoteCloseError();
181 void openMessageBoxInErrorSlot();
183 void connectToLocalHostNoService();
185 void waitForConnectedInHostLookupSlot();
186 void waitForConnectedInHostLookupSlot2();
187 void readyReadSignalsAfterWaitForReadyRead();
189 void linuxKernelBugLocalSocket();
191 void abortiveClose();
192 void localAddressEmptyOnBSD();
193 void zeroAndMinusOneReturns();
194 void connectionRefused();
195 void suddenRemoteDisconnect_data();
196 void suddenRemoteDisconnect();
197 void connectToMultiIP();
198 void moveToThread0();
199 void increaseReadBufferSize();
200 void taskQtBug5799ConnectionErrorWaitForConnected();
201 void taskQtBug5799ConnectionErrorEventLoop();
202 void taskQtBug7054TimeoutErrorResetting();
204 void invalidProxy_data();
206 void proxyFactory_data();
209 void qtbug14268_peek();
213 void nonBlockingIMAP_hostFound();
214 void nonBlockingIMAP_connected();
215 void nonBlockingIMAP_closed();
216 void nonBlockingIMAP_readyRead();
217 void nonBlockingIMAP_bytesWritten(qint64);
218 void readRegularFile_readyRead();
220 void downloadBigFileSlot();
221 void recursiveReadyReadSlot();
222 void waitForReadyReadInASlotSlot();
223 void messageBoxSlot();
224 void hostLookupSlot();
225 void abortiveClose_abortSlot();
226 void remoteCloseErrorSlot();
227 void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth);
228 void earlySocketBytesSent(qint64 bytes);
229 void earlySocketReadyRead();
232 QByteArray expectedReplyIMAP();
233 void fetchExpectedReplyIMAP();
234 QTcpSocket *newSocket() const;
235 QTcpSocket *nonBlockingIMAP_socket;
236 QStringList nonBlockingIMAP_data;
237 qint64 nonBlockingIMAP_totalWritten;
239 QTcpSocket *tmpSocket;
240 qint64 bytesAvailable;
241 qint64 expectedLength;
245 QByteArray expectedReplyIMAP_cached;
247 mutable int proxyAuthCalled;
249 bool gotClosedSignal;
251 static int loopLevel;
253 SocketPair *earlyConstructedSockets;
254 int earlyBytesWrittenCount;
255 int earlyReadyReadCount;
270 int tst_QTcpSocket::loopLevel = 0;
272 class SocketPair: public QObject
276 QTcpSocket *endPoints[2];
278 SocketPair(QObject *parent = 0)
281 endPoints[0] = endPoints[1] = 0;
289 QTcpSocket *active = new QTcpSocket(this);
290 active->connectToHost("127.0.0.1", server.serverPort());
292 if (!active->waitForConnected(1000))
295 if (!server.waitForNewConnection(1000))
298 QTcpSocket *passive = server.nextPendingConnection();
299 passive->setParent(this);
301 endPoints[0] = active;
302 endPoints[1] = passive;
307 tst_QTcpSocket::tst_QTcpSocket()
311 //This code relates to the socketsConstructedBeforeEventLoop test case
312 earlyConstructedSockets = new SocketPair;
313 QVERIFY(earlyConstructedSockets->create());
314 earlyBytesWrittenCount = 0;
315 earlyReadyReadCount = 0;
316 connect(earlyConstructedSockets->endPoints[0], SIGNAL(readyRead()), this, SLOT(earlySocketReadyRead()));
317 connect(earlyConstructedSockets->endPoints[1], SIGNAL(bytesWritten(qint64)), this, SLOT(earlySocketBytesSent(qint64)));
318 earlyConstructedSockets->endPoints[1]->write("hello work");
321 tst_QTcpSocket::~tst_QTcpSocket()
326 void tst_QTcpSocket::initTestCase_data()
328 QTest::addColumn<bool>("setProxy");
329 QTest::addColumn<int>("proxyType");
330 QTest::addColumn<bool>("ssl");
332 qDebug() << QtNetworkSettings::serverName();
333 QTest::newRow("WithoutProxy") << false << 0 << false;
334 QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy) << false;
335 QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic) << false;
337 QTest::newRow("WithHttpProxy") << true << int(HttpProxy) << false;
338 QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic) << false;
339 // QTest::newRow("WithHttpProxyNtlmAuth") << true << int(HttpProxy | AuthNtlm) << false;
341 #ifndef QT_NO_OPENSSL
342 QTest::newRow("WithoutProxy SSL") << false << 0 << true;
343 QTest::newRow("WithSocks5Proxy SSL") << true << int(Socks5Proxy) << true;
344 QTest::newRow("WithSocks5AuthProxy SSL") << true << int(Socks5Proxy | AuthBasic) << true;
346 QTest::newRow("WithHttpProxy SSL") << true << int(HttpProxy) << true;
347 QTest::newRow("WithHttpProxyBasicAuth SSL") << true << int(HttpProxy | AuthBasic) << true;
348 // QTest::newRow("WithHttpProxyNtlmAuth SSL") << true << int(HttpProxy | AuthNtlm) << true;
352 void tst_QTcpSocket::init()
354 QFETCH_GLOBAL(bool, setProxy);
356 QFETCH_GLOBAL(int, proxyType);
357 QList<QHostAddress> addresses = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses();
358 QVERIFY2(addresses.count() > 0, "failed to get ip address for test server");
359 QString fluke = addresses.first().toString();
364 proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1080);
367 case Socks5Proxy | AuthBasic:
368 proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1081);
371 case HttpProxy | NoAuth:
372 proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3128);
375 case HttpProxy | AuthBasic:
376 proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3129);
379 case HttpProxy | AuthNtlm:
380 proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3130);
383 QNetworkProxy::setApplicationProxy(proxy);
386 qt_qhostinfo_clear_cache();
389 QTcpSocket *tst_QTcpSocket::newSocket() const
392 #ifndef QT_NO_OPENSSL
393 QFETCH_GLOBAL(bool, ssl);
394 socket = ssl ? new QSslSocket : new QTcpSocket;
396 socket = new QTcpSocket;
400 connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
401 SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
402 Qt::DirectConnection);
406 void tst_QTcpSocket::cleanup()
408 QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
411 void tst_QTcpSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
414 auth->setUser("qsockstest");
415 auth->setPassword("password");
418 //----------------------------------------------------------------------------------
420 void tst_QTcpSocket::socketsConstructedBeforeEventLoop()
422 QFETCH_GLOBAL(bool, setProxy);
423 QFETCH_GLOBAL(bool, ssl);
426 //This test checks that sockets constructed before QCoreApplication::exec() still emit signals
427 //see construction code in the tst_QTcpSocket constructor
429 QCOMPARE(earlyBytesWrittenCount, 1);
430 QCOMPARE(earlyReadyReadCount, 1);
431 earlyConstructedSockets->endPoints[0]->close();
432 earlyConstructedSockets->endPoints[1]->close();
435 void tst_QTcpSocket::earlySocketBytesSent(qint64 /* bytes */)
437 earlyBytesWrittenCount++;
440 void tst_QTcpSocket::earlySocketReadyRead()
442 earlyReadyReadCount++;
445 //----------------------------------------------------------------------------------
447 void tst_QTcpSocket::constructing()
449 QTcpSocket *socket = newSocket();
451 // Check the initial state of the QTcpSocket.
452 QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
453 QVERIFY(socket->isSequential());
454 QVERIFY(!socket->isOpen());
455 QVERIFY(!socket->isValid());
456 QCOMPARE(socket->socketType(), QTcpSocket::TcpSocket);
459 QCOMPARE(socket->getChar(&c), false);
460 QCOMPARE((int) socket->bytesAvailable(), 0);
461 QCOMPARE(socket->canReadLine(), false);
462 QCOMPARE(socket->readLine(), QByteArray());
463 QCOMPARE(socket->socketDescriptor(), -1);
464 QCOMPARE((int) socket->localPort(), 0);
465 QVERIFY(socket->localAddress() == QHostAddress());
466 QCOMPARE((int) socket->peerPort(), 0);
467 QVERIFY(socket->peerAddress() == QHostAddress());
468 QCOMPARE(socket->error(), QTcpSocket::UnknownSocketError);
469 QCOMPARE(socket->errorString(), QString("Unknown error"));
471 // Check the state of the socket layer?
475 //----------------------------------------------------------------------------------
477 void tst_QTcpSocket::setInvalidSocketDescriptor()
479 QTcpSocket *socket = newSocket();
480 QCOMPARE(socket->socketDescriptor(), -1);
482 QTest::ignoreMessage(QtWarningMsg, "QSymbianSocketEngine::initialize - socket descriptor not found");
484 QVERIFY(!socket->setSocketDescriptor(-5, QTcpSocket::UnconnectedState));
485 QCOMPARE(socket->socketDescriptor(), -1);
487 QCOMPARE(socket->error(), QTcpSocket::UnsupportedSocketOperationError);
492 //----------------------------------------------------------------------------------
494 void tst_QTcpSocket::setSocketDescriptor()
497 QSKIP("adopting open c socket handles is not supported", SkipAll);
499 QFETCH_GLOBAL(bool, setProxy);
501 return; // this test doesn't make sense with proxies
504 // need the dummy to ensure winsock is started
505 QTcpSocket *dummy = newSocket();
506 dummy->connectToHost(QtNetworkSettings::serverName(), 143);
507 QVERIFY(dummy->waitForConnected());
509 SOCKET sock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
510 if (sock == INVALID_SOCKET) {
511 qErrnoWarning(WSAGetLastError(), "INVALID_SOCKET");
514 SOCKET sock = ::socket(AF_INET, SOCK_STREAM, 0);
516 // artificially increase the value of sock
517 SOCKET sock2 = ::fcntl(sock, F_DUPFD, sock + 50);
522 QVERIFY(sock != INVALID_SOCKET);
523 QTcpSocket *socket = newSocket();
524 QVERIFY(socket->setSocketDescriptor(sock, QTcpSocket::UnconnectedState));
525 QCOMPARE(socket->socketDescriptor(), (int)sock);
527 socket->connectToHost(QtNetworkSettings::serverName(), 143);
528 QCOMPARE(socket->state(), QTcpSocket::HostLookupState);
529 QCOMPARE(socket->socketDescriptor(), (int)sock);
530 QVERIFY(socket->waitForConnected(10000));
531 // skip this, it has been broken for years, see task 260735
532 // if somebody complains, consider fixing it, but it might break existing applications.
533 QEXPECT_FAIL("", "bug has been around for years, will not fix without need", Continue);
534 QCOMPARE(socket->socketDescriptor(), (int)sock);
542 //----------------------------------------------------------------------------------
544 void tst_QTcpSocket::socketDescriptor()
546 QTcpSocket *socket = newSocket();
548 QCOMPARE(socket->socketDescriptor(), -1);
549 socket->connectToHost(QtNetworkSettings::serverName(), 143);
550 QVERIFY((socket->state() == QAbstractSocket::HostLookupState && socket->socketDescriptor() == -1) ||
551 (socket->state() == QAbstractSocket::ConnectingState && socket->socketDescriptor() != -1));
552 QVERIFY(socket->waitForConnected(10000));
553 QVERIFY(socket->state() == QAbstractSocket::ConnectedState);
554 QVERIFY(socket->socketDescriptor() != -1);
559 //----------------------------------------------------------------------------------
561 void tst_QTcpSocket::blockingIMAP()
563 QTcpSocket *socket = newSocket();
566 socket->connectToHost(QtNetworkSettings::serverName(), 143);
567 QVERIFY(socket->waitForConnected(10000));
568 QCOMPARE(socket->state(), QTcpSocket::ConnectedState);
569 QVERIFY(socket->isValid());
572 QVERIFY(socket->waitForReadyRead(5000));
573 QString s = socket->readLine();
574 // only test if an OK was returned, to make the test compatible between different
575 // IMAP server versions
576 QCOMPARE(s.left(4).toLatin1().constData(), "* OK");
579 QCOMPARE((int) socket->write("1 NOOP\r\n", 8), 8);
580 QCOMPARE((int) socket->write("2 NOOP\r\n", 8), 8);
582 if (!socket->canReadLine())
583 QVERIFY(socket->waitForReadyRead(5000));
586 s = socket->readLine();
587 QCOMPARE(s.toLatin1().constData(), "1 OK Completed\r\n");
589 // Write a third NOOP to verify that write doesn't clear the read buffer
590 QCOMPARE((int) socket->write("3 NOOP\r\n", 8), 8);
592 // Read second response
593 if (!socket->canReadLine())
594 QVERIFY(socket->waitForReadyRead(5000));
595 s = socket->readLine();
596 QCOMPARE(s.toLatin1().constData(), "2 OK Completed\r\n");
598 // Read third response
599 if (!socket->canReadLine())
600 QVERIFY(socket->waitForReadyRead(5000));
601 s = socket->readLine();
602 QCOMPARE(s.toLatin1().constData(), "3 OK Completed\r\n");
606 QCOMPARE((int) socket->write("4 LOGOUT\r\n", 10), 10);
608 if (!socket->canReadLine())
609 QVERIFY(socket->waitForReadyRead(5000));
611 // Read two lines of respose
612 s = socket->readLine();
613 QCOMPARE(s.toLatin1().constData(), "* BYE LOGOUT received\r\n");
615 if (!socket->canReadLine())
616 QVERIFY(socket->waitForReadyRead(5000));
618 s = socket->readLine();
619 QCOMPARE(s.toLatin1().constData(), "4 OK Completed\r\n");
624 // Check that it's closed
625 QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
630 //----------------------------------------------------------------------------------
632 void tst_QTcpSocket::hostNotFound()
634 QTcpSocket *socket = newSocket();
636 socket->connectToHost("nosuchserver.troll.no", 80);
637 QVERIFY(!socket->waitForConnected());
638 QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
639 QCOMPARE(int(socket->error()), int(QTcpSocket::HostNotFoundError));
644 //----------------------------------------------------------------------------------
645 void tst_QTcpSocket::timeoutConnect_data()
647 QTest::addColumn<QString>("address");
648 QTest::newRow("host") << QtNetworkSettings::serverName();
649 QTest::newRow("ip") << QtNetworkSettings::serverIP().toString();
652 void tst_QTcpSocket::timeoutConnect()
654 QFETCH(QString, address);
655 QTcpSocket *socket = newSocket();
660 // Port 1357 is configured to drop packets on the test server
661 socket->connectToHost(address, 1357);
662 QVERIFY(timer.elapsed() < 150);
663 QVERIFY(!socket->waitForConnected(1000)); //200ms is too short when using SOCKS proxy authentication
664 QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
665 QCOMPARE(int(socket->error()), int(QTcpSocket::SocketTimeoutError));
668 socket->connectToHost(address, 1357);
669 QVERIFY(timer.elapsed() < 150);
670 QTimer::singleShot(50, &QTestEventLoop::instance(), SLOT(exitLoop()));
671 QTestEventLoop::instance().enterLoop(5);
672 QVERIFY(!QTestEventLoop::instance().timeout());
673 QVERIFY(socket->state() == QTcpSocket::ConnectingState
674 || socket->state() == QTcpSocket::HostLookupState);
676 QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
677 QCOMPARE(socket->openMode(), QIODevice::NotOpen);
682 //----------------------------------------------------------------------------------
684 void tst_QTcpSocket::nonBlockingIMAP()
686 QTcpSocket *socket = newSocket();
687 connect(socket, SIGNAL(hostFound()), SLOT(nonBlockingIMAP_hostFound()));
688 connect(socket, SIGNAL(connected()), SLOT(nonBlockingIMAP_connected()));
689 connect(socket, SIGNAL(disconnected()), SLOT(nonBlockingIMAP_closed()));
690 connect(socket, SIGNAL(bytesWritten(qint64)), SLOT(nonBlockingIMAP_bytesWritten(qint64)));
691 connect(socket, SIGNAL(readyRead()), SLOT(nonBlockingIMAP_readyRead()));
692 nonBlockingIMAP_socket = socket;
695 socket->connectToHost(QtNetworkSettings::serverName(), 143);
696 QVERIFY(socket->state() == QTcpSocket::HostLookupState ||
697 socket->state() == QTcpSocket::ConnectingState);
704 if (socket->state() == QTcpSocket::ConnectingState) {
711 QCOMPARE(socket->state(), QTcpSocket::ConnectedState);
719 QVERIFY(!nonBlockingIMAP_data.isEmpty());
720 QCOMPARE(nonBlockingIMAP_data.at(0).left(4).toLatin1().constData(), "* OK");
721 nonBlockingIMAP_data.clear();
723 nonBlockingIMAP_totalWritten = 0;
726 QCOMPARE((int) socket->write("1 NOOP\r\n", 8), 8);
734 QVERIFY(nonBlockingIMAP_totalWritten == 8);
744 QVERIFY(!nonBlockingIMAP_data.isEmpty());
745 QCOMPARE(nonBlockingIMAP_data.at(0).toLatin1().constData(), "1 OK Completed\r\n");
746 nonBlockingIMAP_data.clear();
749 nonBlockingIMAP_totalWritten = 0;
752 QCOMPARE((int) socket->write("2 LOGOUT\r\n", 10), 10);
759 QVERIFY(nonBlockingIMAP_totalWritten == 10);
767 // Read two lines of respose
768 QCOMPARE(nonBlockingIMAP_data.at(0).toLatin1().constData(), "* BYE LOGOUT received\r\n");
769 QCOMPARE(nonBlockingIMAP_data.at(1).toLatin1().constData(), "2 OK Completed\r\n");
770 nonBlockingIMAP_data.clear();
775 // Check that it's closed
776 QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
781 void tst_QTcpSocket::nonBlockingIMAP_hostFound()
786 void tst_QTcpSocket::nonBlockingIMAP_connected()
791 void tst_QTcpSocket::nonBlockingIMAP_readyRead()
793 while (nonBlockingIMAP_socket->canReadLine())
794 nonBlockingIMAP_data.append(nonBlockingIMAP_socket->readLine());
799 void tst_QTcpSocket::nonBlockingIMAP_bytesWritten(qint64 written)
801 nonBlockingIMAP_totalWritten += written;
805 void tst_QTcpSocket::nonBlockingIMAP_closed()
809 //----------------------------------------------------------------------------------
811 void tst_QTcpSocket::delayedClose()
813 QTcpSocket *socket = newSocket();
814 connect(socket, SIGNAL(connected()), SLOT(nonBlockingIMAP_connected()));
815 connect(socket, SIGNAL(disconnected()), SLOT(exitLoopSlot()));
817 socket->connectToHost(QtNetworkSettings::serverName(), 143);
823 QCOMPARE(socket->state(), QTcpSocket::ConnectedState);
825 QCOMPARE((int) socket->write("1 LOGOUT\r\n", 10), 10);
827 // Add a huge bulk of data to be written after the logout
828 // command. The server will shut down after receiving the LOGOUT,
829 // so this data will not be read. But our close call should
830 // schedule a delayed close because all the data can not be
831 // written in one go.
832 QCOMPARE((int) socket->write(QByteArray(100000, '\n'), 100000), 100000);
836 QCOMPARE((int) socket->state(), (int) QTcpSocket::ClosingState);
842 QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
848 //----------------------------------------------------------------------------------
850 QByteArray tst_QTcpSocket::expectedReplyIMAP()
852 if (expectedReplyIMAP_cached.isEmpty()) {
853 fetchExpectedReplyIMAP();
856 return expectedReplyIMAP_cached;
859 // Figure out how the current IMAP server responds
860 void tst_QTcpSocket::fetchExpectedReplyIMAP()
862 QTcpSocket *socket = newSocket();
863 socket->connectToHost(QtNetworkSettings::serverName(), 143);
864 QVERIFY2(socket->waitForConnected(10000), qPrintable(socket->errorString()));
865 QVERIFY2(socket->state() == QTcpSocket::ConnectedState, qPrintable(socket->errorString()));
867 QTRY_VERIFY(socket->canReadLine());
869 QByteArray greeting = socket->readLine();
872 QVERIFY2(QtNetworkSettings::compareReplyIMAP(greeting), greeting.constData());
874 expectedReplyIMAP_cached = greeting;
877 //----------------------------------------------------------------------------------
879 void tst_QTcpSocket::partialRead()
881 QTcpSocket *socket = newSocket();
882 socket->connectToHost(QtNetworkSettings::serverName(), 143);
883 QVERIFY(socket->waitForConnected(10000));
884 QVERIFY(socket->state() == QTcpSocket::ConnectedState);
887 QByteArray greeting = expectedReplyIMAP();
888 QVERIFY(!greeting.isEmpty());
890 for (int i = 0; i < 10; i += 2) {
891 while (socket->bytesAvailable() < 2)
892 QVERIFY(socket->waitForReadyRead(5000));
893 QVERIFY(socket->read(buf, 2) == 2);
895 QCOMPARE((char *)buf, greeting.mid(i, 2).data());
901 //----------------------------------------------------------------------------------
903 void tst_QTcpSocket::unget()
905 QTcpSocket *socket = newSocket();
906 socket->connectToHost(QtNetworkSettings::serverName(), 143);
907 QVERIFY(socket->waitForConnected(10000));
908 QVERIFY(socket->state() == QTcpSocket::ConnectedState);
911 QByteArray greeting = expectedReplyIMAP();
912 QVERIFY(!greeting.isEmpty());
914 for (int i = 0; i < 10; i += 2) {
915 while (socket->bytesAvailable() < 2)
916 QVERIFY(socket->waitForReadyRead(10000));
917 int bA = socket->bytesAvailable();
918 QVERIFY(socket->read(buf, 2) == 2);
920 QCOMPARE((char *)buf, greeting.mid(i, 2).data());
921 QCOMPARE((int)socket->bytesAvailable(), bA - 2);
922 socket->ungetChar(buf[1]);
923 socket->ungetChar(buf[0]);
924 QCOMPARE((int)socket->bytesAvailable(), bA);
925 QVERIFY(socket->read(buf, 2) == 2);
927 QCOMPARE((char *)buf, greeting.mid(i, 2).data());
933 //----------------------------------------------------------------------------------
934 void tst_QTcpSocket::readRegularFile_readyRead()
939 //----------------------------------------------------------------------------------
940 void tst_QTcpSocket::readAllAfterClose()
942 QTcpSocket *socket = newSocket();
943 socket->connectToHost(QtNetworkSettings::serverName(), 143);
944 connect(socket, SIGNAL(readyRead()), SLOT(readRegularFile_readyRead()));
947 QFAIL("Network operation timed out");
950 QByteArray array = socket->readAll();
951 QCOMPARE(array.size(), 0);
956 //----------------------------------------------------------------------------------
957 void tst_QTcpSocket::openCloseOpenClose()
959 QTcpSocket *socket = newSocket();
961 for (int i = 0; i < 3; ++i) {
962 QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
963 QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
964 QVERIFY(socket->isSequential());
965 QVERIFY(!socket->isOpen());
966 QVERIFY(socket->socketType() == QTcpSocket::TcpSocket);
969 QCOMPARE(socket->getChar(&c), false);
970 QCOMPARE((int) socket->bytesAvailable(), 0);
971 QCOMPARE(socket->canReadLine(), false);
972 QCOMPARE(socket->readLine(), QByteArray());
973 QCOMPARE(socket->socketDescriptor(), -1);
974 QCOMPARE((int) socket->localPort(), 0);
975 QVERIFY(socket->localAddress() == QHostAddress());
976 QCOMPARE((int) socket->peerPort(), 0);
977 QVERIFY(socket->peerAddress() == QHostAddress());
978 QCOMPARE(socket->error(), QTcpSocket::UnknownSocketError);
979 QCOMPARE(socket->errorString(), QString("Unknown error"));
981 QVERIFY(socket->state() == QTcpSocket::UnconnectedState);
983 socket->connectToHost(QtNetworkSettings::serverName(), 143);
984 QVERIFY(socket->waitForConnected(10000));
991 //----------------------------------------------------------------------------------
992 void tst_QTcpSocket::connectDisconnectConnectDisconnect()
994 QTcpSocket *socket = newSocket();
996 for (int i = 0; i < 3; ++i) {
997 QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
998 QVERIFY(socket->socketType() == QTcpSocket::TcpSocket);
1000 socket->connectToHost(QtNetworkSettings::serverName(), 143);
1001 QVERIFY(socket->waitForReadyRead(10000));
1002 QCOMPARE(QString::fromLatin1(socket->read(4)), QString("* OK"));
1004 socket->disconnectFromHost();
1005 if (socket->state() != QTcpSocket::UnconnectedState)
1006 QVERIFY(socket->waitForDisconnected(10000));
1007 QCOMPARE(int(socket->openMode()), int(QIODevice::ReadWrite));
1013 //----------------------------------------------------------------------------------
1014 void tst_QTcpSocket::disconnectWhileConnecting_data()
1016 QTest::addColumn<QByteArray>("data");
1017 QTest::addColumn<bool>("closeDirectly");
1019 QTest::newRow("without-data") << QByteArray() << false;
1020 QTest::newRow("without-data+close") << QByteArray() << true;
1021 QTest::newRow("with-data") << QByteArray("Hello, world!") << false;
1022 QTest::newRow("with-data+close") << QByteArray("Hello, world!") << true;
1024 QByteArray bigData(1024*1024, '@');
1025 QTest::newRow("with-big-data") << bigData << false;
1026 QTest::newRow("with-big-data+close") << bigData << true;
1029 void tst_QTcpSocket::disconnectWhileConnecting()
1031 QFETCH(QByteArray, data);
1032 QFETCH_GLOBAL(bool, setProxy);
1034 return; //proxy not useful for localhost test case
1037 QVERIFY(server.listen(QHostAddress::LocalHost));
1039 // proceed to the connect-write-disconnect
1040 QTcpSocket *socket = newSocket();
1041 socket->connectToHost("127.0.0.1", server.serverPort());
1042 if (!data.isEmpty())
1043 socket->write(data);
1044 if (socket->state() == QAbstractSocket::ConnectedState)
1045 QSKIP("localhost connections are immediate, test case is invalid", SkipSingle);
1047 QFETCH(bool, closeDirectly);
1048 if (closeDirectly) {
1050 QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
1052 socket->disconnectFromHost();
1055 connect(socket, SIGNAL(disconnected()), SLOT(exitLoopSlot()));
1056 #ifndef Q_OS_SYMBIAN
1061 QVERIFY2(!timeout(), "Network timeout");
1062 QVERIFY(socket->state() == QAbstractSocket::UnconnectedState);
1063 if (!closeDirectly) {
1064 QCOMPARE(int(socket->openMode()), int(QIODevice::ReadWrite));
1067 QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
1069 // accept the other side and verify that it was sent properly:
1070 QVERIFY(server.hasPendingConnections() || server.waitForNewConnection(0));
1071 QTcpSocket *othersocket = server.nextPendingConnection();
1072 if (othersocket->state() != QAbstractSocket::UnconnectedState)
1073 QVERIFY2(othersocket->waitForDisconnected(10000), "Network timeout");
1074 QVERIFY(othersocket->state() == QAbstractSocket::UnconnectedState);
1075 QCOMPARE(othersocket->readAll(), data);
1081 //----------------------------------------------------------------------------------
1082 class ReceiverThread: public QThread
1088 QByteArray receivedData;
1092 : server(0), ok(false), quit(false)
1095 ~ReceiverThread() { }
1099 server = new QTcpServer;
1100 if (!server->listen(QHostAddress::LocalHost))
1102 serverPort = server->serverPort();
1103 server->moveToThread(this);
1107 static void cleanup(void *ptr)
1109 ReceiverThread* self = reinterpret_cast<ReceiverThread*>(ptr);
1118 bool timedOut = false;
1120 #ifndef Q_OS_SYMBIAN
1121 if (server->waitForNewConnection(500, &timedOut))
1123 if (server->waitForNewConnection(5000, &timedOut))
1130 QTcpSocket *socket = server->nextPendingConnection();
1132 #ifndef Q_OS_SYMBIAN
1133 if (socket->waitForDisconnected(500))
1135 if (socket->waitForDisconnected(5000))
1138 if (socket->error() != QAbstractSocket::SocketTimeoutError)
1143 receivedData = socket->readAll();
1152 void tst_QTcpSocket::disconnectWhileConnectingNoEventLoop_data()
1154 disconnectWhileConnecting_data();
1157 void tst_QTcpSocket::disconnectWhileConnectingNoEventLoop()
1159 QFETCH(QByteArray, data);
1160 QFETCH_GLOBAL(bool, setProxy);
1162 return; //proxy not useful for localhost test case
1164 QScopedPointer<ReceiverThread, ReceiverThread> thread (new ReceiverThread);
1165 QVERIFY(thread->listen());
1168 // proceed to the connect-write-disconnect
1169 QTcpSocket *socket = newSocket();
1170 socket->connectToHost("127.0.0.1", thread->serverPort);
1171 if (!data.isEmpty())
1172 socket->write(data);
1173 if (socket->state() == QAbstractSocket::ConnectedState) {
1174 QSKIP("localhost connections are immediate, test case is invalid", SkipSingle);
1177 QFETCH(bool, closeDirectly);
1178 if (closeDirectly) {
1180 QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
1182 socket->disconnectFromHost();
1185 #ifndef Q_OS_SYMBIAN
1186 QVERIFY2(socket->waitForDisconnected(10000), "Network timeout");
1188 QVERIFY2(socket->waitForDisconnected(30000), "Network timeout");
1190 QVERIFY(socket->state() == QAbstractSocket::UnconnectedState);
1191 if (!closeDirectly) {
1192 QCOMPARE(int(socket->openMode()), int(QIODevice::ReadWrite));
1195 QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
1198 // check if the other side received everything ok
1199 QVERIFY(thread->wait(30000));
1200 QVERIFY(thread->ok);
1201 QCOMPARE(thread->receivedData, data);
1204 //----------------------------------------------------------------------------------
1205 void tst_QTcpSocket::disconnectWhileLookingUp_data()
1207 QTest::addColumn<bool>("doClose");
1209 QTest::newRow("disconnect") << false;
1210 QTest::newRow("close") << true;
1213 void tst_QTcpSocket::disconnectWhileLookingUp()
1215 QFETCH_GLOBAL(bool, setProxy);
1217 return; // we let the proxies do the lookup now
1219 // just connect and disconnect, then make sure nothing weird happened
1220 QTcpSocket *socket = newSocket();
1221 socket->connectToHost(QtNetworkSettings::serverName(), 21);
1223 // check that connect is in progress
1224 QVERIFY(socket->state() != QAbstractSocket::UnconnectedState);
1226 QFETCH(bool, doClose);
1229 QVERIFY(socket->openMode() == QIODevice::NotOpen);
1231 socket->disconnectFromHost();
1232 QVERIFY(socket->openMode() == QIODevice::ReadWrite);
1235 // let anything queued happen
1237 #ifndef Q_OS_SYMBIAN
1238 QTimer::singleShot(50, &loop, SLOT(quit()));
1240 QTimer::singleShot(5000, &loop, SLOT(quit()));
1246 QVERIFY(socket->openMode() == QIODevice::NotOpen);
1248 QVERIFY(socket->openMode() == QIODevice::ReadWrite);
1251 QVERIFY(socket->state() == QAbstractSocket::UnconnectedState);
1254 //----------------------------------------------------------------------------------
1255 void tst_QTcpSocket::downloadBigFile()
1259 tmpSocket = newSocket();
1261 connect(tmpSocket, SIGNAL(connected()), SLOT(exitLoopSlot()));
1262 connect(tmpSocket, SIGNAL(readyRead()), SLOT(downloadBigFileSlot()));
1263 connect(tmpSocket, SIGNAL(disconnected()), SLOT(exitLoopSlot()));
1265 tmpSocket->connectToHost(QtNetworkSettings::serverName(), 80);
1271 QFAIL("Network operation timed out");
1274 QByteArray hostName = QtNetworkSettings::serverName().toLatin1();
1275 QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState);
1276 QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0);
1277 QVERIFY(tmpSocket->write("HOST: ") > 0);
1278 QVERIFY(tmpSocket->write(hostName.data()) > 0);
1279 QVERIFY(tmpSocket->write("\r\n") > 0);
1280 QVERIFY(tmpSocket->write("\r\n") > 0);
1284 readingBody = false;
1293 if (bytesAvailable > 0)
1294 qDebug("Slow Connection, only downloaded %ld of %d", long(bytesAvailable), 10000281);
1295 QFAIL("Network operation timed out");
1298 QCOMPARE(bytesAvailable, expectedLength);
1300 qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
1301 bytesAvailable / (1024.0 * 1024.0),
1302 stopWatch.elapsed() / 1024.0,
1303 (bytesAvailable / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));
1309 //----------------------------------------------------------------------------------
1310 void tst_QTcpSocket::exitLoopSlot()
1315 //----------------------------------------------------------------------------------
1316 void tst_QTcpSocket::downloadBigFileSlot()
1319 while (tmpSocket->canReadLine()) {
1320 QByteArray array = tmpSocket->readLine();
1321 if (array.startsWith("Content-Length"))
1322 expectedLength = array.simplified().split(' ').at(1).toInt();
1323 if (array == "\r\n") {
1330 bytesAvailable += tmpSocket->readAll().size();
1331 if (bytesAvailable == expectedLength)
1336 //----------------------------------------------------------------------------------
1337 void tst_QTcpSocket::readLine()
1339 QTcpSocket *socket = newSocket();
1340 socket->connectToHost(QtNetworkSettings::serverName(), 143);
1341 QVERIFY(socket->waitForConnected(5000));
1343 while (!socket->canReadLine())
1344 QVERIFY(socket->waitForReadyRead(10000));
1348 qint64 linelen = socket->readLine(buffer, sizeof(buffer));
1349 QVERIFY(linelen >= 3);
1350 QVERIFY(linelen < 1024);
1352 QByteArray reply = QByteArray::fromRawData(buffer, linelen);
1353 QCOMPARE((int) buffer[linelen-2], (int) '\r');
1354 QCOMPARE((int) buffer[linelen-1], (int) '\n');
1355 QCOMPARE((int) buffer[linelen], (int) '\0');
1357 QVERIFY2(QtNetworkSettings::compareReplyIMAP(reply), reply.constData());
1359 QCOMPARE(socket->write("1 NOOP\r\n"), qint64(8));
1361 while (socket->bytesAvailable() < 10)
1362 QVERIFY(socket->waitForReadyRead(10000));
1364 QCOMPARE(socket->readLine(buffer, 11), qint64(10));
1365 QCOMPARE((const char *)buffer, "1 OK Compl");
1367 while (socket->bytesAvailable() < 6)
1368 QVERIFY(socket->waitForReadyRead(10000));
1370 QCOMPARE(socket->readLine(buffer, 11), qint64(6));
1371 QCOMPARE((const char *)buffer, "eted\r\n");
1373 QVERIFY(!socket->waitForReadyRead(100));
1374 QCOMPARE(socket->readLine(buffer, sizeof(buffer)), qint64(0));
1375 QVERIFY(socket->error() == QAbstractSocket::SocketTimeoutError
1376 || socket->error() == QAbstractSocket::RemoteHostClosedError);
1377 QCOMPARE(socket->bytesAvailable(), qint64(0));
1380 QCOMPARE(socket->readLine(buffer, sizeof(buffer)), qint64(-1));
1385 //----------------------------------------------------------------------------------
1386 void tst_QTcpSocket::readLineString()
1388 QTcpSocket *socket = newSocket();
1389 socket->connectToHost(QtNetworkSettings::serverName(), 143);
1390 QVERIFY(socket->waitForReadyRead(10000));
1392 QByteArray arr = socket->readLine();
1393 QVERIFY2(QtNetworkSettings::compareReplyIMAP(arr), arr.constData());
1398 //----------------------------------------------------------------------------------
1399 void tst_QTcpSocket::readChunks()
1401 QTcpSocket *socket = newSocket();
1402 socket->connectToHost(QtNetworkSettings::serverName(), 143);
1403 QVERIFY(socket->waitForConnected(10000));
1404 QVERIFY(socket->waitForReadyRead(5000));
1407 memset(buf, '@', sizeof(buf));
1408 qint64 dataLength = socket->read(buf, sizeof(buf));
1409 QVERIFY(dataLength > 0);
1411 QCOMPARE(buf[dataLength - 2], '\r');
1412 QCOMPARE(buf[dataLength - 1], '\n');
1413 QCOMPARE(buf[dataLength], '@');
1418 //----------------------------------------------------------------------------------
1419 void tst_QTcpSocket::waitForBytesWritten()
1421 QTcpSocket *socket = newSocket();
1422 socket->connectToHost(QtNetworkSettings::serverName(), 80);
1423 QVERIFY(socket->waitForConnected(10000));
1425 socket->write("GET / HTTP/1.0\r\n\r\n");
1426 qint64 toWrite = socket->bytesToWrite();
1427 QVERIFY(socket->waitForBytesWritten(5000));
1428 QVERIFY(toWrite > socket->bytesToWrite());
1433 //----------------------------------------------------------------------------------
1434 void tst_QTcpSocket::waitForBytesWrittenMinusOne()
1436 QTcpSocket *socket = newSocket();
1437 socket->connectToHost(QtNetworkSettings::serverName(), 80);
1438 QVERIFY(socket->waitForConnected(10000));
1440 socket->write("GET / HTTP/1.0\r\n\r\n");
1441 qint64 toWrite = socket->bytesToWrite();
1442 QVERIFY(socket->waitForBytesWritten(-1));
1443 QVERIFY(toWrite > socket->bytesToWrite());
1448 //----------------------------------------------------------------------------------
1449 void tst_QTcpSocket::waitForReadyRead()
1451 QTcpSocket *socket = newSocket();
1452 socket->connectToHost(QtNetworkSettings::serverName(), 80);
1453 socket->write("GET / HTTP/1.0\r\n\r\n");
1454 QVERIFY(socket->waitForReadyRead(5000));
1458 //----------------------------------------------------------------------------------
1459 void tst_QTcpSocket::waitForReadyReadMinusOne()
1461 QTcpSocket *socket = newSocket();
1462 socket->connectToHost(QtNetworkSettings::serverName(), 80);
1463 socket->write("GET / HTTP/1.0\r\n\r\n");
1464 QVERIFY(socket->waitForReadyRead(-1));
1468 //----------------------------------------------------------------------------------
1469 void tst_QTcpSocket::flush()
1471 QTcpSocket *socket = newSocket();
1474 connect(socket, SIGNAL(connected()), SLOT(exitLoopSlot()));
1475 socket->connectToHost(QtNetworkSettings::serverName(), 143);
1477 QVERIFY(socket->isOpen());
1479 socket->write("1 LOGOUT\r\n");
1480 QCOMPARE(socket->bytesToWrite(), qint64(10));
1482 QCOMPARE(socket->bytesToWrite(), qint64(0));
1488 //----------------------------------------------------------------------------------
1489 void tst_QTcpSocket::synchronousApi()
1491 QTcpSocket *ftpSocket = newSocket();
1492 ftpSocket->connectToHost(QtNetworkSettings::serverName(), 21);
1493 ftpSocket->write("QUIT\r\n");
1494 QVERIFY(ftpSocket->waitForDisconnected(10000));
1495 QVERIFY(ftpSocket->bytesAvailable() > 0);
1496 QByteArray arr = ftpSocket->readAll();
1497 QVERIFY(arr.size() > 0);
1501 //----------------------------------------------------------------------------------
1502 void tst_QTcpSocket::dontCloseOnTimeout()
1505 server.setProxy(QNetworkProxy(QNetworkProxy::NoProxy));
1506 QVERIFY(server.listen());
1508 QHostAddress serverAddress = QHostAddress::LocalHost;
1509 if (!(server.serverAddress() == QHostAddress::Any) && !(server.serverAddress() == QHostAddress::AnyIPv6))
1510 serverAddress = server.serverAddress();
1512 QTcpSocket *socket = newSocket();
1513 socket->connectToHost(serverAddress, server.serverPort());
1514 #ifndef Q_OS_SYMBIAN
1515 QVERIFY(!socket->waitForReadyRead(100));
1517 QVERIFY(!socket->waitForReadyRead(5000));
1519 QCOMPARE(socket->error(), QTcpSocket::SocketTimeoutError);
1520 QVERIFY(socket->isOpen());
1522 #ifndef Q_OS_SYMBIAN
1523 QVERIFY(!socket->waitForDisconnected(100));
1525 QVERIFY(!socket->waitForDisconnected(5000));
1527 QCOMPARE(socket->error(), QTcpSocket::SocketTimeoutError);
1528 QVERIFY(socket->isOpen());
1533 //----------------------------------------------------------------------------------
1534 void tst_QTcpSocket::recursiveReadyRead()
1536 QTcpSocket *smtp = newSocket();
1537 connect(smtp, SIGNAL(connected()), SLOT(exitLoopSlot()));
1538 connect(smtp, SIGNAL(readyRead()), SLOT(recursiveReadyReadSlot()));
1541 QSignalSpy spy(smtp, SIGNAL(readyRead()));
1543 smtp->connectToHost("smtp.trolltech.com", 25);
1545 QVERIFY2(!timeout(),
1546 "Timed out when connecting to smtp.trolltech.com:25");
1549 QVERIFY2(!timeout(),
1550 "Timed out when waiting for the readyRead() signal");
1552 QCOMPARE(spy.count(), 1);
1557 void tst_QTcpSocket::recursiveReadyReadSlot()
1559 // make sure the server spits out more data
1560 tmpSocket->write("NOOP\r\n");
1563 // indiscriminately enter the event loop and start processing
1564 // events again. but oops! future socket notifications will cause
1565 // undesired recursive behavior. Unless QTcpSocket is smart, which
1566 // it of course is. :-)
1568 for (int i = 0; i < 100; ++i)
1569 loop.processEvents();
1571 // all we really wanted to do was process some events, then exit
1576 //----------------------------------------------------------------------------------
1577 void tst_QTcpSocket::atEnd()
1579 QTcpSocket *socket = newSocket();
1580 socket->connectToHost(QtNetworkSettings::serverName(), 21);
1582 QVERIFY(socket->waitForReadyRead(15000));
1583 QTextStream stream(socket);
1584 QVERIFY(!stream.atEnd());
1585 QString greeting = stream.readLine();
1586 QVERIFY(stream.atEnd());
1588 // Test server must use some vsFTPd 2.x.x version
1589 QVERIFY2(greeting.length() == sizeof("220 (vsFTPd 2.x.x)")-1, qPrintable(greeting));
1590 QVERIFY2(greeting.startsWith("220 (vsFTPd 2."), qPrintable(greeting));
1591 QVERIFY2(greeting.endsWith(")"), qPrintable(greeting));
1596 class TestThread : public QThread
1601 inline QByteArray data() const
1609 #ifndef QT_NO_OPENSSL
1610 QFETCH_GLOBAL(bool, ssl);
1612 socket = new QSslSocket;
1615 socket = new QTcpSocket;
1616 connect(socket, SIGNAL(readyRead()), this, SLOT(getData()), Qt::DirectConnection);
1617 connect(socket, SIGNAL(disconnected()), this, SLOT(closed()), Qt::DirectConnection);
1618 connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
1619 SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), Qt::DirectConnection);
1621 socket->connectToHost(QtNetworkSettings::serverName(), 21);
1622 socket->write("QUIT\r\n");
1629 inline void getData()
1631 socketData += socket->readAll();
1634 inline void closed()
1638 inline void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
1640 auth->setUser("qsockstest");
1641 auth->setPassword("password");
1646 QByteArray socketData;
1649 //----------------------------------------------------------------------------------
1650 void tst_QTcpSocket::socketInAThread()
1652 for (int i = 0; i < 3; ++i) {
1655 QVERIFY(thread.wait(15000));
1656 QByteArray data = thread.data();
1657 QVERIFY2(QtNetworkSettings::compareReplyFtp(data), data.constData());
1661 //----------------------------------------------------------------------------------
1662 void tst_QTcpSocket::socketsInThreads()
1664 for (int i = 0; i < 3; ++i) {
1673 QVERIFY(thread2.wait(15000));
1674 QVERIFY(thread3.wait(15000));
1675 QVERIFY(thread1.wait(15000));
1677 QByteArray data1 = thread1.data();
1678 QByteArray data2 = thread2.data();
1679 QByteArray data3 = thread3.data();
1681 QVERIFY2(QtNetworkSettings::compareReplyFtp(data1), data1.constData());
1682 QVERIFY2(QtNetworkSettings::compareReplyFtp(data2), data2.constData());
1683 QVERIFY2(QtNetworkSettings::compareReplyFtp(data3), data3.constData());
1687 //----------------------------------------------------------------------------------
1688 void tst_QTcpSocket::waitForReadyReadInASlot()
1690 QTcpSocket *socket = newSocket();
1692 connect(socket, SIGNAL(connected()), this, SLOT(waitForReadyReadInASlotSlot()));
1694 socket->connectToHost(QtNetworkSettings::serverName(), 80);
1695 socket->write("GET / HTTP/1.0\r\n\r\n");
1698 QVERIFY(!timeout());
1703 void tst_QTcpSocket::waitForReadyReadInASlotSlot()
1705 QVERIFY(tmpSocket->waitForReadyRead(10000));
1709 class RemoteCloseErrorServer : public QTcpServer
1713 RemoteCloseErrorServer()
1715 connect(this, SIGNAL(newConnection()),
1716 this, SLOT(getConnection()));
1720 void getConnection()
1722 tst_QTcpSocket::exitLoop();
1726 //----------------------------------------------------------------------------------
1727 void tst_QTcpSocket::remoteCloseError()
1729 QFETCH_GLOBAL(bool, setProxy);
1731 return; //proxy not useful for localhost test case
1732 RemoteCloseErrorServer server;
1733 QVERIFY(server.listen(QHostAddress::LocalHost));
1735 QCoreApplication::instance()->processEvents();
1737 QTcpSocket *clientSocket = newSocket();
1738 connect(clientSocket, SIGNAL(readyRead()), this, SLOT(exitLoopSlot()));
1740 clientSocket->connectToHost(server.serverAddress(), server.serverPort());
1743 QVERIFY(!timeout());
1745 QVERIFY(server.hasPendingConnections());
1746 QTcpSocket *serverSocket = server.nextPendingConnection();
1747 connect(clientSocket, SIGNAL(disconnected()), this, SLOT(exitLoopSlot()));
1749 serverSocket->write("Hello");
1752 QVERIFY(!timeout());
1754 QCOMPARE(clientSocket->bytesAvailable(), qint64(5));
1756 qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
1757 QSignalSpy errorSpy(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)));
1758 QSignalSpy disconnectedSpy(clientSocket, SIGNAL(disconnected()));
1760 clientSocket->write("World");
1761 serverSocket->disconnectFromHost();
1763 tmpSocket = clientSocket;
1764 connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
1765 this, SLOT(remoteCloseErrorSlot()));
1768 QVERIFY(!timeout());
1770 QCOMPARE(disconnectedSpy.count(), 1);
1771 QCOMPARE(errorSpy.count(), 1);
1772 QCOMPARE(clientSocket->error(), QAbstractSocket::RemoteHostClosedError);
1774 delete serverSocket;
1776 clientSocket->connectToHost(server.serverAddress(), server.serverPort());
1779 QVERIFY(!timeout());
1781 QVERIFY(server.hasPendingConnections());
1782 serverSocket = server.nextPendingConnection();
1783 serverSocket->disconnectFromHost();
1786 QVERIFY(!timeout());
1788 QCOMPARE(clientSocket->state(), QAbstractSocket::UnconnectedState);
1790 delete clientSocket;
1793 void tst_QTcpSocket::remoteCloseErrorSlot()
1795 QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState);
1796 static_cast<QTcpSocket *>(sender())->close();
1799 void tst_QTcpSocket::messageBoxSlot()
1801 #if !defined(Q_OS_VXWORKS) // no gui
1802 QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
1803 socket->deleteLater();
1805 QTimer::singleShot(100, &box, SLOT(close()));
1807 // This should not delete the socket
1810 // Fire a non-0 singleshot to leave time for the delete
1811 QTimer::singleShot(250, this, SLOT(exitLoopSlot()));
1814 //----------------------------------------------------------------------------------
1815 void tst_QTcpSocket::openMessageBoxInErrorSlot()
1817 #if defined(Q_OS_VXWORKS) // no gui
1818 QSKIP("no default gui available on VxWorks", SkipAll);
1820 QTcpSocket *socket = newSocket();
1821 QPointer<QTcpSocket> p(socket);
1822 connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(messageBoxSlot()));
1824 socket->connectToHost("hostnotfoundhostnotfound.troll.no", 9999); // Host not found, fyi
1830 //----------------------------------------------------------------------------------
1832 void tst_QTcpSocket::connectToLocalHostNoService()
1834 // This test was created after we received a report that claimed
1835 // QTcpSocket would crash if trying to connect to "localhost" on a random
1836 // port with no service listening.
1837 QTcpSocket *socket = newSocket();
1838 socket->connectToHost("localhost", 31415); // no service running here, one suspects
1840 while(socket->state() == QTcpSocket::HostLookupState || socket->state() == QTcpSocket::ConnectingState) {
1843 QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
1848 //----------------------------------------------------------------------------------
1849 void tst_QTcpSocket::waitForConnectedInHostLookupSlot()
1851 // This test tries to reproduce the problem where waitForConnected() is
1852 // called at a point where the host lookup is already done. QTcpSocket
1853 // will try to abort the "pending lookup", but since it's already done and
1854 // the queued signal is already underway, we will receive the signal after
1855 // waitForConnected() has returned, and control goes back to the event
1856 // loop. When the signal has been received, the connection is torn down,
1857 // then reopened. Yikes. If we reproduce this by calling
1858 // waitForConnected() inside hostLookupSlot(), it will even crash.
1859 tmpSocket = newSocket();
1861 connect(tmpSocket, SIGNAL(connected()), &loop, SLOT(quit()));
1863 connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
1864 QSignalSpy timerSpy(&timer, SIGNAL(timeout()));
1867 connect(tmpSocket, SIGNAL(hostFound()), this, SLOT(hostLookupSlot()));
1868 tmpSocket->connectToHost(QtNetworkSettings::serverName(), 143);
1870 // only execute the loop if not already connected
1871 if (tmpSocket->state() != QAbstractSocket::ConnectedState)
1874 QCOMPARE(timerSpy.count(), 0);
1879 void tst_QTcpSocket::hostLookupSlot()
1881 // This will fail to cancel the pending signal
1882 QVERIFY(tmpSocket->waitForConnected(10000));
1885 class Foo : public QObject
1890 bool attemptedToConnect;
1891 bool networkTimeout;
1894 inline Foo(QObject *parent = 0) : QObject(parent)
1896 attemptedToConnect = false;
1897 networkTimeout = false;
1899 #ifndef QT_NO_OPENSSL
1900 QFETCH_GLOBAL(bool, ssl);
1902 sock = new QSslSocket;
1905 sock = new QTcpSocket;
1906 connect(sock, SIGNAL(connected()), this, SLOT(connectedToIt()));
1907 connect(sock, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
1908 SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
1917 inline void connectedToIt()
1922 attemptedToConnect = true;
1923 sock->connectToHost(QtNetworkSettings::serverName(), 80);
1927 #elif defined Q_OS_LINUX
1930 if (!sock->waitForConnected()) {
1931 networkTimeout = true;
1933 tst_QTcpSocket::exitLoop();
1936 inline void exitLoop()
1938 tst_QTcpSocket::exitLoop();
1941 inline void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
1943 auth->setUser("qsockstest");
1944 auth->setPassword("password");
1948 //----------------------------------------------------------------------------------
1949 void tst_QTcpSocket::waitForConnectedInHostLookupSlot2()
1951 #if defined(Q_OS_WIN) || defined(Q_OS_VXWORKS)
1952 QSKIP("waitForConnectedInHostLookupSlot2 is not run on Windows and VxWorks", SkipAll);
1956 QPushButton top("Go", 0);
1958 connect(&top, SIGNAL(clicked()), &foo, SLOT(doIt()));
1960 QTimer::singleShot(100, &top, SLOT(animateClick()));
1961 QTimer::singleShot(5000, &foo, SLOT(exitLoop()));
1964 if (timeout() || foo.networkTimeout)
1965 QFAIL("Network timeout");
1967 QVERIFY(foo.attemptedToConnect);
1968 QCOMPARE(foo.count, 1);
1972 //----------------------------------------------------------------------------------
1973 void tst_QTcpSocket::readyReadSignalsAfterWaitForReadyRead()
1975 QTcpSocket *socket = newSocket();
1977 QSignalSpy readyReadSpy(socket, SIGNAL(readyRead()));
1980 socket->connectToHost(QtNetworkSettings::serverName(), 143);
1982 // Wait for the read
1983 QVERIFY(socket->waitForReadyRead(10000));
1985 QCOMPARE(readyReadSpy.count(), 1);
1987 QString s = socket->readLine();
1988 QVERIFY2(QtNetworkSettings::compareReplyIMAP(s.toLatin1()), s.toLatin1().constData());
1989 QCOMPARE(socket->bytesAvailable(), qint64(0));
1991 QCoreApplication::instance()->processEvents();
1992 QCOMPARE(socket->bytesAvailable(), qint64(0));
1993 QCOMPARE(readyReadSpy.count(), 1);
1998 class TestThread2 : public QThread
2004 QFile fileWriter("fifo");
2005 QVERIFY(fileWriter.open(QFile::WriteOnly));
2006 QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
2007 QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
2008 QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
2009 QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
2013 //----------------------------------------------------------------------------------
2015 void tst_QTcpSocket::linuxKernelBugLocalSocket()
2017 QFile::remove("fifo");
2018 mkfifo("fifo", 0666);
2023 QFile fileReader("fifo");
2024 QVERIFY(fileReader.open(QFile::ReadOnly));
2028 QTcpSocket *socket = newSocket();
2029 socket->setSocketDescriptor(fileReader.handle());
2030 QVERIFY(socket->waitForReadyRead(5000));
2031 QCOMPARE(socket->bytesAvailable(), qint64(128));
2033 QFile::remove("fifo");
2039 //----------------------------------------------------------------------------------
2040 void tst_QTcpSocket::abortiveClose()
2042 QFETCH_GLOBAL(bool, setProxy);
2044 return; //proxy not useful for localhost test case
2046 QVERIFY(server.listen(QHostAddress::LocalHost));
2047 connect(&server, SIGNAL(newConnection()), this, SLOT(exitLoopSlot()));
2049 QTcpSocket *clientSocket = newSocket();
2050 clientSocket->connectToHost(server.serverAddress(), server.serverPort());
2053 QVERIFY(server.hasPendingConnections());
2055 QVERIFY(tmpSocket = server.nextPendingConnection());
2057 qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
2058 QSignalSpy readyReadSpy(clientSocket, SIGNAL(readyRead()));
2059 QSignalSpy errorSpy(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)));
2061 connect(clientSocket, SIGNAL(disconnected()), this, SLOT(exitLoopSlot()));
2062 QTimer::singleShot(0, this, SLOT(abortiveClose_abortSlot()));
2066 QCOMPARE(readyReadSpy.count(), 0);
2067 QCOMPARE(errorSpy.count(), 1);
2069 QCOMPARE(*static_cast<const int *>(errorSpy.at(0).at(0).constData()),
2070 int(QAbstractSocket::RemoteHostClosedError));
2072 delete clientSocket;
2075 void tst_QTcpSocket::abortiveClose_abortSlot()
2080 //----------------------------------------------------------------------------------
2081 void tst_QTcpSocket::localAddressEmptyOnBSD()
2083 QFETCH_GLOBAL(bool, setProxy);
2085 return; //proxy not useful for localhost test case
2087 QVERIFY(server.listen(QHostAddress::LocalHost));
2089 QTcpSocket *tcpSocket = 0;
2090 // we try 10 times, but note that this doesn't always provoke the bug
2091 for (int i = 0; i < 10; ++i) {
2093 tcpSocket = newSocket();
2094 tcpSocket->connectToHost(QHostAddress::LocalHost, server.serverPort());
2095 if (!tcpSocket->waitForConnected(0)) {
2096 // to provoke the bug, we need a local socket that connects immediately
2099 if (tcpSocket->state() != QTcpSocket::UnconnectedState)
2100 QVERIFY(tcpSocket->waitForDisconnected(-1));
2103 QCOMPARE(tcpSocket->localAddress(), QHostAddress(QHostAddress::LocalHost));
2108 //----------------------------------------------------------------------------------
2109 void tst_QTcpSocket::zeroAndMinusOneReturns()
2111 QTcpSocket *socket = newSocket();
2112 socket->connectToHost(QtNetworkSettings::serverName(), 80);
2113 socket->write("GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n");
2114 QVERIFY(socket->waitForReadyRead(15000));
2117 QVERIFY(socket->getChar(c));
2118 QCOMPARE(socket->read(c, 16), qint64(16));
2119 QVERIFY(socket->readLine(c, 16) > 0);
2120 QVERIFY(!socket->readAll().isEmpty());
2122 // the last operation emptied the read buffer
2123 // all read operations from this point on should fail
2124 // with return 0 because the socket is still open
2125 QVERIFY(socket->readAll().isEmpty());
2126 QCOMPARE(socket->read(c, 16), qint64(0));
2127 QCOMPARE(socket->readLine(c, 16), qint64(0));
2128 QVERIFY(!socket->getChar(c));
2130 socket->write("GET / HTTP/1.0\r\n\r\n");
2131 QVERIFY(socket->waitForDisconnected(15000));
2132 QCOMPARE(socket->error(), QAbstractSocket::RemoteHostClosedError);
2134 QCOMPARE(socket->write("BLUBBER"), qint64(-1));
2135 QVERIFY(socket->getChar(c));
2136 QCOMPARE(socket->read(c, 16), qint64(16));
2137 QVERIFY(socket->readLine(c, 16) > 0);
2138 QVERIFY(!socket->readAll().isEmpty());
2140 // the last operation emptied the read buffer
2141 // all read operations from this point on should fail
2142 // with return -1 because the socket is not connected
2143 QVERIFY(socket->readAll().isEmpty());
2144 QCOMPARE(socket->read(c, 16), qint64(-1));
2145 QCOMPARE(socket->readLine(c, 16), qint64(-1));
2146 QVERIFY(!socket->getChar(c));
2147 QVERIFY(!socket->putChar('a'));
2151 // now the QIODevice is closed, which means getChar complains
2152 QCOMPARE(socket->write("BLUBBER"), qint64(-1));
2153 QCOMPARE(socket->read(c, 16), qint64(-1));
2154 QCOMPARE(socket->readLine(c, 16), qint64(-1));
2155 QVERIFY(!socket->getChar(c));
2156 QVERIFY(!socket->putChar('a'));
2161 //----------------------------------------------------------------------------------
2162 void tst_QTcpSocket::connectionRefused()
2164 qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
2165 qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState");
2167 QTcpSocket *socket = newSocket();
2168 QSignalSpy stateSpy(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)));
2169 QSignalSpy errorSpy(socket, SIGNAL(error(QAbstractSocket::SocketError)));
2170 connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
2171 &QTestEventLoop::instance(), SLOT(exitLoop()));
2173 socket->connectToHost(QtNetworkSettings::serverName(), 144);
2176 disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
2177 &QTestEventLoop::instance(), SLOT(exitLoop()));
2178 QVERIFY2(!timeout(), "Network timeout");
2180 QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
2181 QCOMPARE(socket->error(), QAbstractSocket::ConnectionRefusedError);
2183 QCOMPARE(stateSpy.count(), 3);
2184 QCOMPARE(qVariantValue<QAbstractSocket::SocketState>(stateSpy.at(0).at(0)), QAbstractSocket::HostLookupState);
2185 QCOMPARE(qVariantValue<QAbstractSocket::SocketState>(stateSpy.at(1).at(0)), QAbstractSocket::ConnectingState);
2186 QCOMPARE(qVariantValue<QAbstractSocket::SocketState>(stateSpy.at(2).at(0)), QAbstractSocket::UnconnectedState);
2187 QCOMPARE(errorSpy.count(), 1);
2192 //----------------------------------------------------------------------------------
2193 void tst_QTcpSocket::suddenRemoteDisconnect_data()
2195 QTest::addColumn<QString>("client");
2196 QTest::addColumn<QString>("server");
2198 QTest::newRow("Qt4 Client <-> Qt4 Server") << QString::fromLatin1("qt4client") << QString::fromLatin1("qt4server");
2201 void tst_QTcpSocket::suddenRemoteDisconnect()
2203 #if defined( Q_OS_SYMBIAN )
2204 QSKIP("Symbian: QProcess IO is not yet supported, fix when supported", SkipAll);
2206 QFETCH(QString, client);
2207 QFETCH(QString, server);
2209 QFETCH_GLOBAL(bool, setProxy);
2212 QFETCH_GLOBAL(bool, ssl);
2217 QProcess serverProcess;
2218 serverProcess.setReadChannel(QProcess::StandardError);
2219 serverProcess.start(QString::fromLatin1("stressTest/stressTest %1").arg(server),
2220 QIODevice::ReadWrite | QIODevice::Text);
2221 while (!serverProcess.canReadLine())
2222 QVERIFY(serverProcess.waitForReadyRead(10000));
2223 QCOMPARE(serverProcess.readLine().data(), (server.toLatin1() + "\n").data());
2226 QProcess clientProcess;
2227 clientProcess.setReadChannel(QProcess::StandardError);
2228 clientProcess.start(QString::fromLatin1("stressTest/stressTest %1").arg(client),
2229 QIODevice::ReadWrite | QIODevice::Text);
2230 while (!clientProcess.canReadLine())
2231 QVERIFY(clientProcess.waitForReadyRead(10000));
2232 QCOMPARE(clientProcess.readLine().data(), (client.toLatin1() + "\n").data());
2234 // Let them play for a while
2235 qDebug("Running stress test for 5 seconds");
2237 connect(&serverProcess, SIGNAL(finished(int)), &loop, SLOT(quit()));
2238 connect(&clientProcess, SIGNAL(finished(int)), &loop, SLOT(quit()));
2241 QTimer::singleShot(20000, &loop, SLOT(quit()));
2243 while ((serverProcess.state() == QProcess::Running
2244 || clientProcess.state() == QProcess::Running) && stopWatch.elapsed() < 20000)
2247 QVERIFY(stopWatch.elapsed() < 20000);
2249 // Check that both exited normally.
2250 QCOMPARE(clientProcess.readAll().constData(), "SUCCESS\n");
2251 QCOMPARE(serverProcess.readAll().constData(), "SUCCESS\n");
2255 //----------------------------------------------------------------------------------
2256 void tst_QTcpSocket::connectToMultiIP()
2258 QSKIP("TODO: setup DNS in the new network", SkipAll);
2260 #if defined(Q_OS_VXWORKS)
2261 QSKIP("VxSim in standard config doesn't even run a DNS resolver", SkipAll);
2263 QFETCH_GLOBAL(bool, ssl);
2266 QFETCH_GLOBAL(bool, setProxy);
2268 QSKIP("This test takes too long if we also add the proxies.", SkipSingle);
2270 qDebug("Please wait, this test can take a while...");
2272 QTcpSocket *socket = newSocket();
2273 // rationale: this domain resolves to 3 A-records, 2 of them are
2274 // invalid. QTcpSocket should never spend more than 30 seconds per IP, and
2278 socket->connectToHost("multi.dev.troll.no", 80);
2279 QVERIFY(socket->waitForConnected(60500));
2280 QVERIFY(stopWatch.elapsed() < 70000);
2283 stopWatch.restart();
2284 socket->connectToHost("multi.dev.troll.no", 81);
2285 QVERIFY(!socket->waitForConnected(2000));
2286 QVERIFY(stopWatch.elapsed() < 2000);
2287 QCOMPARE(socket->error(), QAbstractSocket::SocketTimeoutError);
2293 //----------------------------------------------------------------------------------
2294 void tst_QTcpSocket::moveToThread0()
2296 QFETCH_GLOBAL(int, proxyType);
2297 if (proxyType & AuthMask)
2301 // Case 1: Moved after connecting, before waiting for connection.
2302 QTcpSocket *socket = newSocket();;
2303 socket->connectToHost(QtNetworkSettings::serverName(), 143);
2304 socket->moveToThread(0);
2305 QVERIFY(socket->waitForConnected(5000));
2306 socket->write("XXX LOGOUT\r\n");
2307 QVERIFY(socket->waitForBytesWritten(5000));
2308 QVERIFY(socket->waitForDisconnected());
2312 // Case 2: Moved before connecting
2313 QTcpSocket *socket = newSocket();
2314 socket->moveToThread(0);
2315 socket->connectToHost(QtNetworkSettings::serverName(), 143);
2316 QVERIFY(socket->waitForConnected(5000));
2317 socket->write("XXX LOGOUT\r\n");
2318 QVERIFY(socket->waitForBytesWritten(5000));
2319 QVERIFY(socket->waitForDisconnected());
2323 // Case 3: Moved after writing, while waiting for bytes to be written.
2324 QTcpSocket *socket = newSocket();
2325 socket->connectToHost(QtNetworkSettings::serverName(), 143);
2326 QVERIFY(socket->waitForConnected(5000));
2327 socket->write("XXX LOGOUT\r\n");
2328 socket->moveToThread(0);
2329 QVERIFY(socket->waitForBytesWritten(5000));
2330 QVERIFY(socket->waitForDisconnected());
2334 // Case 4: Moved after writing, while waiting for response.
2335 QTcpSocket *socket = newSocket();
2336 socket->connectToHost(QtNetworkSettings::serverName(), 143);
2337 QVERIFY(socket->waitForConnected(5000));
2338 socket->write("XXX LOGOUT\r\n");
2339 QVERIFY(socket->waitForBytesWritten(5000));
2340 socket->moveToThread(0);
2341 QVERIFY(socket->waitForDisconnected());
2346 void tst_QTcpSocket::increaseReadBufferSize()
2348 QFETCH_GLOBAL(bool, setProxy);
2350 return; //proxy not useful for localhost test case
2352 QTcpSocket *active = newSocket();
2353 connect(active, SIGNAL(readyRead()), SLOT(exitLoopSlot()));
2355 // connect two sockets to each other:
2356 QVERIFY(server.listen(QHostAddress::LocalHost));
2357 active->connectToHost("127.0.0.1", server.serverPort());
2358 QVERIFY(active->waitForConnected(5000));
2359 QVERIFY(server.waitForNewConnection(5000));
2361 QTcpSocket *passive = server.nextPendingConnection();
2364 // now write 512 bytes of data on one end
2365 QByteArray data(512, 'a');
2366 passive->write(data);
2367 QVERIFY2(passive->waitForBytesWritten(5000), "Network timeout");
2369 // set the read buffer size to less than what was written and iterate:
2370 active->setReadBufferSize(256);
2372 QVERIFY2(!timeout(), "Network timeout");
2373 QCOMPARE(active->bytesAvailable(), active->readBufferSize());
2375 // increase the buffer size and iterate again:
2376 active->setReadBufferSize(384);
2378 QVERIFY2(!timeout(), "Network timeout");
2379 QCOMPARE(active->bytesAvailable(), active->readBufferSize());
2381 // once more, but now it should read everything there was to read
2382 active->setReadBufferSize(1024);
2384 QVERIFY2(!timeout(), "Network timeout");
2385 QCOMPARE(active->bytesAvailable(), qint64(data.size()));
2387 // drain it and compare
2388 QCOMPARE(active->readAll(), data);
2390 // now one more test by setting the buffer size to unlimited:
2391 passive->write(data);
2392 QVERIFY2(passive->waitForBytesWritten(5000), "Network timeout");
2393 active->setReadBufferSize(256);
2395 QVERIFY2(!timeout(), "Network timeout");
2396 QCOMPARE(active->bytesAvailable(), active->readBufferSize());
2397 active->setReadBufferSize(0);
2399 QVERIFY2(!timeout(), "Network timeout");
2400 QCOMPARE(active->bytesAvailable(), qint64(data.size()));
2401 QCOMPARE(active->readAll(), data);
2406 void tst_QTcpSocket::taskQtBug5799ConnectionErrorWaitForConnected()
2408 QFETCH_GLOBAL(bool, setProxy);
2412 // check that we get a proper error connecting to port 12346
2413 // use waitForConnected, e.g. this should use a synchronous select() on the OS level
2416 socket.connectToHost(QtNetworkSettings::serverName(), 12346);
2419 socket.waitForConnected(10000);
2420 QVERIFY2(timer.elapsed() < 9900, "Connection to closed port timed out instead of refusing, something is wrong");
2421 QVERIFY2(socket.state() == QAbstractSocket::UnconnectedState, "Socket connected unexpectedly!");
2422 QVERIFY2(socket.error() == QAbstractSocket::ConnectionRefusedError,
2423 QString("Could not reach server: %1").arg(socket.errorString()).toLocal8Bit());
2426 void tst_QTcpSocket::taskQtBug5799ConnectionErrorEventLoop()
2428 QFETCH_GLOBAL(bool, setProxy);
2432 // check that we get a proper error connecting to port 12346
2433 // This testcase uses an event loop
2435 connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), &QTestEventLoop::instance(), SLOT(exitLoop()));
2436 socket.connectToHost(QtNetworkSettings::serverName(), 12346);
2438 QTestEventLoop::instance().enterLoop(10);
2439 QVERIFY2(!QTestEventLoop::instance().timeout(), "Connection to closed port timed out instead of refusing, something is wrong");
2440 QVERIFY2(socket.state() == QAbstractSocket::UnconnectedState, "Socket connected unexpectedly!");
2441 QVERIFY2(socket.error() == QAbstractSocket::ConnectionRefusedError,
2442 QString("Could not reach server: %1").arg(socket.errorString()).toLocal8Bit());
2445 void tst_QTcpSocket::taskQtBug7054TimeoutErrorResetting()
2447 QTcpSocket *socket = newSocket();
2449 socket->connectToHost(QtNetworkSettings::serverName(), 443);
2450 QVERIFY(socket->waitForConnected(5*1000));
2451 QVERIFY(socket->error() == QAbstractSocket::UnknownSocketError);
2453 // We connected to the HTTPS port. Wait two seconds to receive data. We will receive
2454 // nothing because we would need to start the SSL handshake
2455 QVERIFY(!socket->waitForReadyRead(2*1000));
2456 QVERIFY(socket->error() == QAbstractSocket::SocketTimeoutError);
2458 // Now write some crap to make the server disconnect us. 4 lines are enough.
2459 socket->write("a\r\nb\r\nc\r\nd\r\n");
2460 socket->waitForBytesWritten(2*1000);
2462 // we try to waitForReadyRead another time, but this time instead of a timeout we
2463 // should get a better error since the server disconnected us
2464 QVERIFY(!socket->waitForReadyRead(2*1000));
2465 // It must NOT be the SocketTimeoutError that had been set before
2466 QVERIFY(socket->error() == QAbstractSocket::RemoteHostClosedError);
2469 void tst_QTcpSocket::invalidProxy_data()
2471 QTest::addColumn<int>("type");
2472 QTest::addColumn<QString>("host");
2473 QTest::addColumn<int>("port");
2474 QTest::addColumn<bool>("failsAtConnect");
2475 QTest::addColumn<int>("expectedError");
2477 QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString();
2478 QTest::newRow("ftp-proxy") << int(QNetworkProxy::FtpCachingProxy) << fluke << 21 << true
2479 << int(QAbstractSocket::UnsupportedSocketOperationError);
2480 QTest::newRow("http-caching-proxy") << int(QNetworkProxy::HttpCachingProxy) << fluke << 3128 << true
2481 << int(QAbstractSocket::UnsupportedSocketOperationError);
2482 QTest::newRow("no-such-host-socks5") << int(QNetworkProxy::Socks5Proxy)
2483 << "this-host-will-never-exist.troll.no" << 1080 << false
2484 << int(QAbstractSocket::ProxyNotFoundError);
2485 QTest::newRow("no-such-host-http") << int(QNetworkProxy::HttpProxy)
2486 << "this-host-will-never-exist.troll.no" << 3128 << false
2487 << int(QAbstractSocket::ProxyNotFoundError);
2488 #if !defined(Q_OS_SYMBIAN)
2489 QTest::newRow("http-on-socks5") << int(QNetworkProxy::HttpProxy) << fluke << 1080 << false
2490 << int(QAbstractSocket::ProxyConnectionClosedError);
2491 QTest::newRow("socks5-on-http") << int(QNetworkProxy::Socks5Proxy) << fluke << 3128 << false
2492 << int(QAbstractSocket::SocketTimeoutError);
2496 void tst_QTcpSocket::invalidProxy()
2498 QFETCH_GLOBAL(bool, setProxy);
2503 QFETCH(QString, host);
2505 QFETCH(bool, failsAtConnect);
2506 QNetworkProxy::ProxyType proxyType = QNetworkProxy::ProxyType(type);
2507 QNetworkProxy proxy(proxyType, host, port);
2509 QTcpSocket *socket = newSocket();
2510 socket->setProxy(proxy);
2511 socket->connectToHost(QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(), 80);
2513 if (failsAtConnect) {
2514 QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
2516 QCOMPARE(socket->state(), QAbstractSocket::ConnectingState);
2517 QVERIFY(!socket->waitForConnected(5000));
2519 QVERIFY(!socket->errorString().isEmpty());
2521 // note: the following test is not a hard failure.
2522 // Sometimes, error codes change for the better
2523 QTEST(int(socket->error()), "expectedError");
2528 // copied from tst_qnetworkreply.cpp
2529 class MyProxyFactory: public QNetworkProxyFactory
2533 QList<QNetworkProxy> toReturn;
2534 QNetworkProxyQuery lastQuery;
2535 inline MyProxyFactory() { clear(); }
2540 toReturn = QList<QNetworkProxy>() << QNetworkProxy::DefaultProxy;
2541 lastQuery = QNetworkProxyQuery();
2544 virtual QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query)
2552 void tst_QTcpSocket::proxyFactory_data()
2554 QTest::addColumn<QList<QNetworkProxy> >("proxyList");
2555 QTest::addColumn<QNetworkProxy>("proxyUsed");
2556 QTest::addColumn<bool>("failsAtConnect");
2557 QTest::addColumn<int>("expectedError");
2559 QList<QNetworkProxy> proxyList;
2561 // tests that do connect
2563 proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3129);
2564 QTest::newRow("http")
2565 << proxyList << proxyList.at(0)
2566 << false << int(QAbstractSocket::UnknownSocketError);
2569 proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
2570 QTest::newRow("socks5")
2571 << proxyList << proxyList.at(0)
2572 << false << int(QAbstractSocket::UnknownSocketError);
2575 proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
2576 << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
2577 QTest::newRow("cachinghttp+socks5")
2578 << proxyList << proxyList.at(1)
2579 << false << int(QAbstractSocket::UnknownSocketError);
2582 proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121)
2583 << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
2584 << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
2585 QTest::newRow("ftp+cachinghttp+socks5")
2586 << proxyList << proxyList.at(2)
2587 << false << int(QAbstractSocket::UnknownSocketError);
2589 // tests that fail to connect
2591 proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
2592 QTest::newRow("cachinghttp")
2593 << proxyList << QNetworkProxy()
2594 << true << int(QAbstractSocket::UnsupportedSocketOperationError);
2597 proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121);
2598 QTest::newRow("ftp")
2599 << proxyList << QNetworkProxy()
2600 << true << int(QAbstractSocket::UnsupportedSocketOperationError);
2603 proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121)
2604 << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
2605 QTest::newRow("ftp+cachinghttp")
2606 << proxyList << QNetworkProxy()
2607 << true << int(QAbstractSocket::UnsupportedSocketOperationError);
2610 void tst_QTcpSocket::proxyFactory()
2612 QFETCH_GLOBAL(bool, setProxy);
2616 QFETCH(QList<QNetworkProxy>, proxyList);
2617 QFETCH(QNetworkProxy, proxyUsed);
2618 QFETCH(bool, failsAtConnect);
2620 MyProxyFactory *factory = new MyProxyFactory;
2621 factory->toReturn = proxyList;
2622 QNetworkProxyFactory::setApplicationProxyFactory(factory);
2624 QTcpSocket *socket = newSocket();
2625 QString host = QtNetworkSettings::serverName();
2626 socket->connectToHost(host, 80);
2628 // Verify that the factory was called properly
2629 QCOMPARE(factory->callCount, 1);
2630 QCOMPARE(factory->lastQuery, QNetworkProxyQuery(host, 80));
2632 if (failsAtConnect) {
2633 QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
2635 QCOMPARE(socket->state(), QAbstractSocket::ConnectingState);
2636 QVERIFY(socket->waitForConnected(5000));
2637 QCOMPARE(proxyAuthCalled, 1);
2639 QVERIFY(!socket->errorString().isEmpty());
2641 // note: the following test is not a hard failure.
2642 // Sometimes, error codes change for the better
2643 QTEST(int(socket->error()), "expectedError");
2648 // there is a similar test inside tst_qtcpserver that uses the event loop instead
2649 void tst_QTcpSocket::qtbug14268_peek()
2651 QFETCH_GLOBAL(bool, setProxy);
2655 SocketPair socketPair;
2656 QVERIFY(socketPair.create());
2657 QTcpSocket *outgoing = socketPair.endPoints[0];
2658 QTcpSocket *incoming = socketPair.endPoints[1];
2660 QVERIFY(incoming->state() == QTcpSocket::ConnectedState);
2661 QVERIFY(outgoing->state() == QTcpSocket::ConnectedState);
2663 outgoing->write("abc\n");
2664 QVERIFY(outgoing->waitForBytesWritten(2000));
2665 QVERIFY(incoming->waitForReadyRead(2000));
2666 QVERIFY(incoming->peek(128*1024) == QByteArray("abc\n"));
2668 outgoing->write("def\n");
2669 QVERIFY(outgoing->waitForBytesWritten(2000));
2670 QVERIFY(incoming->waitForReadyRead(2000));
2671 QVERIFY(incoming->peek(128*1024) == QByteArray("abc\ndef\n"));
2673 outgoing->write("ghi\n");
2674 QVERIFY(outgoing->waitForBytesWritten(2000));
2675 QVERIFY(incoming->waitForReadyRead(2000));
2676 QVERIFY(incoming->peek(128*1024) == QByteArray("abc\ndef\nghi\n"));
2678 QVERIFY(incoming->read(128*1024) == QByteArray("abc\ndef\nghi\n"));
2683 QTEST_MAIN(tst_QTcpSocket)
2684 #include "tst_qtcpsocket.moc"