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