diff options
Diffstat (limited to 'utils/rbutilqt/test/test-httpget.cpp')
-rw-r--r-- | utils/rbutilqt/test/test-httpget.cpp | 547 |
1 files changed, 547 insertions, 0 deletions
diff --git a/utils/rbutilqt/test/test-httpget.cpp b/utils/rbutilqt/test/test-httpget.cpp new file mode 100644 index 0000000000..144adc62df --- /dev/null +++ b/utils/rbutilqt/test/test-httpget.cpp | |||
@@ -0,0 +1,547 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2013 Dominik Riebeling | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version 2 | ||
14 | * of the License, or (at your option) any later version. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ****************************************************************************/ | ||
20 | |||
21 | #include <QtTest/QtTest> | ||
22 | #include <QtCore/QObject> | ||
23 | #include "httpget.h" | ||
24 | |||
25 | #define TEST_USER_AGENT "TestAgent/2.3" | ||
26 | #define TEST_HTTP_TIMEOUT 1000 | ||
27 | #define TEST_BINARY_BLOB "\x01\x10\x20\x30\x40\x50\x60\x70" \ | ||
28 | "\x80\x90\xff\xee\xdd\xcc\xbb\xaa" | ||
29 | |||
30 | // HttpDaemon is the the class that implements the simple HTTP server. | ||
31 | class HttpDaemon : public QTcpServer | ||
32 | { | ||
33 | Q_OBJECT | ||
34 | public: | ||
35 | HttpDaemon(quint16 port = 0, QObject* parent = 0) : QTcpServer(parent) | ||
36 | { | ||
37 | listen(QHostAddress::Any, port); | ||
38 | } | ||
39 | |||
40 | quint16 port(void) { return this->serverPort(); } | ||
41 | |||
42 | #if QT_VERSION < 0x050000 | ||
43 | void incomingConnection(int socket) | ||
44 | #else | ||
45 | // Qt 5 uses a different prototype for this function! | ||
46 | void incomingConnection(qintptr socket) | ||
47 | #endif | ||
48 | { | ||
49 | // When a new client connects, the server constructs a QTcpSocket and all | ||
50 | // communication with the client is done over this QTcpSocket. QTcpSocket | ||
51 | // works asynchronously, this means that all the communication is done | ||
52 | // in the two slots readClient() and discardClient(). | ||
53 | QTcpSocket* s = new QTcpSocket(this); | ||
54 | connect(s, SIGNAL(readyRead()), this, SLOT(readClient())); | ||
55 | connect(s, SIGNAL(disconnected()), this, SLOT(discardClient())); | ||
56 | s->setSocketDescriptor(socket); | ||
57 | } | ||
58 | QList<QString> lastRequestData(void) | ||
59 | { | ||
60 | return m_lastRequestData; | ||
61 | } | ||
62 | void setResponsesToSend(QList<QByteArray> response) | ||
63 | { | ||
64 | m_requestNumber = 0; | ||
65 | m_responsesToSend = response; | ||
66 | } | ||
67 | void reset(void) | ||
68 | { | ||
69 | m_requestNumber = 0; | ||
70 | m_lastRequestData.clear(); | ||
71 | QString now = | ||
72 | QDateTime::currentDateTime().toString("ddd, d MMM yyyy hh:mm:ss"); | ||
73 | m_defaultResponse = QByteArray( | ||
74 | "HTTP/1.1 404 Not Found\r\n" | ||
75 | "Date: " + now.toLatin1() + "\r\n" | ||
76 | "Last-Modified: " + now.toLatin1() + "\r\n" | ||
77 | "Connection: close\r\n" | ||
78 | "\r\n"); | ||
79 | } | ||
80 | |||
81 | private slots: | ||
82 | void readClient() | ||
83 | { | ||
84 | // This slot is called when the client sent data to the server. | ||
85 | QTcpSocket* socket = (QTcpSocket*)sender(); | ||
86 | // read whole request | ||
87 | QString request; | ||
88 | while(socket->canReadLine()) { | ||
89 | QString line = socket->readLine(); | ||
90 | request.append(line); | ||
91 | if(request.endsWith("\r\n\r\n")) { | ||
92 | m_lastRequestData.append(request); | ||
93 | |||
94 | if(m_requestNumber < m_responsesToSend.size()) | ||
95 | socket->write(m_responsesToSend.at(m_requestNumber)); | ||
96 | else | ||
97 | socket->write(m_defaultResponse); | ||
98 | socket->close(); | ||
99 | m_requestNumber++; | ||
100 | } | ||
101 | if (socket->state() == QTcpSocket::UnconnectedState) | ||
102 | delete socket; | ||
103 | } | ||
104 | } | ||
105 | void discardClient() | ||
106 | { | ||
107 | QTcpSocket* socket = (QTcpSocket*)sender(); | ||
108 | socket->deleteLater(); | ||
109 | } | ||
110 | |||
111 | private: | ||
112 | int m_requestNumber; | ||
113 | QList<QByteArray> m_responsesToSend; | ||
114 | QList<QString> m_lastRequestData; | ||
115 | QByteArray m_defaultResponse; | ||
116 | }; | ||
117 | |||
118 | |||
119 | class TestHttpGet : public QObject | ||
120 | { | ||
121 | Q_OBJECT | ||
122 | private slots: | ||
123 | void testFileUrlRequest(void); | ||
124 | void testCachedRequest(void); | ||
125 | void testUncachedRepeatedRequest(void); | ||
126 | void testUncachedMovedRequest(void); | ||
127 | void testUserAgent(void); | ||
128 | void testResponseCode(void); | ||
129 | void testContentToBuffer(void); | ||
130 | void testContentToFile(void); | ||
131 | void testNoServer(void); | ||
132 | void testServerTimestamp(void); | ||
133 | void testMovedQuery(void); | ||
134 | void init(void); | ||
135 | void cleanup(void); | ||
136 | |||
137 | public slots: | ||
138 | void waitTimeout(void) | ||
139 | { | ||
140 | m_waitTimeoutOccured = true; | ||
141 | } | ||
142 | QDir temporaryFolder(void) | ||
143 | { | ||
144 | // Qt unfortunately doesn't support creating temporary folders so | ||
145 | // we need to do that ourselves. | ||
146 | QString tempdir; | ||
147 | for(int i = 0; i < 100000; i++) { | ||
148 | tempdir = QDir::tempPath() + QString("/qttest-temp-%1").arg(i); | ||
149 | if(!QFileInfo(tempdir).exists()) break; | ||
150 | } | ||
151 | QDir().mkpath(tempdir); | ||
152 | return QDir(tempdir); | ||
153 | } | ||
154 | void rmTree(QString folder) | ||
155 | { | ||
156 | // no function in Qt to recursively delete a folder :( | ||
157 | QDir dir(folder); | ||
158 | Q_FOREACH(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | ||
159 | | QDir::System | QDir::Hidden | QDir::AllDirs | ||
160 | | QDir::Files, QDir::DirsFirst)) { | ||
161 | if(info.isDir()) rmTree(info.absoluteFilePath()); | ||
162 | else QFile::remove(info.absoluteFilePath()); | ||
163 | } | ||
164 | dir.rmdir(folder); | ||
165 | } | ||
166 | private: | ||
167 | HttpDaemon *m_daemon; | ||
168 | QByteArray m_port; | ||
169 | bool m_waitTimeoutOccured; | ||
170 | QString m_now; | ||
171 | QDir m_cachedir; | ||
172 | HttpGet *m_getter; | ||
173 | QSignalSpy *m_doneSpy; | ||
174 | QSignalSpy *m_progressSpy; | ||
175 | }; | ||
176 | |||
177 | |||
178 | void TestHttpGet::init(void) | ||
179 | { | ||
180 | m_now = QDateTime::currentDateTime().toString("ddd, d MMM yyyy hh:mm:ss"); | ||
181 | m_daemon = new HttpDaemon(0, this); // use port 0 to auto-pick | ||
182 | m_daemon->reset(); | ||
183 | m_port = QString("%1").arg(m_daemon->port()).toLatin1(); | ||
184 | m_cachedir = temporaryFolder(); | ||
185 | m_getter = new HttpGet(this); | ||
186 | m_doneSpy = new QSignalSpy(m_getter, SIGNAL(done(bool))); | ||
187 | m_progressSpy = new QSignalSpy(m_getter, SIGNAL(dataReadProgress(int, int))); | ||
188 | m_waitTimeoutOccured = false; | ||
189 | } | ||
190 | |||
191 | void TestHttpGet::cleanup(void) | ||
192 | { | ||
193 | rmTree(m_cachedir.absolutePath()); | ||
194 | if(m_getter) { | ||
195 | m_getter->abort(); delete m_getter; m_getter = NULL; | ||
196 | } | ||
197 | if(m_daemon) { delete m_daemon; m_daemon = NULL; } | ||
198 | if(m_doneSpy) { delete m_doneSpy; m_doneSpy = NULL; } | ||
199 | if(m_progressSpy) { delete m_progressSpy; m_progressSpy = NULL; } | ||
200 | } | ||
201 | |||
202 | void TestHttpGet::testFileUrlRequest(void) | ||
203 | { | ||
204 | QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void))); | ||
205 | |||
206 | QString teststring = "The quick brown fox jumps over the lazy dog."; | ||
207 | QTemporaryFile datafile; | ||
208 | datafile.open(); | ||
209 | datafile.write(teststring.toLatin1()); | ||
210 | m_getter->getFile(QUrl::fromLocalFile(datafile.fileName())); | ||
211 | datafile.close(); | ||
212 | while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false) | ||
213 | QCoreApplication::processEvents(); | ||
214 | |||
215 | QCOMPARE(m_doneSpy->count(), 1); | ||
216 | QCOMPARE(m_waitTimeoutOccured, false); | ||
217 | QCOMPARE(m_daemon->lastRequestData().size(), 0); | ||
218 | QCOMPARE(m_getter->readAll(), teststring.toLatin1()); | ||
219 | QCOMPARE(m_getter->httpResponse(), 200); | ||
220 | QCOMPARE(m_progressSpy->at(0).at(0).toInt(), 0); | ||
221 | } | ||
222 | |||
223 | |||
224 | /* On uncached requests, HttpGet is supposed to sent a GET request only. | ||
225 | */ | ||
226 | void TestHttpGet::testUncachedRepeatedRequest(void) | ||
227 | { | ||
228 | QList<QByteArray> responses; | ||
229 | responses << QByteArray( | ||
230 | "HTTP/1.1 200 OK\r\n" | ||
231 | "Date: " + m_now.toLatin1() + "\r\n" | ||
232 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
233 | "\r\n\r\n"); | ||
234 | responses << QByteArray( | ||
235 | "HTTP/1.1 200 OK\r\n" | ||
236 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
237 | "Date: " + m_now.toLatin1() + "\r\n" | ||
238 | "\r\n" | ||
239 | "<html></html>\r\n\r\n"); | ||
240 | m_daemon->setResponsesToSend(responses); | ||
241 | |||
242 | QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void))); | ||
243 | |||
244 | m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt")); | ||
245 | while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false) | ||
246 | QCoreApplication::processEvents(); | ||
247 | |||
248 | QCOMPARE(m_doneSpy->count(), 1); | ||
249 | QCOMPARE(m_waitTimeoutOccured, false); | ||
250 | QCOMPARE(m_daemon->lastRequestData().size(), 1); | ||
251 | QCOMPARE(m_daemon->lastRequestData().at(0).startsWith("GET"), true); | ||
252 | |||
253 | // request second time | ||
254 | m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt")); | ||
255 | while(m_doneSpy->count() < 2 && m_waitTimeoutOccured == false) | ||
256 | QCoreApplication::processEvents(); | ||
257 | QCOMPARE(m_doneSpy->count(), 2); | ||
258 | QCOMPARE(m_waitTimeoutOccured, false); | ||
259 | QCOMPARE(m_daemon->lastRequestData().size(), 2); | ||
260 | QCOMPARE(m_daemon->lastRequestData().at(1).startsWith("GET"), true); | ||
261 | QCOMPARE(m_getter->httpResponse(), 200); | ||
262 | } | ||
263 | |||
264 | /* With enabled cache HttpGet is supposed to check the server file using a HEAD | ||
265 | * request first, then request the file using GET if the server file is newer | ||
266 | * than the cached one (or the file does not exist in the cache) | ||
267 | */ | ||
268 | void TestHttpGet::testCachedRequest(void) | ||
269 | { | ||
270 | QList<QByteArray> responses; | ||
271 | responses << QByteArray( | ||
272 | "HTTP/1.1 302 Found\r\n" | ||
273 | "Location: http://localhost:" + m_port + "/test2.txt\r\n" | ||
274 | "Date: " + m_now.toLatin1() + "\r\n" | ||
275 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
276 | "\r\n"); | ||
277 | responses << QByteArray( | ||
278 | "HTTP/1.1 200 OK\r\n" | ||
279 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
280 | "Date: " + m_now.toLatin1() + "\r\n" | ||
281 | "\r\n" | ||
282 | "<html></html>\r\n\r\n"); | ||
283 | responses << QByteArray( | ||
284 | "HTTP/1.1 200 OK\r\n" | ||
285 | "Last-Modified: 1 Jan 2000 00:00:00\r\n" | ||
286 | "Date: " + m_now.toLatin1() + "\r\n" | ||
287 | "\r\n"); | ||
288 | m_daemon->setResponsesToSend(responses); | ||
289 | |||
290 | QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void))); | ||
291 | |||
292 | m_getter->setCache(m_cachedir); | ||
293 | m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt")); | ||
294 | while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false) | ||
295 | QCoreApplication::processEvents(); | ||
296 | |||
297 | QList<QString> requests = m_daemon->lastRequestData(); | ||
298 | QCOMPARE(m_doneSpy->count(), 1); | ||
299 | QCOMPARE(m_doneSpy->at(0).at(0).toBool(), false); | ||
300 | QCOMPARE(m_waitTimeoutOccured, false); | ||
301 | QCOMPARE(requests.size(), 2); | ||
302 | QCOMPARE(requests.at(0).startsWith("GET"), true); | ||
303 | QCOMPARE(requests.at(1).startsWith("GET"), true); | ||
304 | QCOMPARE(m_getter->httpResponse(), 200); | ||
305 | |||
306 | // request real file, this time the response should come from cache. | ||
307 | m_getter->getFile(QUrl("http://localhost:" + m_port + "/test2.txt")); | ||
308 | while(m_doneSpy->count() < 2 && m_waitTimeoutOccured == false) | ||
309 | QCoreApplication::processEvents(); | ||
310 | QCOMPARE(m_doneSpy->count(), 2); // 2 requests, 2 times done() | ||
311 | QCOMPARE(m_doneSpy->at(1).at(0).toBool(), false); | ||
312 | QCOMPARE(m_waitTimeoutOccured, false); | ||
313 | QCOMPARE(m_daemon->lastRequestData().size(), 3); | ||
314 | // redirect will not cache as the redirection target file. | ||
315 | QCOMPARE(m_daemon->lastRequestData().at(2).startsWith("GET"), true); | ||
316 | QCOMPARE(m_getter->httpResponse(), 200); | ||
317 | } | ||
318 | |||
319 | /* When a custom user agent is set all requests are supposed to contain it. | ||
320 | * Enable cache to make HttpGet performs a HEAD request. Answer with 302, so | ||
321 | * HttpGet follows and sends another HEAD request before finally doing a GET. | ||
322 | */ | ||
323 | void TestHttpGet::testUserAgent(void) | ||
324 | { | ||
325 | QList<QByteArray> responses; | ||
326 | responses << QByteArray( | ||
327 | "HTTP/1.1 200 OK\r\n" | ||
328 | "Date: " + m_now.toLatin1() + "\r\n" | ||
329 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
330 | "\r\n\r\n"); | ||
331 | responses << QByteArray( | ||
332 | "HTTP/1.1 200 OK\r\n" | ||
333 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
334 | "Date: " + m_now.toLatin1() + "\r\n" | ||
335 | "\r\n" | ||
336 | "<html></html>\r\n\r\n"); | ||
337 | m_daemon->setResponsesToSend(responses); | ||
338 | |||
339 | QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void))); | ||
340 | |||
341 | m_getter->setGlobalUserAgent(TEST_USER_AGENT); | ||
342 | m_getter->setCache(m_cachedir); | ||
343 | m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt")); | ||
344 | while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false) | ||
345 | QCoreApplication::processEvents(); | ||
346 | |||
347 | QList<QString> requests = m_daemon->lastRequestData(); | ||
348 | QCOMPARE(m_doneSpy->count(), 1); | ||
349 | QCOMPARE(m_waitTimeoutOccured, false); | ||
350 | QCOMPARE(requests.size(), 1); | ||
351 | QCOMPARE(requests.at(0).startsWith("GET"), true); | ||
352 | |||
353 | for(int i = 0; i < requests.size(); ++i) { | ||
354 | QRegExp rx("User-Agent:[\t ]+([a-zA-Z0-9\\./]+)"); | ||
355 | bool userAgentFound = rx.indexIn(requests.at(i)) > 0 ? true : false; | ||
356 | QCOMPARE(userAgentFound, true); | ||
357 | QString userAgentString = rx.cap(1); | ||
358 | QCOMPARE(userAgentString, QString(TEST_USER_AGENT)); | ||
359 | } | ||
360 | } | ||
361 | |||
362 | void TestHttpGet::testUncachedMovedRequest(void) | ||
363 | { | ||
364 | QList<QByteArray> responses; | ||
365 | responses << QByteArray( | ||
366 | "HTTP/1.1 302 Found\r\n" | ||
367 | "Location: http://localhost:" + m_port + "/test2.txt\r\n" | ||
368 | "Date: " + m_now.toLatin1() + "\r\n" | ||
369 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
370 | "\r\n"); | ||
371 | responses << QByteArray( | ||
372 | "HTTP/1.1 200 OK\r\n" | ||
373 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
374 | "Date: " + m_now.toLatin1() + "\r\n" | ||
375 | "\r\n" | ||
376 | "<html></html>\r\n\r\n"); | ||
377 | m_daemon->setResponsesToSend(responses); | ||
378 | |||
379 | QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void))); | ||
380 | |||
381 | m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.php?var=1&b=foo")); | ||
382 | while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false) | ||
383 | QCoreApplication::processEvents(); | ||
384 | |||
385 | QCOMPARE(m_doneSpy->count(), 1); | ||
386 | QCOMPARE(m_waitTimeoutOccured, false); | ||
387 | QCOMPARE(m_daemon->lastRequestData().size(), 2); | ||
388 | QCOMPARE(m_daemon->lastRequestData().at(0).startsWith("GET"), true); | ||
389 | QCOMPARE(m_daemon->lastRequestData().at(1).startsWith("GET"), true); | ||
390 | } | ||
391 | |||
392 | void TestHttpGet::testResponseCode(void) | ||
393 | { | ||
394 | QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void))); | ||
395 | |||
396 | m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt")); | ||
397 | while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false) | ||
398 | QCoreApplication::processEvents(); | ||
399 | |||
400 | QCOMPARE(m_doneSpy->count(), 1); | ||
401 | QCOMPARE(m_doneSpy->at(0).at(0).toBool(), true); | ||
402 | QCOMPARE(m_waitTimeoutOccured, false); | ||
403 | QCOMPARE(m_daemon->lastRequestData().size(), 1); | ||
404 | QCOMPARE(m_daemon->lastRequestData().at(0).startsWith("GET"), true); | ||
405 | QCOMPARE(m_getter->httpResponse(), 404); | ||
406 | } | ||
407 | |||
408 | void TestHttpGet::testContentToBuffer(void) | ||
409 | { | ||
410 | QList<QByteArray> responses; | ||
411 | responses << QByteArray( | ||
412 | "HTTP/1.1 200 OK\r\n" | ||
413 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
414 | "Date: " + m_now.toLatin1() + "\r\n" | ||
415 | "\r\n" | ||
416 | TEST_BINARY_BLOB); | ||
417 | m_daemon->setResponsesToSend(responses); | ||
418 | |||
419 | QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void))); | ||
420 | |||
421 | m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt")); | ||
422 | while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false) | ||
423 | QCoreApplication::processEvents(); | ||
424 | |||
425 | QCOMPARE(m_doneSpy->count(), 1); | ||
426 | QCOMPARE(m_waitTimeoutOccured, false); | ||
427 | QCOMPARE(m_getter->readAll(), QByteArray(TEST_BINARY_BLOB)); | ||
428 | // sizeof(TEST_BINARY_BLOB) will include an additional terminating NULL. | ||
429 | QCOMPARE(m_getter->readAll().size(), (int)sizeof(TEST_BINARY_BLOB) - 1); | ||
430 | QCOMPARE(m_progressSpy->at(m_progressSpy->count() - 1).at(0).toInt(), (int)sizeof(TEST_BINARY_BLOB) - 1); | ||
431 | QCOMPARE(m_progressSpy->at(m_progressSpy->count() - 1).at(1).toInt(), (int)sizeof(TEST_BINARY_BLOB) - 1); | ||
432 | } | ||
433 | |||
434 | void TestHttpGet::testContentToFile(void) | ||
435 | { | ||
436 | QTemporaryFile tf(this); | ||
437 | QList<QByteArray> responses; | ||
438 | responses << QByteArray( | ||
439 | "HTTP/1.1 200 OK\r\n" | ||
440 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
441 | "Date: " + m_now.toLatin1() + "\r\n" | ||
442 | "\r\n" | ||
443 | TEST_BINARY_BLOB); | ||
444 | m_daemon->setResponsesToSend(responses); | ||
445 | |||
446 | QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void))); | ||
447 | |||
448 | m_getter->setFile(&tf); | ||
449 | m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt")); | ||
450 | while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false) | ||
451 | QCoreApplication::processEvents(); | ||
452 | |||
453 | QCOMPARE(m_doneSpy->count(), 1); | ||
454 | QCOMPARE(m_waitTimeoutOccured, false); | ||
455 | |||
456 | tf.open(); | ||
457 | QByteArray data = tf.readAll(); | ||
458 | QCOMPARE(data, QByteArray(TEST_BINARY_BLOB)); | ||
459 | QCOMPARE((unsigned long)data.size(), sizeof(TEST_BINARY_BLOB) - 1); | ||
460 | tf.close(); | ||
461 | } | ||
462 | |||
463 | void TestHttpGet::testNoServer(void) | ||
464 | { | ||
465 | QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void))); | ||
466 | m_getter->getFile(QUrl("http://localhost:53/test1.txt")); | ||
467 | while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false) | ||
468 | QCoreApplication::processEvents(); | ||
469 | |||
470 | QCOMPARE(m_doneSpy->count(), 1); | ||
471 | QCOMPARE(m_doneSpy->at(0).at(0).toBool(), true); | ||
472 | QCOMPARE(m_waitTimeoutOccured, false); | ||
473 | } | ||
474 | |||
475 | void TestHttpGet::testServerTimestamp(void) | ||
476 | { | ||
477 | QList<QByteArray> responses; | ||
478 | responses << QByteArray( | ||
479 | "HTTP/1.1 200 OK\r\n" | ||
480 | "Last-Modified: Wed, 20 Jan 2010 10:20:30\r\n" // RFC 822 | ||
481 | "Date: Wed, 20 Jan 2010 10:20:30\r\n" | ||
482 | "\r\n" | ||
483 | "\r\n"); | ||
484 | responses << QByteArray( | ||
485 | "HTTP/1.1 200 OK\r\n" | ||
486 | "Last-Modified: Sat Feb 19 09:08:07 2011\r\n" // asctime | ||
487 | "Date: Sat Feb 19 09:08:07 2011\r\n" | ||
488 | "\r\n" | ||
489 | "\r\n"); | ||
490 | |||
491 | QList<QDateTime> times; | ||
492 | times << QDateTime::fromString("2010-01-20T11:20:30", Qt::ISODate); | ||
493 | times << QDateTime::fromString("2011-02-19T10:08:07", Qt::ISODate); | ||
494 | |||
495 | m_daemon->setResponsesToSend(responses); | ||
496 | |||
497 | QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void))); | ||
498 | |||
499 | int count = m_doneSpy->count(); | ||
500 | for(int i = 0; i < responses.size(); ++i) { | ||
501 | m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.txt")); | ||
502 | while(m_doneSpy->count() == count && m_waitTimeoutOccured == false) | ||
503 | QCoreApplication::processEvents(); | ||
504 | count = m_doneSpy->count(); | ||
505 | QCOMPARE(m_getter->timestamp(), times.at(i)); | ||
506 | } | ||
507 | } | ||
508 | |||
509 | void TestHttpGet::testMovedQuery(void) | ||
510 | { | ||
511 | QList<QByteArray> responses; | ||
512 | responses << QByteArray( | ||
513 | "HTTP/1.1 302 Found\r\n" | ||
514 | "Location: http://localhost:" + m_port + "/test2.php\r\n" | ||
515 | "Date: " + m_now.toLatin1() + "\r\n" | ||
516 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
517 | "\r\n"); | ||
518 | responses << QByteArray( | ||
519 | "HTTP/1.1 200 OK\r\n" | ||
520 | "Last-Modified: " + m_now.toLatin1() + "\r\n" | ||
521 | "Date: " + m_now.toLatin1() + "\r\n" | ||
522 | "\r\n" | ||
523 | "<html></html>\r\n\r\n"); | ||
524 | m_daemon->setResponsesToSend(responses); | ||
525 | |||
526 | QTimer::singleShot(TEST_HTTP_TIMEOUT, this, SLOT(waitTimeout(void))); | ||
527 | |||
528 | m_getter->getFile(QUrl("http://localhost:" + m_port + "/test1.php?var=1&b=foo")); | ||
529 | while(m_doneSpy->count() == 0 && m_waitTimeoutOccured == false) | ||
530 | QCoreApplication::processEvents(); | ||
531 | |||
532 | QCOMPARE(m_doneSpy->count(), 1); | ||
533 | QCOMPARE(m_waitTimeoutOccured, false); | ||
534 | QCOMPARE(m_getter->httpResponse(), 200); | ||
535 | QCOMPARE(m_daemon->lastRequestData().size(), 2); | ||
536 | QCOMPARE(m_daemon->lastRequestData().at(0).startsWith("GET"), true); | ||
537 | QCOMPARE(m_daemon->lastRequestData().at(1).startsWith("GET"), true); | ||
538 | // current implementation keeps order of query items. | ||
539 | QCOMPARE((bool)m_daemon->lastRequestData().at(1).contains("/test2.php?var=1&b=foo"), true); | ||
540 | } | ||
541 | |||
542 | QTEST_MAIN(TestHttpGet) | ||
543 | |||
544 | // this include is needed because we don't use a separate header file for the | ||
545 | // test class. It also needs to be at the end. | ||
546 | #include "test-httpget.moc" | ||
547 | |||