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

View File

@ -74,6 +74,7 @@
#include "uri.h" #include "uri.h"
#include "SocketRecvBuffer.h" #include "SocketRecvBuffer.h"
#include "MetalinkHttpEntry.h" #include "MetalinkHttpEntry.h"
#include "NullProgressInfoFile.h"
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
# include "Checksum.h" # include "Checksum.h"
# include "ChecksumCheckIntegrityEntry.h" # include "ChecksumCheckIntegrityEntry.h"
@ -258,11 +259,6 @@ bool HttpResponseCommand::executeInternal()
} }
fe->setContentType(httpResponse->getContentType()); fe->setContentType(httpResponse->getContentType());
grp->preDownloadProcessing(); 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 // update last modified time
updateLastModifiedTime(httpResponse->getLastModifiedTime()); updateLastModifiedTime(httpResponse->getLastModifiedTime());
@ -451,7 +447,7 @@ bool HttpResponseCommand::handleOtherEncoding(
return true; return true;
} }
getRequestGroup()->shouldCancelDownloadForSafety(); getRequestGroup()->adjustFilename(std::make_shared<NullProgressInfoFile>());
getRequestGroup()->initPieceStorage(); getRequestGroup()->initPieceStorage();
getPieceStorage()->getDiskAdaptor()->initAndOpenFile(); getPieceStorage()->getDiskAdaptor()->initAndOpenFile();

View File

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

View File

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