mirror of https://github.com/aria2/aria2
Don't fail multiple concurrent dl same file if auto-file-renaming is enabled
parent
2aa8e01836
commit
e1e6bb1ec5
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue