Mercurial > trustbridge
comparison ui/downloader_win.cpp @ 17:c12825a651ed
Read out content-length and use this to skip existing files
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Wed, 19 Feb 2014 14:22:26 +0000 |
parents | 95e1b6edf2fc |
children | f4f957c58e0a |
comparison
equal
deleted
inserted
replaced
16:225a5ec20dad | 17:c12825a651ed |
---|---|
19 #include <winhttp.h> | 19 #include <winhttp.h> |
20 | 20 |
21 #include <QDebug> | 21 #include <QDebug> |
22 #include <QDateTime> | 22 #include <QDateTime> |
23 #include <QSaveFile> | 23 #include <QSaveFile> |
24 #include <QFileInfo> | |
24 | 25 |
25 #define DEBUG if (1) qDebug() << __PRETTY_FUNCTION__ | 26 #define DEBUG if (1) qDebug() << __PRETTY_FUNCTION__ |
26 | 27 |
27 #define MAX_SW_SIZE 10485760 | 28 #define MAX_SW_SIZE 10485760 |
28 #define MAX_LIST_SIZE 1048576 | 29 #define MAX_LIST_SIZE 1048576 |
30 | |
31 | |
32 #define LIST_RESOURCE "/incoming/aheinecke/test" | |
33 #define SW_RESOURCE "/incoming/aheinecke/test" | |
34 | |
29 | 35 |
30 /** @brief Qt wrapper around FormatMessage | 36 /** @brief Qt wrapper around FormatMessage |
31 * | 37 * |
32 * @returns The error message of the error that occurred | 38 * @returns The error message of the error that occurred |
33 */ | 39 */ |
279 SetLastError(err); | 285 SetLastError(err); |
280 return retval; | 286 return retval; |
281 } | 287 } |
282 | 288 |
283 bool Downloader::downloadFile(HINTERNET hSession, HINTERNET hConnect, | 289 bool Downloader::downloadFile(HINTERNET hSession, HINTERNET hConnect, |
284 LPCWSTR resource, const QString &filename, DWORD maxSize) | 290 LPCWSTR resource, const QString &fileName, DWORD maxSize) |
285 { | 291 { |
286 HINTERNET hRequest = NULL; | 292 HINTERNET hRequest = NULL; |
287 bool retval = false; | 293 bool retval = false; |
288 DWORD bytesAvailable = 0, | 294 DWORD bytesAvailable = 0, |
289 err = 0, | 295 err = 0, |
290 bytesRead = 0, | 296 bytesRead = 0, |
291 totalDownloaded = 0; | 297 totalDownloaded = 0, |
292 | 298 contentLength = 0, |
293 QSaveFile outputFile(filename); | 299 sizeOfDWORD = sizeof (DWORD); |
300 | |
301 QSaveFile outputFile(fileName); | |
294 | 302 |
295 if (!hSession || !hConnect || !resource) { | 303 if (!hSession || !hConnect || !resource) { |
296 SetLastError(ERROR_INVALID_PARAMETER); | 304 SetLastError(ERROR_INVALID_PARAMETER); |
297 return retval; | 305 return retval; |
298 } | 306 } |
320 if (!verifyCertificate(hRequest)) { | 328 if (!verifyCertificate(hRequest)) { |
321 DEBUG << "Certificate verification failed"; | 329 DEBUG << "Certificate verification failed"; |
322 // TODO error out | 330 // TODO error out |
323 } | 331 } |
324 | 332 |
333 | |
334 if (!(WinHttpQueryHeaders(hRequest, | |
335 WINHTTP_QUERY_CONTENT_LENGTH | | |
336 WINHTTP_QUERY_FLAG_NUMBER, | |
337 NULL, | |
338 &contentLength, | |
339 &sizeOfDWORD, | |
340 WINHTTP_NO_HEADER_INDEX))) { | |
341 // Continue anyway as we later really check how | |
342 // much we download. | |
343 DEBUG << "No content-length"; | |
344 } | |
345 | |
346 if (contentLength > maxSize) { | |
347 err = ERROR_INVALID_DATA; | |
348 goto cleanup; | |
349 } | |
350 | |
351 if (contentLength) { | |
352 QFileInfo finf(fileName); | |
353 if (finf.exists() && finf.isReadable() && | |
354 finf.size() == contentLength) { | |
355 // We already have data of the same size | |
356 // No need to waste bandwidth. | |
357 DEBUG << "Skipping download because file exists"; | |
358 retval = true; | |
359 goto cleanup; | |
360 } | |
361 } | |
362 | |
325 // Open / Create the file to write to. | 363 // Open / Create the file to write to. |
326 if (!outputFile.open(QIODevice::WriteOnly)) { | 364 if (!outputFile.open(QIODevice::WriteOnly)) { |
327 DEBUG << "Failed to open file"; | 365 DEBUG << "Failed to open file"; |
328 err = GetLastError(); | 366 err = GetLastError(); |
329 goto cleanup; | 367 goto cleanup; |
330 } | 368 } |
331 | 369 |
370 DEBUG << "output file size: " << outputFile.size(); | |
332 do | 371 do |
333 { | 372 { |
334 char outBuf[8192]; // 8KB is the internal buffer size of winhttp | 373 char outBuf[8192]; // 8KB is the internal buffer size of winhttp |
335 memset(outBuf, 0, sizeof(outBuf)); | 374 memset(outBuf, 0, sizeof(outBuf)); |
336 bytesRead = 0; | 375 bytesRead = 0; |
348 } | 387 } |
349 | 388 |
350 if (bytesAvailable > maxSize) { | 389 if (bytesAvailable > maxSize) { |
351 DEBUG << "File to large"; | 390 DEBUG << "File to large"; |
352 retval = false; | 391 retval = false; |
392 err = ERROR_INVALID_DATA; | |
353 break; | 393 break; |
354 } | 394 } |
355 | 395 |
356 if (!WinHttpReadData(hRequest, (LPVOID)outBuf, | 396 if (!WinHttpReadData(hRequest, (LPVOID)outBuf, |
357 sizeof(outBuf), &bytesRead)) { | 397 sizeof(outBuf), &bytesRead)) { |
358 DEBUG << "Error reading data"; | 398 DEBUG << "Error reading data"; |
359 err = GetLastError(); | 399 err = GetLastError(); |
360 break; | 400 break; |
361 } else { | 401 } else { |
362 if (bytesRead) { | 402 if (bytesRead) { |
363 DEBUG << "Downloaded: " << bytesRead << "B"; | |
364 | |
365 // Write data to file. | 403 // Write data to file. |
366 if (outputFile.write(outBuf, bytesRead) != | 404 if (outputFile.write(outBuf, bytesRead) != |
367 bytesRead) { | 405 bytesRead) { |
368 err = GetLastError(); | 406 err = GetLastError(); |
369 DEBUG << "Error writing to file."; | 407 DEBUG << "Error writing to file."; |
390 } | 428 } |
391 } while (bytesAvailable > 0); | 429 } while (bytesAvailable > 0); |
392 | 430 |
393 cleanup: | 431 cleanup: |
394 | 432 |
395 if (retval) { | 433 if (retval && outputFile.isOpen()) { |
396 // Actually save the file to disk / move to homedir | 434 // Actually save the file to disk / move to homedir |
397 retval = outputFile.commit(); | 435 retval = outputFile.commit(); |
398 } | 436 } |
399 | 437 |
400 if (hRequest) { | 438 if (hRequest) { |
438 goto cleanup; | 476 goto cleanup; |
439 } | 477 } |
440 | 478 |
441 | 479 |
442 lastModifiedSoftware = getLastModifiedHeader(hSession, hConnect, | 480 lastModifiedSoftware = getLastModifiedHeader(hSession, hConnect, |
443 L"/incoming/aheinecke/test"); | 481 L""SW_RESOURCE); |
444 | 482 |
445 lastModifiedList = getLastModifiedHeader(hSession, hConnect, | 483 lastModifiedList = getLastModifiedHeader(hSession, hConnect, |
446 L"/incoming/aheinecke/test"); | 484 L""LIST_RESOURCE); |
447 | 485 |
448 if (!lastModifiedList.isValid() || !lastModifiedSoftware.isValid()) { | 486 if (!lastModifiedList.isValid() || !lastModifiedSoftware.isValid()) { |
449 DEBUG << "Could not read headers: " << getLastErrorMsg(); | 487 DEBUG << "Could not read headers: " << getLastErrorMsg(); |
450 goto cleanup; | 488 goto cleanup; |
451 } | 489 } |
460 | 498 |
461 QString fileName = dataDirectory.append("/SW-") | 499 QString fileName = dataDirectory.append("/SW-") |
462 .append(lastModifiedSoftware.toString("yyyymmddHHmmss")) | 500 .append(lastModifiedSoftware.toString("yyyymmddHHmmss")) |
463 .append(".exe"); | 501 .append(".exe"); |
464 | 502 |
465 DEBUG << "Filename: " << fileName; | 503 DEBUG << "fileName: " << fileName; |
466 | 504 |
467 if (!downloadFile(hSession, hConnect, L"/incoming/aheinecke/test", | 505 if (!downloadFile(hSession, hConnect, L""SW_RESOURCE, |
468 fileName, MAX_SW_SIZE)) { | 506 fileName, MAX_SW_SIZE)) { |
469 DEBUG << "Error downloading File: " << getLastErrorMsg(); | 507 DEBUG << "Error downloading File: " << getLastErrorMsg(); |
470 goto cleanup; | 508 goto cleanup; |
471 } | 509 } |
472 | 510 |
481 | 519 |
482 QString fileName = dataDirectory.append("/list-") | 520 QString fileName = dataDirectory.append("/list-") |
483 .append(lastModifiedSoftware.toString("yyyymmddHHmmss")) | 521 .append(lastModifiedSoftware.toString("yyyymmddHHmmss")) |
484 .append(".txt"); | 522 .append(".txt"); |
485 | 523 |
486 DEBUG << "Filename: " << fileName; | 524 DEBUG << "fileName: " << fileName; |
487 | 525 |
488 if (!downloadFile(hSession, hConnect, L"/incoming/aheinecke/test", | 526 if (!downloadFile(hSession, hConnect, L""LIST_RESOURCE, |
489 fileName, MAX_LIST_SIZE)) { | 527 fileName, MAX_LIST_SIZE)) { |
490 DEBUG << "Error downloading File: " << getLastErrorMsg(); | 528 DEBUG << "Error downloading File: " << getLastErrorMsg(); |
491 goto cleanup; | 529 goto cleanup; |
492 } | 530 } |
493 | 531 |