2009-06-21 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

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
pull/1/head
Tatsuhiro Tsujikawa 2009-06-21 10:26:14 +00:00
parent 8d4f29d302
commit f3c79ebf05
4 changed files with 53 additions and 37 deletions

View File

@ -1,3 +1,13 @@
2009-06-21 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
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 <t-tujikawa@users.sourceforge.net> 2009-06-21 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
The default value of --dir option is the absolute path to the The default value of --dir option is the absolute path to the

View File

@ -141,17 +141,15 @@ size_t CookieStorage::size() const
return _cookies.size(); 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 char header[16]; // "SQLite format 3" plus \0
{ std::ifstream s(filename.c_str(), std::ios::binary);
std::ifstream s(filename.c_str(), std::ios::binary); s.get(header, sizeof(header));
s.get(header, sizeof(header)); if(!s) {
if(!s) { _logger->error("Failed to read header of cookie file %s",
throw DL_ABORT_EX filename.c_str());
(StringFormat("Failed to read header of cookie file %s", return false;
filename.c_str()).str());
}
} }
try { try {
if(std::string(header) == "SQLite format 3") { if(std::string(header) == "SQLite format 3") {
@ -165,29 +163,37 @@ void CookieStorage::load(const std::string& filename)
} else { } else {
storeCookies(NsCookieParser().parse(filename)); storeCookies(NsCookieParser().parse(filename));
} }
return true;
} catch(RecoverableException& e) { } catch(RecoverableException& e) {
throw DL_ABORT_EX2 _logger->error("Failed to load cookies from %s", filename.c_str());
(StringFormat("Failed to load cookies from %s", filename.c_str()).str(), return false;
e);
} }
} }
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) { if(!o) {
throw DL_ABORT_EX _logger->error("Cannot create cookie file %s, cause %s",
(StringFormat("Cannot create cookie file %s, cause %s", filename.c_str(), strerror(errno));
filename.c_str(), strerror(errno)).str()); return false;
} }
for(std::deque<Cookie>::const_iterator i = _cookies.begin(); for(std::deque<Cookie>::const_iterator i = _cookies.begin();
i != _cookies.end(); ++i) { i != _cookies.end(); ++i) {
o << (*i).toNsCookieFormat() << "\n"; o << (*i).toNsCookieFormat() << "\n";
if(!o) { if(!o) {
throw DL_ABORT_EX _logger->error("Failed to save cookies to %s", filename.c_str());
(StringFormat("Failed to save cookies to %s", filename.c_str()).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 } // namespace aria2

View File

@ -76,9 +76,17 @@ public:
const std::string& requestPath, const std::string& requestPath,
time_t date, bool secure) const; 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; size_t size() const;

View File

@ -106,18 +106,14 @@ DownloadResult::RESULT MultiUrlRequestInfo::execute()
DownloadEngineHandle e = DownloadEngineHandle e =
DownloadEngineFactory().newDownloadEngine(_option.get(), _requestGroups); DownloadEngineFactory().newDownloadEngine(_option.get(), _requestGroups);
try { if(!_option->blank(PREF_LOAD_COOKIES)) {
if(!_option->blank(PREF_LOAD_COOKIES)) { File cookieFile(_option->get(PREF_LOAD_COOKIES));
File cookieFile(_option->get(PREF_LOAD_COOKIES)); if(cookieFile.isFile()) {
if(cookieFile.isFile()) { e->getCookieStorage()->load(_option->get(PREF_LOAD_COOKIES));
e->getCookieStorage()->load(_option->get(PREF_LOAD_COOKIES)); } else {
} else { _logger->error(MSG_LOADING_COOKIE_FAILED,
_logger->error(MSG_LOADING_COOKIE_FAILED, _option->get(PREF_LOAD_COOKIES).c_str());
_option->get(PREF_LOAD_COOKIES).c_str());
}
} }
} catch(RecoverableException& e) {
_logger->error(EX_EXCEPTION_CAUGHT, e);
} }
SharedHandle<AuthConfigFactory> authConfigFactory SharedHandle<AuthConfigFactory> authConfigFactory
@ -183,11 +179,7 @@ DownloadResult::RESULT MultiUrlRequestInfo::execute()
e->run(); e->run();
if(!_option->blank(PREF_SAVE_COOKIES)) { if(!_option->blank(PREF_SAVE_COOKIES)) {
try { e->getCookieStorage()->saveNsFormat(_option->get(PREF_SAVE_COOKIES));
e->getCookieStorage()->saveNsFormat(_option->get(PREF_SAVE_COOKIES));
} catch(RecoverableException& e) {
_logger->error(EX_EXCEPTION_CAUGHT, e);
}
} }
std::string serverStatOf = _option->get(PREF_SERVER_STAT_OF); std::string serverStatOf = _option->get(PREF_SERVER_STAT_OF);