diff --git a/ChangeLog b/ChangeLog index 05148c00..a0b2841e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2009-06-21 Tatsuhiro Tsujikawa + + In CookieStorage::load() and saveNsFormat(), handle exception + inside the functions. When saving Cookies, first write temporary + file and after successful writes, then renames it to final + destination. + * src/CookieStorage.cc + * src/CookieStorage.h + * src/MultiUrlRequestInfo.cc + 2009-06-21 Tatsuhiro Tsujikawa The default value of --dir option is the absolute path to the diff --git a/src/CookieStorage.cc b/src/CookieStorage.cc index 9df2b40c..3e838657 100644 --- a/src/CookieStorage.cc +++ b/src/CookieStorage.cc @@ -141,17 +141,15 @@ size_t CookieStorage::size() const return _cookies.size(); } -void CookieStorage::load(const std::string& filename) +bool CookieStorage::load(const std::string& filename) { char header[16]; // "SQLite format 3" plus \0 - { - std::ifstream s(filename.c_str(), std::ios::binary); - s.get(header, sizeof(header)); - if(!s) { - throw DL_ABORT_EX - (StringFormat("Failed to read header of cookie file %s", - filename.c_str()).str()); - } + std::ifstream s(filename.c_str(), std::ios::binary); + s.get(header, sizeof(header)); + if(!s) { + _logger->error("Failed to read header of cookie file %s", + filename.c_str()); + return false; } try { if(std::string(header) == "SQLite format 3") { @@ -165,29 +163,37 @@ void CookieStorage::load(const std::string& filename) } else { storeCookies(NsCookieParser().parse(filename)); } + return true; } catch(RecoverableException& e) { - throw DL_ABORT_EX2 - (StringFormat("Failed to load cookies from %s", filename.c_str()).str(), - e); + _logger->error("Failed to load cookies from %s", filename.c_str()); + return false; } } -void CookieStorage::saveNsFormat(const std::string& filename) +bool CookieStorage::saveNsFormat(const std::string& filename) { - std::ofstream o(filename.c_str(), std::ios::binary); + std::string tempfilename = filename+"__temp"; + std::ofstream o(tempfilename.c_str(), std::ios::binary); if(!o) { - throw DL_ABORT_EX - (StringFormat("Cannot create cookie file %s, cause %s", - filename.c_str(), strerror(errno)).str()); + _logger->error("Cannot create cookie file %s, cause %s", + filename.c_str(), strerror(errno)); + return false; } for(std::deque::const_iterator i = _cookies.begin(); i != _cookies.end(); ++i) { o << (*i).toNsCookieFormat() << "\n"; if(!o) { - throw DL_ABORT_EX - (StringFormat("Failed to save cookies to %s", filename.c_str()).str()); + _logger->error("Failed to save cookies to %s", filename.c_str()); + return false; } } + if(File(tempfilename).renameTo(filename)) { + return true; + } else { + _logger->error("Could not rename file %s as %s", + tempfilename.c_str(), filename.c_str()); + return false; + } } } // namespace aria2 diff --git a/src/CookieStorage.h b/src/CookieStorage.h index 32a12809..0b0b1571 100644 --- a/src/CookieStorage.h +++ b/src/CookieStorage.h @@ -76,9 +76,17 @@ public: const std::string& requestPath, time_t date, bool secure) const; - void load(const std::string& filename); + // Loads Cookies from file denoted by filename. If compiled with + // libsqlite3, this method automatically detects the specified file + // is sqlite3 or just plain text file and calls appropriate parser + // implementation class. If Cookies are successfully loaded, this + // method returns true. Otherwise, this method returns false. + bool load(const std::string& filename); - void saveNsFormat(const std::string& filename); + // Saves Cookies in Netspace format which is used in + // Firefox1.2/Netscape/Mozilla. If Cookies are successfully saved, + // this method returns true, otherwise returns false. + bool saveNsFormat(const std::string& filename); size_t size() const; diff --git a/src/MultiUrlRequestInfo.cc b/src/MultiUrlRequestInfo.cc index 82a45083..e388ef72 100644 --- a/src/MultiUrlRequestInfo.cc +++ b/src/MultiUrlRequestInfo.cc @@ -106,18 +106,14 @@ DownloadResult::RESULT MultiUrlRequestInfo::execute() DownloadEngineHandle e = DownloadEngineFactory().newDownloadEngine(_option.get(), _requestGroups); - try { - if(!_option->blank(PREF_LOAD_COOKIES)) { - File cookieFile(_option->get(PREF_LOAD_COOKIES)); - if(cookieFile.isFile()) { - e->getCookieStorage()->load(_option->get(PREF_LOAD_COOKIES)); - } else { - _logger->error(MSG_LOADING_COOKIE_FAILED, - _option->get(PREF_LOAD_COOKIES).c_str()); - } + if(!_option->blank(PREF_LOAD_COOKIES)) { + File cookieFile(_option->get(PREF_LOAD_COOKIES)); + if(cookieFile.isFile()) { + e->getCookieStorage()->load(_option->get(PREF_LOAD_COOKIES)); + } else { + _logger->error(MSG_LOADING_COOKIE_FAILED, + _option->get(PREF_LOAD_COOKIES).c_str()); } - } catch(RecoverableException& e) { - _logger->error(EX_EXCEPTION_CAUGHT, e); } SharedHandle authConfigFactory @@ -183,11 +179,7 @@ DownloadResult::RESULT MultiUrlRequestInfo::execute() e->run(); if(!_option->blank(PREF_SAVE_COOKIES)) { - try { - e->getCookieStorage()->saveNsFormat(_option->get(PREF_SAVE_COOKIES)); - } catch(RecoverableException& e) { - _logger->error(EX_EXCEPTION_CAUGHT, e); - } + e->getCookieStorage()->saveNsFormat(_option->get(PREF_SAVE_COOKIES)); } std::string serverStatOf = _option->get(PREF_SERVER_STAT_OF);