1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the test suite of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
44
// To prevent windows system header files from re-defining min/max
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>
70
#include <QStringList>
76
#include <QTextStream>
81
// RVCT compiles also unused inline methods
82
# include <QNetworkProxy>
91
#include "private/qhostinfo_p.h"
93
#include "../../../network-settings.h"
95
QT_FORWARD_DECLARE_CLASS(QTcpSocket)
98
class tst_QTcpSocket : public QObject
104
virtual ~tst_QTcpSocket();
106
static void enterLoop(int secs)
109
QTestEventLoop::instance().enterLoop(secs);
112
static void exitLoop()
114
// Safe exit - if we aren't in an event loop, don't
117
QTestEventLoop::instance().exitLoop();
119
static bool timeout()
121
return QTestEventLoop::instance().timeout();
125
void initTestCase_data();
130
void socketsConstructedBeforeEventLoop();
134
void setInvalidSocketDescriptor();
135
void setSocketDescriptor();
136
void socketDescriptor();
138
void nonBlockingIMAP();
140
void timeoutConnect_data();
141
void timeoutConnect();
145
void readAllAfterClose();
146
void openCloseOpenClose();
147
void connectDisconnectConnectDisconnect();
148
void disconnectWhileConnecting_data();
149
void disconnectWhileConnecting();
150
void disconnectWhileConnectingNoEventLoop_data();
151
void disconnectWhileConnectingNoEventLoop();
152
void disconnectWhileLookingUp_data();
153
void disconnectWhileLookingUp();
154
void downloadBigFile();
156
void readLineString();
158
void waitForBytesWritten();
159
void waitForBytesWrittenMinusOne();
160
void waitForReadyRead();
161
void waitForReadyReadMinusOne();
163
void synchronousApi();
164
void dontCloseOnTimeout();
165
void recursiveReadyRead();
167
void socketInAThread();
168
void socketsInThreads();
169
void waitForReadyReadInASlot();
170
void remoteCloseError();
171
void nestedEventLoopInErrorSlot();
173
void connectToLocalHostNoService();
175
void waitForConnectedInHostLookupSlot();
176
void waitForConnectedInHostLookupSlot2();
177
void readyReadSignalsAfterWaitForReadyRead();
179
void linuxKernelBugLocalSocket();
181
void abortiveClose();
182
void localAddressEmptyOnBSD();
183
void zeroAndMinusOneReturns();
184
void connectionRefused();
185
void suddenRemoteDisconnect_data();
186
void suddenRemoteDisconnect();
187
void connectToMultiIP();
188
void moveToThread0();
189
void increaseReadBufferSize();
190
void taskQtBug5799ConnectionErrorWaitForConnected();
191
void taskQtBug5799ConnectionErrorEventLoop();
192
void taskQtBug7054TimeoutErrorResetting();
194
void invalidProxy_data();
196
void proxyFactory_data();
199
void qtbug14268_peek();
201
void setSocketOption();
205
void nonBlockingIMAP_hostFound();
206
void nonBlockingIMAP_connected();
207
void nonBlockingIMAP_closed();
208
void nonBlockingIMAP_readyRead();
209
void nonBlockingIMAP_bytesWritten(qint64);
210
void readRegularFile_readyRead();
212
void downloadBigFileSlot();
213
void recursiveReadyReadSlot();
214
void waitForReadyReadInASlotSlot();
215
void enterLoopSlot();
216
void hostLookupSlot();
217
void abortiveClose_abortSlot();
218
void remoteCloseErrorSlot();
219
void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth);
220
void earlySocketBytesSent(qint64 bytes);
221
void earlySocketReadyRead();
224
QByteArray expectedReplyIMAP();
225
void fetchExpectedReplyIMAP();
226
QTcpSocket *newSocket() const;
227
QTcpSocket *nonBlockingIMAP_socket;
228
QStringList nonBlockingIMAP_data;
229
qint64 nonBlockingIMAP_totalWritten;
231
QTcpSocket *tmpSocket;
232
qint64 bytesAvailable;
233
qint64 expectedLength;
237
QByteArray expectedReplyIMAP_cached;
239
mutable int proxyAuthCalled;
241
bool gotClosedSignal;
243
static int loopLevel;
245
SocketPair *earlyConstructedSockets;
246
int earlyBytesWrittenCount;
247
int earlyReadyReadCount;
248
QString stressTestDir;
263
int tst_QTcpSocket::loopLevel = 0;
265
class SocketPair: public QObject
269
QTcpSocket *endPoints[2];
271
SocketPair(QObject *parent = 0)
274
endPoints[0] = endPoints[1] = 0;
282
QTcpSocket *active = new QTcpSocket(this);
283
active->connectToHost("127.0.0.1", server.serverPort());
285
if (!active->waitForConnected(1000))
288
if (!server.waitForNewConnection(1000))
291
QTcpSocket *passive = server.nextPendingConnection();
292
passive->setParent(this);
294
endPoints[0] = active;
295
endPoints[1] = passive;
300
tst_QTcpSocket::tst_QTcpSocket()
304
//This code relates to the socketsConstructedBeforeEventLoop test case
305
earlyConstructedSockets = new SocketPair;
306
QVERIFY(earlyConstructedSockets->create());
307
earlyBytesWrittenCount = 0;
308
earlyReadyReadCount = 0;
309
connect(earlyConstructedSockets->endPoints[0], SIGNAL(readyRead()), this, SLOT(earlySocketReadyRead()));
310
connect(earlyConstructedSockets->endPoints[1], SIGNAL(bytesWritten(qint64)), this, SLOT(earlySocketBytesSent(qint64)));
311
earlyConstructedSockets->endPoints[1]->write("hello work");
314
tst_QTcpSocket::~tst_QTcpSocket()
319
void tst_QTcpSocket::initTestCase_data()
321
QTest::addColumn<bool>("setProxy");
322
QTest::addColumn<int>("proxyType");
323
QTest::addColumn<bool>("ssl");
325
qDebug() << QtNetworkSettings::serverName();
326
QTest::newRow("WithoutProxy") << false << 0 << false;
327
QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy) << false;
328
QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic) << false;
330
QTest::newRow("WithHttpProxy") << true << int(HttpProxy) << false;
331
QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic) << false;
332
// QTest::newRow("WithHttpProxyNtlmAuth") << true << int(HttpProxy | AuthNtlm) << false;
335
QTest::newRow("WithoutProxy SSL") << false << 0 << true;
336
QTest::newRow("WithSocks5Proxy SSL") << true << int(Socks5Proxy) << true;
337
QTest::newRow("WithSocks5AuthProxy SSL") << true << int(Socks5Proxy | AuthBasic) << true;
339
QTest::newRow("WithHttpProxy SSL") << true << int(HttpProxy) << true;
340
QTest::newRow("WithHttpProxyBasicAuth SSL") << true << int(HttpProxy | AuthBasic) << true;
341
// QTest::newRow("WithHttpProxyNtlmAuth SSL") << true << int(HttpProxy | AuthNtlm) << true;
344
stressTestDir = QFINDTESTDATA("stressTest");
345
QVERIFY2(!stressTestDir.isEmpty(), qPrintable(
346
QString::fromLatin1("Couldn't find stressTest dir starting from %1.").arg(QDir::currentPath())));
349
void tst_QTcpSocket::initTestCase()
351
QVERIFY(QtNetworkSettings::verifyTestNetworkSettings());
354
void tst_QTcpSocket::init()
356
QFETCH_GLOBAL(bool, setProxy);
358
QFETCH_GLOBAL(int, proxyType);
359
QList<QHostAddress> addresses = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses();
360
QVERIFY2(addresses.count() > 0, "failed to get ip address for test server");
361
QString fluke = addresses.first().toString();
366
proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1080);
369
case Socks5Proxy | AuthBasic:
370
proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1081);
373
case HttpProxy | NoAuth:
374
proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3128);
377
case HttpProxy | AuthBasic:
378
proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3129);
381
case HttpProxy | AuthNtlm:
382
proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3130);
385
QNetworkProxy::setApplicationProxy(proxy);
388
qt_qhostinfo_clear_cache();
391
QTcpSocket *tst_QTcpSocket::newSocket() const
395
QFETCH_GLOBAL(bool, ssl);
396
socket = ssl ? new QSslSocket : new QTcpSocket;
398
socket = new QTcpSocket;
402
connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
403
SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
404
Qt::DirectConnection);
408
void tst_QTcpSocket::cleanup()
410
QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
413
void tst_QTcpSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
416
auth->setUser("qsockstest");
417
auth->setPassword("password");
420
//----------------------------------------------------------------------------------
422
void tst_QTcpSocket::socketsConstructedBeforeEventLoop()
424
QFETCH_GLOBAL(bool, setProxy);
425
QFETCH_GLOBAL(bool, ssl);
428
//This test checks that sockets constructed before QCoreApplication::exec() still emit signals
429
//see construction code in the tst_QTcpSocket constructor
431
QCOMPARE(earlyBytesWrittenCount, 1);
432
QCOMPARE(earlyReadyReadCount, 1);
433
earlyConstructedSockets->endPoints[0]->close();
434
earlyConstructedSockets->endPoints[1]->close();
437
void tst_QTcpSocket::earlySocketBytesSent(qint64 /* bytes */)
439
earlyBytesWrittenCount++;
442
void tst_QTcpSocket::earlySocketReadyRead()
444
earlyReadyReadCount++;
447
//----------------------------------------------------------------------------------
449
void tst_QTcpSocket::constructing()
451
QTcpSocket *socket = newSocket();
453
// Check the initial state of the QTcpSocket.
454
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
455
QVERIFY(socket->isSequential());
456
QVERIFY(!socket->isOpen());
457
QVERIFY(!socket->isValid());
458
QCOMPARE(socket->socketType(), QTcpSocket::TcpSocket);
461
QCOMPARE(socket->getChar(&c), false);
462
QCOMPARE((int) socket->bytesAvailable(), 0);
463
QCOMPARE(socket->canReadLine(), false);
464
QCOMPARE(socket->readLine(), QByteArray());
465
QCOMPARE(socket->socketDescriptor(), (qintptr)-1);
466
QCOMPARE((int) socket->localPort(), 0);
467
QVERIFY(socket->localAddress() == QHostAddress());
468
QCOMPARE((int) socket->peerPort(), 0);
469
QVERIFY(socket->peerAddress() == QHostAddress());
470
QCOMPARE(socket->error(), QTcpSocket::UnknownSocketError);
471
QCOMPARE(socket->errorString(), QString("Unknown error"));
473
// Check the state of the socket layer?
477
//----------------------------------------------------------------------------------
479
void tst_QTcpSocket::bind_data()
481
QTest::addColumn<QString>("stringAddr");
482
QTest::addColumn<bool>("successExpected");
483
QTest::addColumn<QString>("stringExpectedLocalAddress");
485
// iterate all interfaces, add all addresses on them as test data
486
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
487
foreach (const QNetworkInterface &interface, interfaces) {
488
if (!interface.isValid())
491
foreach (const QNetworkAddressEntry &entry, interface.addressEntries()) {
492
if (entry.ip().isInSubnet(QHostAddress::parseSubnet("fe80::/10"))
493
|| entry.ip().isInSubnet(QHostAddress::parseSubnet("169.254/16")))
494
continue; // link-local bind will fail, at least on Linux, so skip it.
496
QString ip(entry.ip().toString());
497
QTest::newRow(ip.toLatin1().constData()) << ip << true << ip;
501
// additionally, try bind to known-bad addresses, and make sure this doesn't work
502
// these ranges are guaranteed to be reserved for 'documentation purposes',
503
// and thus, should be unused in the real world. Not that I'm assuming the
504
// world is full of competent administrators, or anything.
505
QStringList knownBad;
506
knownBad << "198.51.100.1";
507
knownBad << "2001:0DB8::1";
508
foreach (const QString &badAddress, knownBad) {
509
QTest::newRow(badAddress.toLatin1().constData()) << badAddress << false << QString();
513
void tst_QTcpSocket::bind()
515
QFETCH_GLOBAL(bool, setProxy);
517
QSKIP("QTBUG-22964");
518
QFETCH(QString, stringAddr);
519
QFETCH(bool, successExpected);
520
QFETCH(QString, stringExpectedLocalAddress);
522
QHostAddress addr(stringAddr);
523
QHostAddress expectedLocalAddress(stringExpectedLocalAddress);
525
QTcpSocket *socket = newSocket();
526
qDebug() << "Binding " << addr;
528
if (successExpected) {
529
QVERIFY2(socket->bind(addr), qPrintable(socket->errorString()));
531
QVERIFY(!socket->bind(addr));
534
QCOMPARE(socket->localAddress(), expectedLocalAddress);
539
//----------------------------------------------------------------------------------
542
void tst_QTcpSocket::setInvalidSocketDescriptor()
544
QTcpSocket *socket = newSocket();
545
QCOMPARE(socket->socketDescriptor(), (qintptr)-1);
546
QVERIFY(!socket->setSocketDescriptor(-5, QTcpSocket::UnconnectedState));
547
QCOMPARE(socket->socketDescriptor(), (qintptr)-1);
549
QCOMPARE(socket->error(), QTcpSocket::UnsupportedSocketOperationError);
554
//----------------------------------------------------------------------------------
556
void tst_QTcpSocket::setSocketDescriptor()
558
QFETCH_GLOBAL(bool, setProxy);
560
return; // this test doesn't make sense with proxies
563
// need the dummy to ensure winsock is started
564
QTcpSocket *dummy = newSocket();
565
dummy->connectToHost(QtNetworkSettings::serverName(), 143);
566
QVERIFY(dummy->waitForConnected());
568
SOCKET sock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
569
if (sock == INVALID_SOCKET) {
570
qErrnoWarning(WSAGetLastError(), "INVALID_SOCKET");
573
SOCKET sock = ::socket(AF_INET, SOCK_STREAM, 0);
575
// artificially increase the value of sock
576
SOCKET sock2 = ::fcntl(sock, F_DUPFD, sock + 50);
581
QVERIFY(sock != INVALID_SOCKET);
582
QTcpSocket *socket = newSocket();
583
QVERIFY(socket->setSocketDescriptor(sock, QTcpSocket::UnconnectedState));
584
QCOMPARE(socket->socketDescriptor(), (qintptr)sock);
586
qt_qhostinfo_clear_cache(); //avoid the HostLookupState being skipped due to address being in cache from previous test.
587
socket->connectToHost(QtNetworkSettings::serverName(), 143);
588
QCOMPARE(socket->state(), QTcpSocket::HostLookupState);
589
QCOMPARE(socket->socketDescriptor(), (qintptr)sock);
590
QVERIFY(socket->waitForConnected(10000));
591
// skip this, it has been broken for years, see task 260735
592
// if somebody complains, consider fixing it, but it might break existing applications.
593
QEXPECT_FAIL("", "bug has been around for years, will not fix without need", Continue);
594
QCOMPARE(socket->socketDescriptor(), (qintptr)sock);
601
//----------------------------------------------------------------------------------
603
void tst_QTcpSocket::socketDescriptor()
605
QTcpSocket *socket = newSocket();
607
QCOMPARE(socket->socketDescriptor(), (qintptr)-1);
608
socket->connectToHost(QtNetworkSettings::serverName(), 143);
609
QVERIFY((socket->state() == QAbstractSocket::HostLookupState && socket->socketDescriptor() == -1) ||
610
(socket->state() == QAbstractSocket::ConnectingState && socket->socketDescriptor() != -1));
611
QVERIFY(socket->waitForConnected(10000));
612
QVERIFY(socket->state() == QAbstractSocket::ConnectedState);
613
QVERIFY(socket->socketDescriptor() != -1);
618
//----------------------------------------------------------------------------------
620
void tst_QTcpSocket::blockingIMAP()
622
QTcpSocket *socket = newSocket();
625
socket->connectToHost(QtNetworkSettings::serverName(), 143);
626
QVERIFY(socket->waitForConnected(10000));
627
QCOMPARE(socket->state(), QTcpSocket::ConnectedState);
628
QVERIFY(socket->isValid());
631
QVERIFY(socket->waitForReadyRead(5000));
632
QString s = socket->readLine();
633
// only test if an OK was returned, to make the test compatible between different
634
// IMAP server versions
635
QCOMPARE(s.left(4).toLatin1().constData(), "* OK");
638
QCOMPARE((int) socket->write("1 NOOP\r\n", 8), 8);
639
QCOMPARE((int) socket->write("2 NOOP\r\n", 8), 8);
641
if (!socket->canReadLine())
642
QVERIFY(socket->waitForReadyRead(5000));
645
s = socket->readLine();
646
QCOMPARE(s.toLatin1().constData(), "1 OK Completed\r\n");
648
// Write a third NOOP to verify that write doesn't clear the read buffer
649
QCOMPARE((int) socket->write("3 NOOP\r\n", 8), 8);
651
// Read second response
652
if (!socket->canReadLine())
653
QVERIFY(socket->waitForReadyRead(5000));
654
s = socket->readLine();
655
QCOMPARE(s.toLatin1().constData(), "2 OK Completed\r\n");
657
// Read third response
658
if (!socket->canReadLine())
659
QVERIFY(socket->waitForReadyRead(5000));
660
s = socket->readLine();
661
QCOMPARE(s.toLatin1().constData(), "3 OK Completed\r\n");
665
QCOMPARE((int) socket->write("4 LOGOUT\r\n", 10), 10);
667
if (!socket->canReadLine())
668
QVERIFY(socket->waitForReadyRead(5000));
670
// Read two lines of respose
671
s = socket->readLine();
672
QCOMPARE(s.toLatin1().constData(), "* BYE LOGOUT received\r\n");
674
if (!socket->canReadLine())
675
QVERIFY(socket->waitForReadyRead(5000));
677
s = socket->readLine();
678
QCOMPARE(s.toLatin1().constData(), "4 OK Completed\r\n");
683
// Check that it's closed
684
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
689
//----------------------------------------------------------------------------------
691
void tst_QTcpSocket::hostNotFound()
693
QTcpSocket *socket = newSocket();
695
socket->connectToHost("nosuchserver.qt-project.org", 80);
696
QVERIFY(!socket->waitForConnected());
697
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
698
QCOMPARE(int(socket->error()), int(QTcpSocket::HostNotFoundError));
703
//----------------------------------------------------------------------------------
704
void tst_QTcpSocket::timeoutConnect_data()
706
QTest::addColumn<QString>("address");
707
QTest::newRow("host") << QtNetworkSettings::serverName();
708
QTest::newRow("ip") << QtNetworkSettings::serverIP().toString();
711
void tst_QTcpSocket::timeoutConnect()
713
QFETCH(QString, address);
714
QTcpSocket *socket = newSocket();
719
// Port 1357 is configured to drop packets on the test server
720
socket->connectToHost(address, 1357);
721
QVERIFY(timer.elapsed() < 150);
722
QVERIFY(!socket->waitForConnected(1000)); //200ms is too short when using SOCKS proxy authentication
723
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
724
QCOMPARE(int(socket->error()), int(QTcpSocket::SocketTimeoutError));
727
socket->connectToHost(address, 1357);
728
QVERIFY(timer.elapsed() < 150);
729
QTimer::singleShot(50, &QTestEventLoop::instance(), SLOT(exitLoop()));
730
QTestEventLoop::instance().enterLoop(5);
731
QVERIFY(!QTestEventLoop::instance().timeout());
732
QVERIFY(socket->state() == QTcpSocket::ConnectingState
733
|| socket->state() == QTcpSocket::HostLookupState);
735
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
736
QCOMPARE(socket->openMode(), QIODevice::NotOpen);
741
//----------------------------------------------------------------------------------
743
void tst_QTcpSocket::nonBlockingIMAP()
745
QTcpSocket *socket = newSocket();
746
connect(socket, SIGNAL(hostFound()), SLOT(nonBlockingIMAP_hostFound()));
747
connect(socket, SIGNAL(connected()), SLOT(nonBlockingIMAP_connected()));
748
connect(socket, SIGNAL(disconnected()), SLOT(nonBlockingIMAP_closed()));
749
connect(socket, SIGNAL(bytesWritten(qint64)), SLOT(nonBlockingIMAP_bytesWritten(qint64)));
750
connect(socket, SIGNAL(readyRead()), SLOT(nonBlockingIMAP_readyRead()));
751
nonBlockingIMAP_socket = socket;
754
socket->connectToHost(QtNetworkSettings::serverName(), 143);
755
QVERIFY(socket->state() == QTcpSocket::HostLookupState ||
756
socket->state() == QTcpSocket::ConnectingState);
763
if (socket->state() == QTcpSocket::ConnectingState) {
770
QCOMPARE(socket->state(), QTcpSocket::ConnectedState);
778
QVERIFY(!nonBlockingIMAP_data.isEmpty());
779
QCOMPARE(nonBlockingIMAP_data.at(0).left(4).toLatin1().constData(), "* OK");
780
nonBlockingIMAP_data.clear();
782
nonBlockingIMAP_totalWritten = 0;
785
QCOMPARE((int) socket->write("1 NOOP\r\n", 8), 8);
793
QVERIFY(nonBlockingIMAP_totalWritten == 8);
803
QVERIFY(!nonBlockingIMAP_data.isEmpty());
804
QCOMPARE(nonBlockingIMAP_data.at(0).toLatin1().constData(), "1 OK Completed\r\n");
805
nonBlockingIMAP_data.clear();
808
nonBlockingIMAP_totalWritten = 0;
811
QCOMPARE((int) socket->write("2 LOGOUT\r\n", 10), 10);
818
QVERIFY(nonBlockingIMAP_totalWritten == 10);
826
// Read two lines of respose
827
QCOMPARE(nonBlockingIMAP_data.at(0).toLatin1().constData(), "* BYE LOGOUT received\r\n");
828
QCOMPARE(nonBlockingIMAP_data.at(1).toLatin1().constData(), "2 OK Completed\r\n");
829
nonBlockingIMAP_data.clear();
834
// Check that it's closed
835
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
840
void tst_QTcpSocket::nonBlockingIMAP_hostFound()
845
void tst_QTcpSocket::nonBlockingIMAP_connected()
850
void tst_QTcpSocket::nonBlockingIMAP_readyRead()
852
while (nonBlockingIMAP_socket->canReadLine())
853
nonBlockingIMAP_data.append(nonBlockingIMAP_socket->readLine());
858
void tst_QTcpSocket::nonBlockingIMAP_bytesWritten(qint64 written)
860
nonBlockingIMAP_totalWritten += written;
864
void tst_QTcpSocket::nonBlockingIMAP_closed()
868
//----------------------------------------------------------------------------------
870
void tst_QTcpSocket::delayedClose()
872
QTcpSocket *socket = newSocket();
873
connect(socket, SIGNAL(connected()), SLOT(nonBlockingIMAP_connected()));
874
connect(socket, SIGNAL(disconnected()), SLOT(exitLoopSlot()));
876
socket->connectToHost(QtNetworkSettings::serverName(), 143);
882
QCOMPARE(socket->state(), QTcpSocket::ConnectedState);
884
QCOMPARE((int) socket->write("1 LOGOUT\r\n", 10), 10);
886
// Add a huge bulk of data to be written after the logout
887
// command. The server will shut down after receiving the LOGOUT,
888
// so this data will not be read. But our close call should
889
// schedule a delayed close because all the data can not be
890
// written in one go.
891
QCOMPARE((int) socket->write(QByteArray(100000, '\n'), 100000), 100000);
895
QCOMPARE((int) socket->state(), (int) QTcpSocket::ClosingState);
901
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
907
//----------------------------------------------------------------------------------
909
QByteArray tst_QTcpSocket::expectedReplyIMAP()
911
if (expectedReplyIMAP_cached.isEmpty()) {
912
fetchExpectedReplyIMAP();
915
return expectedReplyIMAP_cached;
918
// Figure out how the current IMAP server responds
919
void tst_QTcpSocket::fetchExpectedReplyIMAP()
921
QTcpSocket *socket = newSocket();
922
socket->connectToHost(QtNetworkSettings::serverName(), 143);
923
QVERIFY2(socket->waitForConnected(10000), qPrintable(socket->errorString()));
924
QVERIFY2(socket->state() == QTcpSocket::ConnectedState, qPrintable(socket->errorString()));
926
QTRY_VERIFY(socket->canReadLine());
928
QByteArray greeting = socket->readLine();
931
QVERIFY2(QtNetworkSettings::compareReplyIMAP(greeting), greeting.constData());
933
expectedReplyIMAP_cached = greeting;
936
//----------------------------------------------------------------------------------
938
void tst_QTcpSocket::partialRead()
940
QTcpSocket *socket = newSocket();
941
socket->connectToHost(QtNetworkSettings::serverName(), 143);
942
QVERIFY(socket->waitForConnected(10000));
943
QVERIFY(socket->state() == QTcpSocket::ConnectedState);
946
QByteArray greeting = expectedReplyIMAP();
947
QVERIFY(!greeting.isEmpty());
949
for (int i = 0; i < 10; i += 2) {
950
while (socket->bytesAvailable() < 2)
951
QVERIFY(socket->waitForReadyRead(5000));
952
QVERIFY(socket->read(buf, 2) == 2);
954
QCOMPARE((char *)buf, greeting.mid(i, 2).data());
960
//----------------------------------------------------------------------------------
962
void tst_QTcpSocket::unget()
964
QTcpSocket *socket = newSocket();
965
socket->connectToHost(QtNetworkSettings::serverName(), 143);
966
QVERIFY(socket->waitForConnected(10000));
967
QVERIFY(socket->state() == QTcpSocket::ConnectedState);
970
QByteArray greeting = expectedReplyIMAP();
971
QVERIFY(!greeting.isEmpty());
973
for (int i = 0; i < 10; i += 2) {
974
while (socket->bytesAvailable() < 2)
975
QVERIFY(socket->waitForReadyRead(10000));
976
int bA = socket->bytesAvailable();
977
QVERIFY(socket->read(buf, 2) == 2);
979
QCOMPARE((char *)buf, greeting.mid(i, 2).data());
980
QCOMPARE((int)socket->bytesAvailable(), bA - 2);
981
socket->ungetChar(buf[1]);
982
socket->ungetChar(buf[0]);
983
QCOMPARE((int)socket->bytesAvailable(), bA);
984
QVERIFY(socket->read(buf, 2) == 2);
986
QCOMPARE((char *)buf, greeting.mid(i, 2).data());
992
//----------------------------------------------------------------------------------
993
void tst_QTcpSocket::readRegularFile_readyRead()
998
//----------------------------------------------------------------------------------
999
void tst_QTcpSocket::readAllAfterClose()
1001
QTcpSocket *socket = newSocket();
1002
socket->connectToHost(QtNetworkSettings::serverName(), 143);
1003
connect(socket, SIGNAL(readyRead()), SLOT(readRegularFile_readyRead()));
1006
QFAIL("Network operation timed out");
1009
QByteArray array = socket->readAll();
1010
QCOMPARE(array.size(), 0);
1015
//----------------------------------------------------------------------------------
1016
void tst_QTcpSocket::openCloseOpenClose()
1018
QTcpSocket *socket = newSocket();
1020
for (int i = 0; i < 3; ++i) {
1021
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
1022
QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
1023
QVERIFY(socket->isSequential());
1024
QVERIFY(!socket->isOpen());
1025
QVERIFY(socket->socketType() == QTcpSocket::TcpSocket);
1028
QCOMPARE(socket->getChar(&c), false);
1029
QCOMPARE((int) socket->bytesAvailable(), 0);
1030
QCOMPARE(socket->canReadLine(), false);
1031
QCOMPARE(socket->readLine(), QByteArray());
1032
QCOMPARE(socket->socketDescriptor(), (qintptr)-1);
1033
QCOMPARE((int) socket->localPort(), 0);
1034
QVERIFY(socket->localAddress() == QHostAddress());
1035
QCOMPARE((int) socket->peerPort(), 0);
1036
QVERIFY(socket->peerAddress() == QHostAddress());
1037
QCOMPARE(socket->error(), QTcpSocket::UnknownSocketError);
1038
QCOMPARE(socket->errorString(), QString("Unknown error"));
1040
QVERIFY(socket->state() == QTcpSocket::UnconnectedState);
1042
socket->connectToHost(QtNetworkSettings::serverName(), 143);
1043
QVERIFY(socket->waitForConnected(10000));
1050
//----------------------------------------------------------------------------------
1051
void tst_QTcpSocket::connectDisconnectConnectDisconnect()
1053
QTcpSocket *socket = newSocket();
1055
for (int i = 0; i < 3; ++i) {
1056
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
1057
QVERIFY(socket->socketType() == QTcpSocket::TcpSocket);
1059
socket->connectToHost(QtNetworkSettings::serverName(), 143);
1060
QVERIFY(socket->waitForReadyRead(10000));
1061
QCOMPARE(QString::fromLatin1(socket->read(4)), QString("* OK"));
1063
socket->disconnectFromHost();
1064
if (socket->state() != QTcpSocket::UnconnectedState)
1065
QVERIFY(socket->waitForDisconnected(10000));
1066
QCOMPARE(int(socket->openMode()), int(QIODevice::ReadWrite));
1072
//----------------------------------------------------------------------------------
1073
void tst_QTcpSocket::disconnectWhileConnecting_data()
1075
QTest::addColumn<QByteArray>("data");
1076
QTest::addColumn<bool>("closeDirectly");
1078
QTest::newRow("without-data") << QByteArray() << false;
1079
QTest::newRow("without-data+close") << QByteArray() << true;
1080
QTest::newRow("with-data") << QByteArray("Hello, world!") << false;
1081
QTest::newRow("with-data+close") << QByteArray("Hello, world!") << true;
1083
QByteArray bigData(1024*1024, '@');
1084
QTest::newRow("with-big-data") << bigData << false;
1085
QTest::newRow("with-big-data+close") << bigData << true;
1088
void tst_QTcpSocket::disconnectWhileConnecting()
1090
QFETCH(QByteArray, data);
1091
QFETCH_GLOBAL(bool, setProxy);
1093
return; //proxy not useful for localhost test case
1096
QVERIFY(server.listen(QHostAddress::LocalHost));
1098
// proceed to the connect-write-disconnect
1099
QTcpSocket *socket = newSocket();
1100
socket->connectToHost("127.0.0.1", server.serverPort());
1101
if (!data.isEmpty())
1102
socket->write(data);
1103
if (socket->state() == QAbstractSocket::ConnectedState)
1104
QSKIP("localhost connections are immediate, test case is invalid");
1106
QFETCH(bool, closeDirectly);
1107
if (closeDirectly) {
1109
QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
1111
socket->disconnectFromHost();
1114
connect(socket, SIGNAL(disconnected()), SLOT(exitLoopSlot()));
1116
QVERIFY2(!timeout(), "Network timeout");
1117
QVERIFY(socket->state() == QAbstractSocket::UnconnectedState);
1118
if (!closeDirectly) {
1119
QCOMPARE(int(socket->openMode()), int(QIODevice::ReadWrite));
1122
QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
1124
// accept the other side and verify that it was sent properly:
1125
QVERIFY(server.hasPendingConnections() || server.waitForNewConnection(0));
1126
QTcpSocket *othersocket = server.nextPendingConnection();
1127
if (othersocket->state() != QAbstractSocket::UnconnectedState)
1128
QVERIFY2(othersocket->waitForDisconnected(10000), "Network timeout");
1129
QVERIFY(othersocket->state() == QAbstractSocket::UnconnectedState);
1130
QCOMPARE(othersocket->readAll(), data);
1136
//----------------------------------------------------------------------------------
1137
class ReceiverThread: public QThread
1143
QByteArray receivedData;
1147
: server(0), ok(false), quit(false)
1150
~ReceiverThread() { }
1154
server = new QTcpServer;
1155
if (!server->listen(QHostAddress::LocalHost))
1157
serverPort = server->serverPort();
1158
server->moveToThread(this);
1162
static void cleanup(void *ptr)
1164
ReceiverThread* self = reinterpret_cast<ReceiverThread*>(ptr);
1173
bool timedOut = false;
1175
if (server->waitForNewConnection(500, &timedOut))
1181
QTcpSocket *socket = server->nextPendingConnection();
1183
if (socket->waitForDisconnected(500))
1185
if (socket->error() != QAbstractSocket::SocketTimeoutError)
1190
receivedData = socket->readAll();
1199
void tst_QTcpSocket::disconnectWhileConnectingNoEventLoop_data()
1201
disconnectWhileConnecting_data();
1204
void tst_QTcpSocket::disconnectWhileConnectingNoEventLoop()
1206
QFETCH(QByteArray, data);
1207
QFETCH_GLOBAL(bool, setProxy);
1209
return; //proxy not useful for localhost test case
1211
QScopedPointer<ReceiverThread, ReceiverThread> thread (new ReceiverThread);
1212
QVERIFY(thread->listen());
1215
// proceed to the connect-write-disconnect
1216
QTcpSocket *socket = newSocket();
1217
socket->connectToHost("127.0.0.1", thread->serverPort);
1218
if (!data.isEmpty())
1219
socket->write(data);
1220
if (socket->state() == QAbstractSocket::ConnectedState)
1221
QSKIP("localhost connections are immediate, test case is invalid");
1223
QFETCH(bool, closeDirectly);
1224
if (closeDirectly) {
1226
QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
1228
socket->disconnectFromHost();
1231
QVERIFY2(socket->waitForDisconnected(10000), "Network timeout");
1232
QVERIFY(socket->state() == QAbstractSocket::UnconnectedState);
1233
if (!closeDirectly) {
1234
QCOMPARE(int(socket->openMode()), int(QIODevice::ReadWrite));
1237
QCOMPARE(int(socket->openMode()), int(QIODevice::NotOpen));
1240
// check if the other side received everything ok
1241
QVERIFY(thread->wait(30000));
1242
QVERIFY(thread->ok);
1243
QCOMPARE(thread->receivedData, data);
1246
//----------------------------------------------------------------------------------
1247
void tst_QTcpSocket::disconnectWhileLookingUp_data()
1249
QTest::addColumn<bool>("doClose");
1251
QTest::newRow("disconnect") << false;
1252
QTest::newRow("close") << true;
1255
void tst_QTcpSocket::disconnectWhileLookingUp()
1257
QFETCH_GLOBAL(bool, setProxy);
1259
return; // we let the proxies do the lookup now
1261
// just connect and disconnect, then make sure nothing weird happened
1262
QTcpSocket *socket = newSocket();
1263
socket->connectToHost(QtNetworkSettings::serverName(), 21);
1265
// check that connect is in progress
1266
QVERIFY(socket->state() != QAbstractSocket::UnconnectedState);
1268
QFETCH(bool, doClose);
1271
QVERIFY(socket->openMode() == QIODevice::NotOpen);
1273
socket->disconnectFromHost();
1274
QVERIFY(socket->openMode() == QIODevice::ReadWrite);
1275
QVERIFY(socket->waitForDisconnected(5000));
1278
// let anything queued happen
1280
QTimer::singleShot(50, &loop, SLOT(quit()));
1285
QVERIFY(socket->openMode() == QIODevice::NotOpen);
1287
QVERIFY(socket->openMode() == QIODevice::ReadWrite);
1290
QVERIFY(socket->state() == QAbstractSocket::UnconnectedState);
1293
//----------------------------------------------------------------------------------
1294
void tst_QTcpSocket::downloadBigFile()
1298
tmpSocket = newSocket();
1300
connect(tmpSocket, SIGNAL(connected()), SLOT(exitLoopSlot()));
1301
connect(tmpSocket, SIGNAL(readyRead()), SLOT(downloadBigFileSlot()));
1302
connect(tmpSocket, SIGNAL(disconnected()), SLOT(exitLoopSlot()));
1304
tmpSocket->connectToHost(QtNetworkSettings::serverName(), 80);
1310
QFAIL("Network operation timed out");
1313
QByteArray hostName = QtNetworkSettings::serverName().toLatin1();
1314
QVERIFY(tmpSocket->state() == QAbstractSocket::ConnectedState);
1315
QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0);
1316
QVERIFY(tmpSocket->write("HOST: ") > 0);
1317
QVERIFY(tmpSocket->write(hostName.data()) > 0);
1318
QVERIFY(tmpSocket->write("\r\n") > 0);
1319
QVERIFY(tmpSocket->write("\r\n") > 0);
1323
readingBody = false;
1332
if (bytesAvailable > 0)
1333
qDebug("Slow Connection, only downloaded %ld of %d", long(bytesAvailable), 10000281);
1334
QFAIL("Network operation timed out");
1337
QCOMPARE(bytesAvailable, expectedLength);
1339
qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
1340
bytesAvailable / (1024.0 * 1024.0),
1341
stopWatch.elapsed() / 1024.0,
1342
(bytesAvailable / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));
1348
//----------------------------------------------------------------------------------
1349
void tst_QTcpSocket::exitLoopSlot()
1354
//----------------------------------------------------------------------------------
1355
void tst_QTcpSocket::downloadBigFileSlot()
1358
while (tmpSocket->canReadLine()) {
1359
QByteArray array = tmpSocket->readLine();
1360
if (array.startsWith("Content-Length"))
1361
expectedLength = array.simplified().split(' ').at(1).toInt();
1362
if (array == "\r\n") {
1369
bytesAvailable += tmpSocket->readAll().size();
1370
if (bytesAvailable == expectedLength)
1375
//----------------------------------------------------------------------------------
1376
void tst_QTcpSocket::readLine()
1378
QTcpSocket *socket = newSocket();
1379
socket->connectToHost(QtNetworkSettings::serverName(), 143);
1380
QVERIFY(socket->waitForConnected(5000));
1382
while (!socket->canReadLine())
1383
QVERIFY(socket->waitForReadyRead(10000));
1387
qint64 linelen = socket->readLine(buffer, sizeof(buffer));
1388
QVERIFY(linelen >= 3);
1389
QVERIFY(linelen < 1024);
1391
QByteArray reply = QByteArray::fromRawData(buffer, linelen);
1392
QCOMPARE((int) buffer[linelen-2], (int) '\r');
1393
QCOMPARE((int) buffer[linelen-1], (int) '\n');
1394
QCOMPARE((int) buffer[linelen], (int) '\0');
1396
QVERIFY2(QtNetworkSettings::compareReplyIMAP(reply), reply.constData());
1398
QCOMPARE(socket->write("1 NOOP\r\n"), qint64(8));
1400
while (socket->bytesAvailable() < 10)
1401
QVERIFY(socket->waitForReadyRead(10000));
1403
QCOMPARE(socket->readLine(buffer, 11), qint64(10));
1404
QCOMPARE((const char *)buffer, "1 OK Compl");
1406
while (socket->bytesAvailable() < 6)
1407
QVERIFY(socket->waitForReadyRead(10000));
1409
QCOMPARE(socket->readLine(buffer, 11), qint64(6));
1410
QCOMPARE((const char *)buffer, "eted\r\n");
1412
QVERIFY(!socket->waitForReadyRead(100));
1413
QCOMPARE(socket->readLine(buffer, sizeof(buffer)), qint64(0));
1414
QVERIFY(socket->error() == QAbstractSocket::SocketTimeoutError
1415
|| socket->error() == QAbstractSocket::RemoteHostClosedError);
1416
QCOMPARE(socket->bytesAvailable(), qint64(0));
1419
QCOMPARE(socket->readLine(buffer, sizeof(buffer)), qint64(-1));
1424
//----------------------------------------------------------------------------------
1425
void tst_QTcpSocket::readLineString()
1427
QTcpSocket *socket = newSocket();
1428
socket->connectToHost(QtNetworkSettings::serverName(), 143);
1429
QVERIFY(socket->waitForReadyRead(10000));
1431
QByteArray arr = socket->readLine();
1432
QVERIFY2(QtNetworkSettings::compareReplyIMAP(arr), arr.constData());
1437
//----------------------------------------------------------------------------------
1438
void tst_QTcpSocket::readChunks()
1440
QTcpSocket *socket = newSocket();
1441
socket->connectToHost(QtNetworkSettings::serverName(), 143);
1442
QVERIFY(socket->waitForConnected(10000));
1443
QVERIFY(socket->waitForReadyRead(5000));
1446
memset(buf, '@', sizeof(buf));
1447
qint64 dataLength = socket->read(buf, sizeof(buf));
1448
QVERIFY(dataLength > 0);
1450
QCOMPARE(buf[dataLength - 2], '\r');
1451
QCOMPARE(buf[dataLength - 1], '\n');
1452
QCOMPARE(buf[dataLength], '@');
1457
//----------------------------------------------------------------------------------
1458
void tst_QTcpSocket::waitForBytesWritten()
1460
QTcpSocket *socket = newSocket();
1461
socket->connectToHost(QtNetworkSettings::serverName(), 80);
1462
QVERIFY(socket->waitForConnected(10000));
1464
socket->write("GET / HTTP/1.0\r\n\r\n");
1465
qint64 toWrite = socket->bytesToWrite();
1466
QVERIFY(socket->waitForBytesWritten(5000));
1467
QVERIFY(toWrite > socket->bytesToWrite());
1472
//----------------------------------------------------------------------------------
1473
void tst_QTcpSocket::waitForBytesWrittenMinusOne()
1476
QSKIP("QTBUG-24451 - indefinite wait may hang");
1478
QTcpSocket *socket = newSocket();
1479
socket->connectToHost(QtNetworkSettings::serverName(), 80);
1480
QVERIFY(socket->waitForConnected(10000));
1482
socket->write("GET / HTTP/1.0\r\n\r\n");
1483
qint64 toWrite = socket->bytesToWrite();
1484
QVERIFY(socket->waitForBytesWritten(-1));
1485
QVERIFY(toWrite > socket->bytesToWrite());
1490
//----------------------------------------------------------------------------------
1491
void tst_QTcpSocket::waitForReadyRead()
1493
QTcpSocket *socket = newSocket();
1494
socket->connectToHost(QtNetworkSettings::serverName(), 80);
1495
socket->write("GET / HTTP/1.0\r\n\r\n");
1496
QVERIFY(socket->waitForReadyRead(5000));
1500
//----------------------------------------------------------------------------------
1501
void tst_QTcpSocket::waitForReadyReadMinusOne()
1504
QSKIP("QTBUG-24451 - indefinite wait may hang");
1506
QTcpSocket *socket = newSocket();
1507
socket->connectToHost(QtNetworkSettings::serverName(), 80);
1508
socket->write("GET / HTTP/1.0\r\n\r\n");
1509
QVERIFY(socket->waitForReadyRead(-1));
1513
//----------------------------------------------------------------------------------
1514
void tst_QTcpSocket::flush()
1516
QTcpSocket *socket = newSocket();
1519
connect(socket, SIGNAL(connected()), SLOT(exitLoopSlot()));
1520
socket->connectToHost(QtNetworkSettings::serverName(), 143);
1522
QVERIFY(socket->isOpen());
1524
socket->write("1 LOGOUT\r\n");
1525
QCOMPARE(socket->bytesToWrite(), qint64(10));
1527
QCOMPARE(socket->bytesToWrite(), qint64(0));
1533
//----------------------------------------------------------------------------------
1534
void tst_QTcpSocket::synchronousApi()
1536
QTcpSocket *ftpSocket = newSocket();
1537
ftpSocket->connectToHost(QtNetworkSettings::serverName(), 21);
1538
ftpSocket->write("QUIT\r\n");
1539
QVERIFY(ftpSocket->waitForDisconnected(10000));
1540
QVERIFY(ftpSocket->bytesAvailable() > 0);
1541
QByteArray arr = ftpSocket->readAll();
1542
QVERIFY(arr.size() > 0);
1546
//----------------------------------------------------------------------------------
1547
void tst_QTcpSocket::dontCloseOnTimeout()
1550
server.setProxy(QNetworkProxy(QNetworkProxy::NoProxy));
1551
QVERIFY(server.listen());
1553
QHostAddress serverAddress = QHostAddress::LocalHost;
1554
if (!(server.serverAddress() == QHostAddress::AnyIPv4)
1555
&& !(server.serverAddress() == QHostAddress::AnyIPv6)
1556
&& !(server.serverAddress() == QHostAddress::Any))
1557
serverAddress = server.serverAddress();
1559
QTcpSocket *socket = newSocket();
1560
socket->connectToHost(serverAddress, server.serverPort());
1561
QVERIFY(!socket->waitForReadyRead(100));
1562
QCOMPARE(socket->error(), QTcpSocket::SocketTimeoutError);
1563
QVERIFY(socket->isOpen());
1565
QVERIFY(!socket->waitForDisconnected(100));
1566
QCOMPARE(socket->error(), QTcpSocket::SocketTimeoutError);
1567
QVERIFY(socket->isOpen());
1572
//----------------------------------------------------------------------------------
1573
void tst_QTcpSocket::recursiveReadyRead()
1575
QTcpSocket *testSocket = newSocket();
1576
connect(testSocket, SIGNAL(connected()), SLOT(exitLoopSlot()));
1577
connect(testSocket, SIGNAL(readyRead()), SLOT(recursiveReadyReadSlot()));
1578
tmpSocket = testSocket;
1580
QSignalSpy spy(testSocket, SIGNAL(readyRead()));
1582
testSocket->connectToHost(QtNetworkSettings::serverName(), 25);
1584
QVERIFY2(!timeout(),
1585
"Timed out when connecting to QtNetworkSettings::serverName().");
1588
QVERIFY2(!timeout(),
1589
"Timed out when waiting for the readyRead() signal.");
1591
QCOMPARE(spy.count(), 1);
1596
void tst_QTcpSocket::recursiveReadyReadSlot()
1598
// make sure the server spits out more data
1599
tmpSocket->write("NOOP\r\n");
1602
// indiscriminately enter the event loop and start processing
1603
// events again. but oops! future socket notifications will cause
1604
// undesired recursive behavior. Unless QTcpSocket is smart, which
1605
// it of course is. :-)
1607
for (int i = 0; i < 100; ++i)
1608
loop.processEvents();
1610
// all we really wanted to do was process some events, then exit
1615
//----------------------------------------------------------------------------------
1616
void tst_QTcpSocket::atEnd()
1618
QTcpSocket *socket = newSocket();
1619
socket->connectToHost(QtNetworkSettings::serverName(), 21);
1621
QVERIFY(socket->waitForReadyRead(15000));
1622
QTextStream stream(socket);
1623
QVERIFY(!stream.atEnd());
1624
QString greeting = stream.readLine();
1625
QVERIFY(stream.atEnd());
1627
// Test server must use some vsFTPd 2.x.x version
1628
QVERIFY2(greeting.length() == sizeof("220 (vsFTPd 2.x.x)")-1, qPrintable(greeting));
1629
QVERIFY2(greeting.startsWith("220 (vsFTPd 2."), qPrintable(greeting));
1630
QVERIFY2(greeting.endsWith(")"), qPrintable(greeting));
1635
class TestThread : public QThread
1640
inline QByteArray data() const
1649
QFETCH_GLOBAL(bool, ssl);
1651
socket = new QSslSocket;
1654
socket = new QTcpSocket;
1655
connect(socket, SIGNAL(readyRead()), this, SLOT(getData()), Qt::DirectConnection);
1656
connect(socket, SIGNAL(disconnected()), this, SLOT(closed()), Qt::DirectConnection);
1657
connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
1658
SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), Qt::DirectConnection);
1660
socket->connectToHost(QtNetworkSettings::serverName(), 21);
1661
socket->write("QUIT\r\n");
1668
inline void getData()
1670
socketData += socket->readAll();
1673
inline void closed()
1677
inline void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
1679
auth->setUser("qsockstest");
1680
auth->setPassword("password");
1685
QByteArray socketData;
1688
//----------------------------------------------------------------------------------
1689
void tst_QTcpSocket::socketInAThread()
1691
for (int i = 0; i < 3; ++i) {
1694
QVERIFY(thread.wait(15000));
1695
QByteArray data = thread.data();
1696
QVERIFY2(QtNetworkSettings::compareReplyFtp(data), data.constData());
1700
//----------------------------------------------------------------------------------
1701
void tst_QTcpSocket::socketsInThreads()
1703
for (int i = 0; i < 3; ++i) {
1712
QVERIFY(thread2.wait(15000));
1713
QVERIFY(thread3.wait(15000));
1714
QVERIFY(thread1.wait(15000));
1716
QByteArray data1 = thread1.data();
1717
QByteArray data2 = thread2.data();
1718
QByteArray data3 = thread3.data();
1720
QVERIFY2(QtNetworkSettings::compareReplyFtp(data1), data1.constData());
1721
QVERIFY2(QtNetworkSettings::compareReplyFtp(data2), data2.constData());
1722
QVERIFY2(QtNetworkSettings::compareReplyFtp(data3), data3.constData());
1726
//----------------------------------------------------------------------------------
1727
void tst_QTcpSocket::waitForReadyReadInASlot()
1729
QTcpSocket *socket = newSocket();
1731
connect(socket, SIGNAL(connected()), this, SLOT(waitForReadyReadInASlotSlot()));
1733
socket->connectToHost(QtNetworkSettings::serverName(), 80);
1734
socket->write("GET / HTTP/1.0\r\n\r\n");
1737
QVERIFY(!timeout());
1742
void tst_QTcpSocket::waitForReadyReadInASlotSlot()
1744
QVERIFY(tmpSocket->waitForReadyRead(10000));
1748
class RemoteCloseErrorServer : public QTcpServer
1752
RemoteCloseErrorServer()
1754
connect(this, SIGNAL(newConnection()),
1755
this, SLOT(getConnection()));
1759
void getConnection()
1761
tst_QTcpSocket::exitLoop();
1765
//----------------------------------------------------------------------------------
1766
void tst_QTcpSocket::remoteCloseError()
1768
QFETCH_GLOBAL(bool, setProxy);
1770
return; //proxy not useful for localhost test case
1771
RemoteCloseErrorServer server;
1772
QVERIFY(server.listen(QHostAddress::LocalHost));
1774
QCoreApplication::instance()->processEvents();
1776
QTcpSocket *clientSocket = newSocket();
1777
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(exitLoopSlot()));
1779
clientSocket->connectToHost(server.serverAddress(), server.serverPort());
1782
QVERIFY(!timeout());
1784
QVERIFY(server.hasPendingConnections());
1785
QTcpSocket *serverSocket = server.nextPendingConnection();
1786
connect(clientSocket, SIGNAL(disconnected()), this, SLOT(exitLoopSlot()));
1788
serverSocket->write("Hello");
1791
QVERIFY(!timeout());
1793
QCOMPARE(clientSocket->bytesAvailable(), qint64(5));
1795
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
1796
QSignalSpy errorSpy(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)));
1797
QSignalSpy disconnectedSpy(clientSocket, SIGNAL(disconnected()));
1799
clientSocket->write("World");
1800
serverSocket->disconnectFromHost();
1802
tmpSocket = clientSocket;
1803
connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
1804
this, SLOT(remoteCloseErrorSlot()));
1807
QVERIFY(!timeout());
1809
QCOMPARE(disconnectedSpy.count(), 1);
1810
QCOMPARE(errorSpy.count(), 1);
1811
QCOMPARE(clientSocket->error(), QAbstractSocket::RemoteHostClosedError);
1813
delete serverSocket;
1815
clientSocket->connectToHost(server.serverAddress(), server.serverPort());
1818
QVERIFY(!timeout());
1820
QVERIFY(server.hasPendingConnections());
1821
serverSocket = server.nextPendingConnection();
1822
serverSocket->disconnectFromHost();
1825
QVERIFY(!timeout());
1827
QCOMPARE(clientSocket->state(), QAbstractSocket::UnconnectedState);
1829
delete clientSocket;
1832
void tst_QTcpSocket::remoteCloseErrorSlot()
1834
QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState);
1835
static_cast<QTcpSocket *>(sender())->close();
1838
void tst_QTcpSocket::enterLoopSlot()
1840
QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
1841
socket->deleteLater();
1843
// enter nested event loop
1845
QTimer::singleShot(100, &loop, SLOT(quit()));
1848
// Fire a non-0 singleshot to leave time for the delete
1849
QTimer::singleShot(250, this, SLOT(exitLoopSlot()));
1851
//----------------------------------------------------------------------------------
1852
void tst_QTcpSocket::nestedEventLoopInErrorSlot()
1854
QTcpSocket *socket = newSocket();
1855
QPointer<QTcpSocket> p(socket);
1856
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(enterLoopSlot()));
1858
socket->connectToHost("hostnotfoundhostnotfound.qt-project.org", 9999);
1863
//----------------------------------------------------------------------------------
1865
void tst_QTcpSocket::connectToLocalHostNoService()
1867
// This test was created after we received a report that claimed
1868
// QTcpSocket would crash if trying to connect to "localhost" on a random
1869
// port with no service listening.
1870
QTcpSocket *socket = newSocket();
1871
socket->connectToHost("localhost", 31415); // no service running here, one suspects
1873
while(socket->state() == QTcpSocket::HostLookupState || socket->state() == QTcpSocket::ConnectingState) {
1876
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
1881
//----------------------------------------------------------------------------------
1882
void tst_QTcpSocket::waitForConnectedInHostLookupSlot()
1884
// This test tries to reproduce the problem where waitForConnected() is
1885
// called at a point where the host lookup is already done. QTcpSocket
1886
// will try to abort the "pending lookup", but since it's already done and
1887
// the queued signal is already underway, we will receive the signal after
1888
// waitForConnected() has returned, and control goes back to the event
1889
// loop. When the signal has been received, the connection is torn down,
1890
// then reopened. Yikes. If we reproduce this by calling
1891
// waitForConnected() inside hostLookupSlot(), it will even crash.
1892
tmpSocket = newSocket();
1894
connect(tmpSocket, SIGNAL(connected()), &loop, SLOT(quit()));
1896
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
1897
QSignalSpy timerSpy(&timer, SIGNAL(timeout()));
1900
connect(tmpSocket, SIGNAL(hostFound()), this, SLOT(hostLookupSlot()));
1901
tmpSocket->connectToHost(QtNetworkSettings::serverName(), 143);
1903
// only execute the loop if not already connected
1904
if (tmpSocket->state() != QAbstractSocket::ConnectedState)
1907
QCOMPARE(timerSpy.count(), 0);
1912
void tst_QTcpSocket::hostLookupSlot()
1914
// This will fail to cancel the pending signal
1915
QVERIFY(tmpSocket->waitForConnected(10000));
1918
class Foo : public QObject
1923
bool attemptedToConnect;
1924
bool networkTimeout;
1927
inline Foo(QObject *parent = 0) : QObject(parent)
1929
attemptedToConnect = false;
1930
networkTimeout = false;
1933
QFETCH_GLOBAL(bool, ssl);
1935
sock = new QSslSocket;
1938
sock = new QTcpSocket;
1939
connect(sock, SIGNAL(connected()), this, SLOT(connectedToIt()));
1940
connect(sock, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
1941
SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
1950
inline void connectedToIt()
1955
attemptedToConnect = true;
1956
sock->connectToHost(QtNetworkSettings::serverName(), 80);
1960
#elif defined Q_OS_LINUX
1963
if (!sock->waitForConnected()) {
1964
networkTimeout = true;
1966
tst_QTcpSocket::exitLoop();
1969
inline void exitLoop()
1971
tst_QTcpSocket::exitLoop();
1974
inline void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
1976
auth->setUser("qsockstest");
1977
auth->setPassword("password");
1981
//----------------------------------------------------------------------------------
1982
void tst_QTcpSocket::waitForConnectedInHostLookupSlot2()
1986
QTimer::singleShot(100, &foo, SLOT(doIt()));
1987
QTimer::singleShot(5000, &foo, SLOT(exitLoop()));
1990
if (timeout() || foo.networkTimeout)
1991
QFAIL("Network timeout");
1993
QVERIFY(foo.attemptedToConnect);
1994
QCOMPARE(foo.count, 1);
1997
//----------------------------------------------------------------------------------
1998
void tst_QTcpSocket::readyReadSignalsAfterWaitForReadyRead()
2000
QTcpSocket *socket = newSocket();
2002
QSignalSpy readyReadSpy(socket, SIGNAL(readyRead()));
2005
socket->connectToHost(QtNetworkSettings::serverName(), 143);
2007
// Wait for the read
2008
QVERIFY(socket->waitForReadyRead(10000));
2010
QCOMPARE(readyReadSpy.count(), 1);
2012
QString s = socket->readLine();
2013
QVERIFY2(QtNetworkSettings::compareReplyIMAP(s.toLatin1()), s.toLatin1().constData());
2014
QCOMPARE(socket->bytesAvailable(), qint64(0));
2016
QCoreApplication::instance()->processEvents();
2017
QCOMPARE(socket->bytesAvailable(), qint64(0));
2018
QCOMPARE(readyReadSpy.count(), 1);
2023
class TestThread2 : public QThread
2029
QFile fileWriter("fifo");
2030
QVERIFY(fileWriter.open(QFile::WriteOnly));
2031
QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
2032
QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
2033
QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
2034
QCOMPARE(fileWriter.write(QByteArray(32, '@')), qint64(32));
2038
//----------------------------------------------------------------------------------
2040
void tst_QTcpSocket::linuxKernelBugLocalSocket()
2042
QFile::remove("fifo");
2043
mkfifo("fifo", 0666);
2048
QFile fileReader("fifo");
2049
QVERIFY(fileReader.open(QFile::ReadOnly));
2053
QTcpSocket *socket = newSocket();
2054
socket->setSocketDescriptor(fileReader.handle());
2055
QVERIFY(socket->waitForReadyRead(5000));
2056
QCOMPARE(socket->bytesAvailable(), qint64(128));
2058
QFile::remove("fifo");
2064
//----------------------------------------------------------------------------------
2065
void tst_QTcpSocket::abortiveClose()
2067
QFETCH_GLOBAL(bool, setProxy);
2069
return; //proxy not useful for localhost test case
2071
QVERIFY(server.listen(QHostAddress::LocalHost));
2072
connect(&server, SIGNAL(newConnection()), this, SLOT(exitLoopSlot()));
2074
QTcpSocket *clientSocket = newSocket();
2075
clientSocket->connectToHost(server.serverAddress(), server.serverPort());
2078
QVERIFY(server.hasPendingConnections());
2080
QVERIFY(tmpSocket = server.nextPendingConnection());
2082
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
2083
QSignalSpy readyReadSpy(clientSocket, SIGNAL(readyRead()));
2084
QSignalSpy errorSpy(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)));
2086
connect(clientSocket, SIGNAL(disconnected()), this, SLOT(exitLoopSlot()));
2087
QTimer::singleShot(0, this, SLOT(abortiveClose_abortSlot()));
2091
QCOMPARE(readyReadSpy.count(), 0);
2092
QCOMPARE(errorSpy.count(), 1);
2094
QCOMPARE(*static_cast<const int *>(errorSpy.at(0).at(0).constData()),
2095
int(QAbstractSocket::RemoteHostClosedError));
2097
delete clientSocket;
2100
void tst_QTcpSocket::abortiveClose_abortSlot()
2105
//----------------------------------------------------------------------------------
2106
void tst_QTcpSocket::localAddressEmptyOnBSD()
2109
QSKIP("QTBUG-24451 - indefinite wait may hang");
2111
QFETCH_GLOBAL(bool, setProxy);
2113
return; //proxy not useful for localhost test case
2115
QVERIFY(server.listen(QHostAddress::LocalHost));
2117
QTcpSocket *tcpSocket = 0;
2118
// we try 10 times, but note that this doesn't always provoke the bug
2119
for (int i = 0; i < 10; ++i) {
2121
tcpSocket = newSocket();
2122
tcpSocket->connectToHost(QHostAddress::LocalHost, server.serverPort());
2123
if (!tcpSocket->waitForConnected(0)) {
2124
// to provoke the bug, we need a local socket that connects immediately
2127
if (tcpSocket->state() != QTcpSocket::UnconnectedState)
2128
QVERIFY(tcpSocket->waitForDisconnected(-1));
2131
QCOMPARE(tcpSocket->localAddress(), QHostAddress(QHostAddress::LocalHost));
2136
//----------------------------------------------------------------------------------
2137
void tst_QTcpSocket::zeroAndMinusOneReturns()
2139
QTcpSocket *socket = newSocket();
2140
socket->connectToHost(QtNetworkSettings::serverName(), 80);
2141
socket->write("GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n");
2142
QVERIFY(socket->waitForReadyRead(15000));
2145
QVERIFY(socket->getChar(c));
2146
QCOMPARE(socket->read(c, 16), qint64(16));
2147
QVERIFY(socket->readLine(c, 16) > 0);
2148
QVERIFY(!socket->readAll().isEmpty());
2150
// the last operation emptied the read buffer
2151
// all read operations from this point on should fail
2152
// with return 0 because the socket is still open
2153
QVERIFY(socket->readAll().isEmpty());
2154
QCOMPARE(socket->read(c, 16), qint64(0));
2155
QCOMPARE(socket->readLine(c, 16), qint64(0));
2156
QVERIFY(!socket->getChar(c));
2158
socket->write("GET / HTTP/1.0\r\n\r\n");
2159
QVERIFY(socket->waitForDisconnected(15000));
2160
QCOMPARE(socket->error(), QAbstractSocket::RemoteHostClosedError);
2162
QCOMPARE(socket->write("BLUBBER"), qint64(-1));
2163
QVERIFY(socket->getChar(c));
2164
QCOMPARE(socket->read(c, 16), qint64(16));
2165
QVERIFY(socket->readLine(c, 16) > 0);
2166
QVERIFY(!socket->readAll().isEmpty());
2168
// the last operation emptied the read buffer
2169
// all read operations from this point on should fail
2170
// with return -1 because the socket is not connected
2171
QVERIFY(socket->readAll().isEmpty());
2172
QCOMPARE(socket->read(c, 16), qint64(-1));
2173
QCOMPARE(socket->readLine(c, 16), qint64(-1));
2174
QVERIFY(!socket->getChar(c));
2175
QVERIFY(!socket->putChar('a'));
2179
// now the QIODevice is closed, which means getChar complains
2180
QCOMPARE(socket->write("BLUBBER"), qint64(-1));
2181
QCOMPARE(socket->read(c, 16), qint64(-1));
2182
QCOMPARE(socket->readLine(c, 16), qint64(-1));
2183
QVERIFY(!socket->getChar(c));
2184
QVERIFY(!socket->putChar('a'));
2189
//----------------------------------------------------------------------------------
2190
void tst_QTcpSocket::connectionRefused()
2192
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
2193
qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState");
2195
QTcpSocket *socket = newSocket();
2196
QSignalSpy stateSpy(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)));
2197
QSignalSpy errorSpy(socket, SIGNAL(error(QAbstractSocket::SocketError)));
2198
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
2199
&QTestEventLoop::instance(), SLOT(exitLoop()));
2201
socket->connectToHost(QtNetworkSettings::serverName(), 144);
2204
disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
2205
&QTestEventLoop::instance(), SLOT(exitLoop()));
2206
QVERIFY2(!timeout(), "Network timeout");
2208
QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
2209
QCOMPARE(socket->error(), QAbstractSocket::ConnectionRefusedError);
2211
QCOMPARE(stateSpy.count(), 3);
2212
QCOMPARE(qvariant_cast<QAbstractSocket::SocketState>(stateSpy.at(0).at(0)), QAbstractSocket::HostLookupState);
2213
QCOMPARE(qvariant_cast<QAbstractSocket::SocketState>(stateSpy.at(1).at(0)), QAbstractSocket::ConnectingState);
2214
QCOMPARE(qvariant_cast<QAbstractSocket::SocketState>(stateSpy.at(2).at(0)), QAbstractSocket::UnconnectedState);
2215
QCOMPARE(errorSpy.count(), 1);
2220
//----------------------------------------------------------------------------------
2221
void tst_QTcpSocket::suddenRemoteDisconnect_data()
2223
QTest::addColumn<QString>("client");
2224
QTest::addColumn<QString>("server");
2226
QTest::newRow("Qt4 Client <-> Qt4 Server") << QString::fromLatin1("qt4client") << QString::fromLatin1("qt4server");
2229
void tst_QTcpSocket::suddenRemoteDisconnect()
2231
QFETCH(QString, client);
2232
QFETCH(QString, server);
2234
QFETCH_GLOBAL(bool, setProxy);
2237
QFETCH_GLOBAL(bool, ssl);
2241
QString processExe = stressTestDir + "/stressTest";
2244
QProcess serverProcess;
2245
serverProcess.setReadChannel(QProcess::StandardError);
2246
serverProcess.start(processExe, QStringList(server), QIODevice::ReadWrite | QIODevice::Text);
2247
QVERIFY2(serverProcess.waitForStarted(), qPrintable(
2248
QString::fromLatin1("Could not start %1: %2").arg(processExe, serverProcess.errorString())));
2249
while (!serverProcess.canReadLine())
2250
QVERIFY(serverProcess.waitForReadyRead(10000));
2251
QCOMPARE(serverProcess.readLine().data(), QByteArray(server.toLatin1() + "\n").data());
2254
QProcess clientProcess;
2255
clientProcess.setReadChannel(QProcess::StandardError);
2256
clientProcess.start(processExe, QStringList(client), QIODevice::ReadWrite | QIODevice::Text);
2257
QVERIFY2(clientProcess.waitForStarted(), qPrintable(
2258
QString::fromLatin1("Could not start %1: %2").arg(processExe, clientProcess.errorString())));
2259
while (!clientProcess.canReadLine())
2260
QVERIFY(clientProcess.waitForReadyRead(10000));
2261
QCOMPARE(clientProcess.readLine().data(), QByteArray(client.toLatin1() + "\n").data());
2263
// Let them play for a while
2264
qDebug("Running stress test for 5 seconds");
2266
connect(&serverProcess, SIGNAL(finished(int)), &loop, SLOT(quit()));
2267
connect(&clientProcess, SIGNAL(finished(int)), &loop, SLOT(quit()));
2270
QTimer::singleShot(20000, &loop, SLOT(quit()));
2272
while ((serverProcess.state() == QProcess::Running
2273
|| clientProcess.state() == QProcess::Running) && stopWatch.elapsed() < 20000)
2276
QVERIFY(stopWatch.elapsed() < 20000);
2278
// Check that both exited normally.
2279
#if defined(UBUNTU_ONEIRIC) && defined(__x86_64__)
2280
QEXPECT_FAIL("", "Fails on this platform", Abort);
2282
QCOMPARE(clientProcess.readAll().constData(), "SUCCESS\n");
2283
QCOMPARE(serverProcess.readAll().constData(), "SUCCESS\n");
2286
//----------------------------------------------------------------------------------
2288
void tst_QTcpSocket::connectToMultiIP()
2290
QSKIP("TODO: setup DNS in the new network");
2291
#if defined(Q_OS_VXWORKS)
2292
QSKIP("VxSim in standard config doesn't even run a DNS resolver");
2294
QFETCH_GLOBAL(bool, ssl);
2297
QFETCH_GLOBAL(bool, setProxy);
2299
QSKIP("This test takes too long if we also add the proxies.");
2301
qDebug("Please wait, this test can take a while...");
2303
QTcpSocket *socket = newSocket();
2304
// rationale: this domain resolves to 3 A-records, 2 of them are
2305
// invalid. QTcpSocket should never spend more than 30 seconds per IP, and
2309
socket->connectToHost("multi.dev.qt-project.org", 80);
2310
QVERIFY(socket->waitForConnected(60500));
2311
QVERIFY(stopWatch.elapsed() < 70000);
2314
stopWatch.restart();
2315
socket->connectToHost("multi.dev.qt-project.org", 81);
2316
QVERIFY(!socket->waitForConnected(2000));
2317
QVERIFY(stopWatch.elapsed() < 2000);
2318
QCOMPARE(socket->error(), QAbstractSocket::SocketTimeoutError);
2324
//----------------------------------------------------------------------------------
2325
void tst_QTcpSocket::moveToThread0()
2327
QFETCH_GLOBAL(int, proxyType);
2328
if (proxyType & AuthMask)
2332
// Case 1: Moved after connecting, before waiting for connection.
2333
QTcpSocket *socket = newSocket();;
2334
socket->connectToHost(QtNetworkSettings::serverName(), 143);
2335
socket->moveToThread(0);
2336
QVERIFY(socket->waitForConnected(5000));
2337
socket->write("XXX LOGOUT\r\n");
2338
QVERIFY(socket->waitForBytesWritten(5000));
2339
QVERIFY(socket->waitForDisconnected());
2343
// Case 2: Moved before connecting
2344
QTcpSocket *socket = newSocket();
2345
socket->moveToThread(0);
2346
socket->connectToHost(QtNetworkSettings::serverName(), 143);
2347
QVERIFY(socket->waitForConnected(5000));
2348
socket->write("XXX LOGOUT\r\n");
2349
QVERIFY(socket->waitForBytesWritten(5000));
2350
QVERIFY(socket->waitForDisconnected());
2354
// Case 3: Moved after writing, while waiting for bytes to be written.
2355
QTcpSocket *socket = newSocket();
2356
socket->connectToHost(QtNetworkSettings::serverName(), 143);
2357
QVERIFY(socket->waitForConnected(5000));
2358
socket->write("XXX LOGOUT\r\n");
2359
socket->moveToThread(0);
2360
QVERIFY(socket->waitForBytesWritten(5000));
2361
QVERIFY(socket->waitForDisconnected());
2365
// Case 4: Moved after writing, while waiting for response.
2366
QTcpSocket *socket = newSocket();
2367
socket->connectToHost(QtNetworkSettings::serverName(), 143);
2368
QVERIFY(socket->waitForConnected(5000));
2369
socket->write("XXX LOGOUT\r\n");
2370
QVERIFY(socket->waitForBytesWritten(5000));
2371
socket->moveToThread(0);
2372
QVERIFY(socket->waitForDisconnected());
2377
void tst_QTcpSocket::increaseReadBufferSize()
2379
QFETCH_GLOBAL(bool, setProxy);
2381
return; //proxy not useful for localhost test case
2383
QTcpSocket *active = newSocket();
2384
connect(active, SIGNAL(readyRead()), SLOT(exitLoopSlot()));
2386
// connect two sockets to each other:
2387
QVERIFY(server.listen(QHostAddress::LocalHost));
2388
active->connectToHost("127.0.0.1", server.serverPort());
2389
QVERIFY(active->waitForConnected(5000));
2390
QVERIFY(server.waitForNewConnection(5000));
2392
QTcpSocket *passive = server.nextPendingConnection();
2395
// now write 512 bytes of data on one end
2396
QByteArray data(512, 'a');
2397
passive->write(data);
2398
QVERIFY2(passive->waitForBytesWritten(5000), "Network timeout");
2400
// set the read buffer size to less than what was written and iterate:
2401
active->setReadBufferSize(256);
2403
QVERIFY2(!timeout(), "Network timeout");
2404
QCOMPARE(active->bytesAvailable(), active->readBufferSize());
2406
// increase the buffer size and iterate again:
2407
active->setReadBufferSize(384);
2409
QVERIFY2(!timeout(), "Network timeout");
2410
QCOMPARE(active->bytesAvailable(), active->readBufferSize());
2412
// once more, but now it should read everything there was to read
2413
active->setReadBufferSize(1024);
2415
QVERIFY2(!timeout(), "Network timeout");
2416
QCOMPARE(active->bytesAvailable(), qint64(data.size()));
2418
// drain it and compare
2419
QCOMPARE(active->readAll(), data);
2421
// now one more test by setting the buffer size to unlimited:
2422
passive->write(data);
2423
QVERIFY2(passive->waitForBytesWritten(5000), "Network timeout");
2424
active->setReadBufferSize(256);
2426
QVERIFY2(!timeout(), "Network timeout");
2427
QCOMPARE(active->bytesAvailable(), active->readBufferSize());
2428
active->setReadBufferSize(0);
2430
QVERIFY2(!timeout(), "Network timeout");
2431
QCOMPARE(active->bytesAvailable(), qint64(data.size()));
2432
QCOMPARE(active->readAll(), data);
2437
void tst_QTcpSocket::taskQtBug5799ConnectionErrorWaitForConnected()
2439
QFETCH_GLOBAL(bool, setProxy);
2443
// check that we get a proper error connecting to port 12346
2444
// use waitForConnected, e.g. this should use a synchronous select() on the OS level
2447
socket.connectToHost(QtNetworkSettings::serverName(), 12346);
2450
socket.waitForConnected(10000);
2451
QVERIFY2(timer.elapsed() < 9900, "Connection to closed port timed out instead of refusing, something is wrong");
2452
QVERIFY2(socket.state() == QAbstractSocket::UnconnectedState, "Socket connected unexpectedly!");
2453
QVERIFY2(socket.error() == QAbstractSocket::ConnectionRefusedError,
2454
QString("Could not reach server: %1").arg(socket.errorString()).toLocal8Bit());
2457
void tst_QTcpSocket::taskQtBug5799ConnectionErrorEventLoop()
2459
QFETCH_GLOBAL(bool, setProxy);
2463
// check that we get a proper error connecting to port 12346
2464
// This testcase uses an event loop
2466
connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), &QTestEventLoop::instance(), SLOT(exitLoop()));
2467
socket.connectToHost(QtNetworkSettings::serverName(), 12346);
2469
QTestEventLoop::instance().enterLoop(10);
2470
QVERIFY2(!QTestEventLoop::instance().timeout(), "Connection to closed port timed out instead of refusing, something is wrong");
2471
QVERIFY2(socket.state() == QAbstractSocket::UnconnectedState, "Socket connected unexpectedly!");
2472
QVERIFY2(socket.error() == QAbstractSocket::ConnectionRefusedError,
2473
QString("Could not reach server: %1").arg(socket.errorString()).toLocal8Bit());
2476
void tst_QTcpSocket::taskQtBug7054TimeoutErrorResetting()
2478
QTcpSocket *socket = newSocket();
2480
socket->connectToHost(QtNetworkSettings::serverName(), 443);
2481
QVERIFY(socket->waitForConnected(5*1000));
2482
QVERIFY(socket->error() == QAbstractSocket::UnknownSocketError);
2484
// We connected to the HTTPS port. Wait two seconds to receive data. We will receive
2485
// nothing because we would need to start the SSL handshake
2486
QVERIFY(!socket->waitForReadyRead(2*1000));
2487
QVERIFY(socket->error() == QAbstractSocket::SocketTimeoutError);
2489
// Now write some crap to make the server disconnect us. 4 lines are enough.
2490
socket->write("a\r\nb\r\nc\r\nd\r\n");
2491
socket->waitForBytesWritten(2*1000);
2493
// we try to waitForReadyRead another time, but this time instead of a timeout we
2494
// should get a better error since the server disconnected us
2495
QVERIFY(!socket->waitForReadyRead(2*1000));
2496
// It must NOT be the SocketTimeoutError that had been set before
2497
QVERIFY(socket->error() == QAbstractSocket::RemoteHostClosedError);
2500
void tst_QTcpSocket::invalidProxy_data()
2502
QTest::addColumn<int>("type");
2503
QTest::addColumn<QString>("host");
2504
QTest::addColumn<int>("port");
2505
QTest::addColumn<bool>("failsAtConnect");
2506
QTest::addColumn<int>("expectedError");
2508
QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString();
2509
QTest::newRow("ftp-proxy") << int(QNetworkProxy::FtpCachingProxy) << fluke << 21 << true
2510
<< int(QAbstractSocket::UnsupportedSocketOperationError);
2511
QTest::newRow("http-caching-proxy") << int(QNetworkProxy::HttpCachingProxy) << fluke << 3128 << true
2512
<< int(QAbstractSocket::UnsupportedSocketOperationError);
2513
QTest::newRow("no-such-host-socks5") << int(QNetworkProxy::Socks5Proxy)
2514
<< "this-host-will-never-exist.qt-project.org" << 1080 << false
2515
<< int(QAbstractSocket::ProxyNotFoundError);
2516
QTest::newRow("no-such-host-http") << int(QNetworkProxy::HttpProxy)
2517
<< "this-host-will-never-exist.qt-project.org" << 3128 << false
2518
<< int(QAbstractSocket::ProxyNotFoundError);
2519
QTest::newRow("http-on-socks5") << int(QNetworkProxy::HttpProxy) << fluke << 1080 << false
2520
<< int(QAbstractSocket::ProxyConnectionClosedError);
2521
QTest::newRow("socks5-on-http") << int(QNetworkProxy::Socks5Proxy) << fluke << 3128 << false
2522
<< int(QAbstractSocket::SocketTimeoutError);
2525
void tst_QTcpSocket::invalidProxy()
2527
QFETCH_GLOBAL(bool, setProxy);
2532
QFETCH(QString, host);
2534
QFETCH(bool, failsAtConnect);
2535
QNetworkProxy::ProxyType proxyType = QNetworkProxy::ProxyType(type);
2536
QNetworkProxy proxy(proxyType, host, port);
2538
QTcpSocket *socket = newSocket();
2539
socket->setProxy(proxy);
2540
socket->connectToHost(QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(), 80);
2542
if (failsAtConnect) {
2543
QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
2545
QCOMPARE(socket->state(), QAbstractSocket::ConnectingState);
2546
QVERIFY(!socket->waitForConnected(5000));
2548
QVERIFY(!socket->errorString().isEmpty());
2550
// note: the following test is not a hard failure.
2551
// Sometimes, error codes change for the better
2552
QTEST(int(socket->error()), "expectedError");
2557
// copied from tst_qnetworkreply.cpp
2558
class MyProxyFactory: public QNetworkProxyFactory
2562
QList<QNetworkProxy> toReturn;
2563
QNetworkProxyQuery lastQuery;
2564
inline MyProxyFactory() { clear(); }
2569
toReturn = QList<QNetworkProxy>() << QNetworkProxy::DefaultProxy;
2570
lastQuery = QNetworkProxyQuery();
2573
virtual QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query)
2581
void tst_QTcpSocket::proxyFactory_data()
2583
QTest::addColumn<QList<QNetworkProxy> >("proxyList");
2584
QTest::addColumn<QNetworkProxy>("proxyUsed");
2585
QTest::addColumn<bool>("failsAtConnect");
2586
QTest::addColumn<int>("expectedError");
2588
QList<QNetworkProxy> proxyList;
2590
// tests that do connect
2592
proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3129);
2593
QTest::newRow("http")
2594
<< proxyList << proxyList.at(0)
2595
<< false << int(QAbstractSocket::UnknownSocketError);
2598
proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
2599
QTest::newRow("socks5")
2600
<< proxyList << proxyList.at(0)
2601
<< false << int(QAbstractSocket::UnknownSocketError);
2604
proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
2605
<< QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
2606
QTest::newRow("cachinghttp+socks5")
2607
<< proxyList << proxyList.at(1)
2608
<< false << int(QAbstractSocket::UnknownSocketError);
2611
proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121)
2612
<< QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
2613
<< QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
2614
QTest::newRow("ftp+cachinghttp+socks5")
2615
<< proxyList << proxyList.at(2)
2616
<< false << int(QAbstractSocket::UnknownSocketError);
2618
// tests that fail to connect
2620
proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
2621
QTest::newRow("cachinghttp")
2622
<< proxyList << QNetworkProxy()
2623
<< true << int(QAbstractSocket::UnsupportedSocketOperationError);
2626
proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121);
2627
QTest::newRow("ftp")
2628
<< proxyList << QNetworkProxy()
2629
<< true << int(QAbstractSocket::UnsupportedSocketOperationError);
2632
proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121)
2633
<< QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
2634
QTest::newRow("ftp+cachinghttp")
2635
<< proxyList << QNetworkProxy()
2636
<< true << int(QAbstractSocket::UnsupportedSocketOperationError);
2639
void tst_QTcpSocket::proxyFactory()
2641
QFETCH_GLOBAL(bool, setProxy);
2645
QFETCH(QList<QNetworkProxy>, proxyList);
2646
QFETCH(QNetworkProxy, proxyUsed);
2647
QFETCH(bool, failsAtConnect);
2649
MyProxyFactory *factory = new MyProxyFactory;
2650
factory->toReturn = proxyList;
2651
QNetworkProxyFactory::setApplicationProxyFactory(factory);
2653
QTcpSocket *socket = newSocket();
2654
QString host = QtNetworkSettings::serverName();
2655
socket->connectToHost(host, 80);
2657
// Verify that the factory was called properly
2658
QCOMPARE(factory->callCount, 1);
2659
QCOMPARE(factory->lastQuery, QNetworkProxyQuery(host, 80));
2661
if (failsAtConnect) {
2662
QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState);
2664
QCOMPARE(socket->state(), QAbstractSocket::ConnectingState);
2665
QVERIFY(socket->waitForConnected(5000));
2666
QCOMPARE(proxyAuthCalled, 1);
2668
QVERIFY(!socket->errorString().isEmpty());
2670
// note: the following test is not a hard failure.
2671
// Sometimes, error codes change for the better
2672
QTEST(int(socket->error()), "expectedError");
2677
// there is a similar test inside tst_qtcpserver that uses the event loop instead
2678
void tst_QTcpSocket::qtbug14268_peek()
2680
QFETCH_GLOBAL(bool, setProxy);
2684
SocketPair socketPair;
2685
QVERIFY(socketPair.create());
2686
QTcpSocket *outgoing = socketPair.endPoints[0];
2687
QTcpSocket *incoming = socketPair.endPoints[1];
2689
QVERIFY(incoming->state() == QTcpSocket::ConnectedState);
2690
QVERIFY(outgoing->state() == QTcpSocket::ConnectedState);
2692
outgoing->write("abc\n");
2693
QVERIFY(outgoing->waitForBytesWritten(2000));
2694
QVERIFY(incoming->waitForReadyRead(2000));
2695
QVERIFY(incoming->peek(128*1024) == QByteArray("abc\n"));
2697
outgoing->write("def\n");
2698
QVERIFY(outgoing->waitForBytesWritten(2000));
2699
QVERIFY(incoming->waitForReadyRead(2000));
2700
QVERIFY(incoming->peek(128*1024) == QByteArray("abc\ndef\n"));
2702
outgoing->write("ghi\n");
2703
QVERIFY(outgoing->waitForBytesWritten(2000));
2704
QVERIFY(incoming->waitForReadyRead(2000));
2705
QVERIFY(incoming->peek(128*1024) == QByteArray("abc\ndef\nghi\n"));
2707
QVERIFY(incoming->read(128*1024) == QByteArray("abc\ndef\nghi\n"));
2710
void tst_QTcpSocket::setSocketOption()
2712
QFETCH_GLOBAL(bool, setProxy);
2716
SocketPair socketPair;
2717
QVERIFY(socketPair.create());
2718
QTcpSocket *outgoing = socketPair.endPoints[0];
2719
QTcpSocket *incoming = socketPair.endPoints[1];
2721
QVERIFY(incoming->state() == QTcpSocket::ConnectedState);
2722
QVERIFY(outgoing->state() == QTcpSocket::ConnectedState);
2724
outgoing->setSocketOption(QAbstractSocket::LowDelayOption, true);
2725
QVariant v = outgoing->socketOption(QAbstractSocket::LowDelayOption);
2726
QVERIFY(v.isValid() && v.toBool());
2727
outgoing->setSocketOption(QAbstractSocket::KeepAliveOption, true);
2728
v = outgoing->socketOption(QAbstractSocket::KeepAliveOption);
2729
QVERIFY(v.isValid() && v.toBool());
2731
outgoing->setSocketOption(QAbstractSocket::LowDelayOption, false);
2732
v = outgoing->socketOption(QAbstractSocket::LowDelayOption);
2733
QVERIFY(v.isValid() && !v.toBool());
2734
outgoing->setSocketOption(QAbstractSocket::KeepAliveOption, false);
2735
v = outgoing->socketOption(QAbstractSocket::KeepAliveOption);
2736
QVERIFY(v.isValid() && !v.toBool());
2739
QEXPECT_FAIL("", "QTBUG-23323", Abort);
2741
outgoing->setSocketOption(QAbstractSocket::TypeOfServiceOption, 32); //high priority
2742
v = outgoing->socketOption(QAbstractSocket::TypeOfServiceOption);
2743
QVERIFY(v.isValid() && v.toInt() == 32);
2746
QTEST_MAIN(tst_QTcpSocket)
2747
#include "tst_qtcpsocket.moc"