diff options
author | vng <viktor.govako@gmail.com> | 2012-10-29 22:24:17 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:46:26 +0300 |
commit | 74f36cfc00ef77209261c5c2c241498022dda9eb (patch) | |
tree | dc3c048363d169d1c2a46f092bd06f948f114b58 /platform/http_request.cpp | |
parent | 4ebdce7bb3b72f2d47a989b6e57908fc60a1fbc7 (diff) |
- Fix bug with resume downloading - truncate "downloading" file if resume info is invalid;
- Reserve size for "downloading" file;
- Process FileWriter exceptions in download initializing;
Diffstat (limited to 'platform/http_request.cpp')
-rw-r--r-- | platform/http_request.cpp | 71 |
1 files changed, 44 insertions, 27 deletions
diff --git a/platform/http_request.cpp b/platform/http_request.cpp index 5cbc6158e7..2b4803abd0 100644 --- a/platform/http_request.cpp +++ b/platform/http_request.cpp @@ -212,17 +212,7 @@ class FileHttpRequest : public HttpRequest, public IHttpThreadCallback if (m_status != EInProgress) { - try - { - m_writer.reset(); - } - catch (Writer::Exception const & ex) - { - LOG(LWARNING, ("Can't close file correctly. There is not enough space, possibly.")); - - ASSERT_EQUAL ( m_status, EFailed, () ); - m_status = EFailed; - } + CloseWriter(); // clean up resume file with chunks range on success if (m_status == ECompleted) @@ -242,6 +232,20 @@ class FileHttpRequest : public HttpRequest, public IHttpThreadCallback } } + void CloseWriter() + { + try + { + m_writer.reset(); + } + catch (Writer::Exception const & ex) + { + LOG(LWARNING, ("Can't close file correctly. There is not enough space, possibly.")); + + m_status = EFailed; + } + } + public: FileHttpRequest(vector<string> const & urls, string const & filePath, int64_t fileSize, CallbackT const & onFinish, CallbackT const & onProgress, @@ -251,13 +255,29 @@ public: { ASSERT ( !urls.empty(), () ); - // Open file here. Avoid throwing exceptions from constructor's initialization list. - m_writer.reset(new FileWriter(filePath + DOWNLOADING_FILE_EXTENSION, FileWriter::OP_WRITE_EXISTING)); - + // Load resume downloading information. m_progress.first = m_strategy.LoadOrInitChunks(m_filePath + RESUME_FILE_EXTENSION, fileSize, chunkSize); m_progress.second = fileSize; + FileWriter::Op openMode = FileWriter::OP_WRITE_TRUNCATE; + if (m_progress.first != 0) + { + // Check that resume information is correct with existing file. + uint64_t size; + if (my::GetFileSize(filePath + DOWNLOADING_FILE_EXTENSION, size) && size == fileSize) + openMode = FileWriter::OP_WRITE_EXISTING; + else + m_strategy.InitChunks(fileSize, chunkSize); + } + + // Create file and reserve needed size. + scoped_ptr<FileWriter> writer(new FileWriter(filePath + DOWNLOADING_FILE_EXTENSION, openMode)); + writer->Reserve(fileSize); + + // Assign here, because previous functions can throw an exception. + m_writer.swap(writer); + #ifdef OMIM_OS_IPHONE m_writer->Flush(); DisableBackupForFile(filePath + DOWNLOADING_FILE_EXTENSION); @@ -274,12 +294,12 @@ public: if (m_status == EInProgress) { // means that client canceled download process, so delete all temporary files - m_writer.reset(); + CloseWriter(); if (m_doCleanProgressFiles) { - my::DeleteFileX(m_filePath + DOWNLOADING_FILE_EXTENSION); - my::DeleteFileX(m_filePath + RESUME_FILE_EXTENSION); + (void)my::DeleteFileX(m_filePath + DOWNLOADING_FILE_EXTENSION); + (void)my::DeleteFileX(m_filePath + RESUME_FILE_EXTENSION); } } } @@ -328,29 +348,26 @@ namespace }; } -HttpRequest * HttpRequest::GetFile(vector<string> const & urls, string const & filePath, int64_t fileSize, +HttpRequest * HttpRequest::GetFile(vector<string> const & urls, + string const & filePath, int64_t fileSize, CallbackT const & onFinish, CallbackT const & onProgress, - int64_t chunkSize, bool doCleanProgressFiles) + int64_t chunkSize, bool doCleanOnCancel) { - FileHttpRequest * p = 0; try { - p = new FileHttpRequest(urls, filePath, fileSize, onFinish, onProgress, chunkSize, doCleanProgressFiles); + return new FileHttpRequest(urls, filePath, fileSize, onFinish, onProgress, chunkSize, doCleanOnCancel); } catch (FileWriter::Exception const & e) { - // Can't create file for writing. + // Can't create or open file for writing. LOG(LERROR, ("Can't create FileHttpRequest for", filePath, e.what())); - delete p; - p = 0; - // Mark the end of download with error. ErrorHttpRequest error(filePath); onFinish(error); - } - return p; + return 0; + } } } // namespace downloader |