Don't fail multiple concurrent dl same file if auto-file-renaming is enabled

pull/150/head
Tatsuhiro Tsujikawa 2013-11-08 00:59:57 +09:00
parent 2aa8e01836
commit e1e6bb1ec5
4 changed files with 27 additions and 33 deletions

View File

@ -74,6 +74,7 @@
#include "CheckIntegrityEntry.h"
#include "error_code.h"
#include "SocketRecvBuffer.h"
#include "NullProgressInfoFile.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "ChecksumCheckIntegrityEntry.h"
#endif // ENABLE_MESSAGE_DIGEST
@ -369,13 +370,6 @@ bool FtpNegotiationCommand::onFileSizeDetermined(int64_t totalLength)
getRequest()->getFile().end())));
}
getRequestGroup()->preDownloadProcessing();
if(getDownloadEngine()->getRequestGroupMan()->
isSameFileBeingDownloaded(getRequestGroup())) {
throw DOWNLOAD_FAILURE_EXCEPTION2
(fmt(EX_DUPLICATE_FILE_DOWNLOAD,
getRequestGroup()->getFirstFilePath().c_str()),
error_code::DUPLICATE_DOWNLOAD);
}
if(totalLength == 0) {
if(getOption()->getAsBool(PREF_FTP_PASV)) {
@ -422,7 +416,8 @@ bool FtpNegotiationCommand::onFileSizeDetermined(int64_t totalLength)
return false;
}
getRequestGroup()->shouldCancelDownloadForSafety();
getRequestGroup()->adjustFilename
(std::make_shared<NullProgressInfoFile>());
getRequestGroup()->initPieceStorage();
getPieceStorage()->getDiskAdaptor()->initAndOpenFile();

View File

@ -74,6 +74,7 @@
#include "uri.h"
#include "SocketRecvBuffer.h"
#include "MetalinkHttpEntry.h"
#include "NullProgressInfoFile.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "Checksum.h"
# include "ChecksumCheckIntegrityEntry.h"
@ -258,11 +259,6 @@ bool HttpResponseCommand::executeInternal()
}
fe->setContentType(httpResponse->getContentType());
grp->preDownloadProcessing();
if (getDownloadEngine()->getRequestGroupMan()->isSameFileBeingDownloaded(grp)) {
throw DOWNLOAD_FAILURE_EXCEPTION2(fmt(EX_DUPLICATE_FILE_DOWNLOAD,
grp->getFirstFilePath().c_str()),
error_code::DUPLICATE_DOWNLOAD);
}
// update last modified time
updateLastModifiedTime(httpResponse->getLastModifiedTime());
@ -451,7 +447,7 @@ bool HttpResponseCommand::handleOtherEncoding(
return true;
}
getRequestGroup()->shouldCancelDownloadForSafety();
getRequestGroup()->adjustFilename(std::make_shared<NullProgressInfoFile>());
getRequestGroup()->initPieceStorage();
getPieceStorage()->getDiskAdaptor()->initAndOpenFile();

View File

@ -465,11 +465,6 @@ void RequestGroup::createInitialCommand(
createNextCommand(commands, e, 1);
return;
}
if (e->getRequestGroupMan()->isSameFileBeingDownloaded(this)) {
throw DOWNLOAD_FAILURE_EXCEPTION2(fmt(EX_DUPLICATE_FILE_DOWNLOAD,
downloadContext_->getBasePath().c_str()),
error_code::DUPLICATE_DOWNLOAD);
}
auto progressInfoFile = std::make_shared<DefaultBtProgressInfoFile>(
downloadContext_,
nullptr,
@ -652,6 +647,15 @@ void RequestGroup::adjustFilename(
// OK, no need to care about filename.
return;
}
// TODO need this?
if(requestGroupMan_) {
if(requestGroupMan_->isSameFileBeingDownloaded(this)) {
// The file name must be renamed
tryAutoFileRenaming();
A2_LOG_NOTICE(fmt(MSG_FILE_RENAMED, getFirstFilePath().c_str()));
return;
}
}
if (!option_->getAsBool(PREF_DRY_RUN) &&
option_->getAsBool(PREF_REMOVE_CONTROL_FILE) &&
infoFile->exists()) {
@ -743,37 +747,36 @@ void RequestGroup::shouldCancelDownloadForSafety()
return;
}
tryAutoFileRenaming();
A2_LOG_NOTICE(fmt(MSG_FILE_RENAMED, getFirstFilePath().c_str()));
}
void RequestGroup::tryAutoFileRenaming()
{
if (!option_->getAsBool(PREF_AUTO_FILE_RENAMING)) {
throw DOWNLOAD_FAILURE_EXCEPTION2(fmt(MSG_FILE_ALREADY_EXISTS,
getFirstFilePath().c_str()),
error_code::FILE_ALREADY_EXISTS);
}
if (!tryAutoFileRenaming()) {
std::string filepath = getFirstFilePath();
if(filepath.empty()) {
throw DOWNLOAD_FAILURE_EXCEPTION2(fmt("File renaming failed: %s",
getFirstFilePath().c_str()),
error_code::FILE_RENAMING_FAILED);
}
A2_LOG_NOTICE(fmt(MSG_FILE_RENAMED, getFirstFilePath().c_str()));
}
bool RequestGroup::tryAutoFileRenaming()
{
std::string filepath = getFirstFilePath();
if(filepath.empty()) {
return false;
}
for (int i = 1; i < 10000; ++i) {
auto newfilename = fmt("%s.%d", filepath.c_str(), i);
File newfile(newfilename);
File ctrlfile(newfile.getPath() + DefaultBtProgressInfoFile::getSuffix());
if (!newfile.exists() || (newfile.exists() && ctrlfile.exists())) {
downloadContext_->getFirstFileEntry()->setPath(newfile.getPath());
return true;
return;
}
}
return false;
throw DOWNLOAD_FAILURE_EXCEPTION2(fmt("File renaming failed: %s",
getFirstFilePath().c_str()),
error_code::FILE_RENAMING_FAILED);
}
void RequestGroup::createNextCommandWithAdj(

View File

@ -185,7 +185,7 @@ private:
void initializePostDownloadHandler();
bool tryAutoFileRenaming();
void tryAutoFileRenaming();
// Returns the result code of this RequestGroup. If the download
// finished, then returns error_code::FINISHED. If the