Преглед на файлове

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

Tatsuhiro Tsujikawa преди 12 години
родител
ревизия
e1e6bb1ec5
променени са 4 файла, в които са добавени 27 реда и са изтрити 33 реда
  1. 3 8
      src/FtpNegotiationCommand.cc
  2. 2 6
      src/HttpResponseCommand.cc
  3. 21 18
      src/RequestGroup.cc
  4. 1 1
      src/RequestGroup.h

+ 3 - 8
src/FtpNegotiationCommand.cc

@@ -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();
 

+ 2 - 6
src/HttpResponseCommand.cc

@@ -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();
 

+ 21 - 18
src/RequestGroup.cc

@@ -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(

+ 1 - 1
src/RequestGroup.h

@@ -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