Selaa lähdekoodia

2007-11-13 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	Added the ability to detect duplicate download entry which is 
about to
	download the same file other RequestGroup is downloading.
	* src/RequestGroup.cc
	* src/HttpResponseCommand.cc
	* src/FtpNegotiationCommand.cc
Tatsuhiro Tsujikawa 18 vuotta sitten
vanhempi
sitoutus
3adebc4d45
5 muutettua tiedostoa jossa 37 lisäystä ja 7 poistoa
  1. 8 0
      ChangeLog
  2. 0 1
      TODO
  3. 7 0
      src/FtpNegotiationCommand.cc
  4. 6 0
      src/HttpResponseCommand.cc
  5. 16 6
      src/RequestGroup.cc

+ 8 - 0
ChangeLog

@@ -1,3 +1,11 @@
+2007-11-13  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Added the ability to detect duplicate download entry which is about to
+	download the same file other RequestGroup is downloading.
+	* src/RequestGroup.cc
+	* src/HttpResponseCommand.cc
+	* src/FtpNegotiationCommand.cc
+
 2007-11-13  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	Recalculates download progress when loading a control file,

+ 0 - 1
TODO

@@ -56,5 +56,4 @@
   FatalException .... Program should abort.
 
 -- remaining features to be implemented for 0.12.0 release
-* Implement duplicate download checking
 * improve --metalink-location field

+ 7 - 0
src/FtpNegotiationCommand.cc

@@ -45,6 +45,8 @@
 #include "Util.h"
 #include "SingleFileDownloadContext.h"
 #include "DefaultBtProgressInfoFile.h"
+#include "RequestGroupMan.h"
+#include "DownloadFailureException.h"
 
 FtpNegotiationCommand::FtpNegotiationCommand(int32_t cuid,
 					     const RequestHandle& req,
@@ -199,6 +201,11 @@ bool FtpNegotiationCommand::recvSize() {
     dctx->setTotalLength(size);
     dctx->setFilename(Util::urldecode(req->getFile()));
 
+    if(e->_requestGroupMan->isSameFileBeingDownloaded(_requestGroup)) {
+      throw new DownloadFailureException(EX_DUPLICATE_FILE_DOWNLOAD,
+					 _requestGroup->getFilePath().c_str());
+    }
+
     _requestGroup->initPieceStorage();
 
     // validate totalsize against hintTotalSize if it is provided.

+ 6 - 0
src/HttpResponseCommand.cc

@@ -49,6 +49,8 @@
 #include "DiskAdaptor.h"
 #include "PieceStorage.h"
 #include "DefaultBtProgressInfoFile.h"
+#include "RequestGroupMan.h"
+#include "DownloadFailureException.h"
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -91,6 +93,10 @@ bool HttpResponseCommand::executeInternal()
     SingleFileDownloadContextHandle dctx = _requestGroup->getDownloadContext();
     dctx->setTotalLength(totalLength);
     dctx->setFilename(httpResponse->determinFilename());
+    if(e->_requestGroupMan->isSameFileBeingDownloaded(_requestGroup)) {
+      throw new DownloadFailureException(EX_DUPLICATE_FILE_DOWNLOAD,
+					 _requestGroup->getFilePath().c_str());
+    }
     if(totalLength == 0 || httpResponse->isTransferEncodingSpecified()) {
       // we ignore content-length when transfer-encoding is set
       dctx->setTotalLength(0);

+ 16 - 6
src/RequestGroup.cc

@@ -55,6 +55,7 @@
 #include "SingleFileDownloadContext.h"
 #include "DlAbortEx.h"
 #include "DownloadFailureException.h"
+#include "RequestGroupMan.h"
 #ifdef ENABLE_MESSAGE_DIGEST
 # include "CheckIntegrityCommand.h"
 #endif // ENABLE_MESSAGE_DIGEST
@@ -139,15 +140,14 @@ void RequestGroup::closeFile()
 
 Commands RequestGroup::createInitialCommand(DownloadEngine* e)
 {
-  // If this includes torrent download, then this method returns
-  // the command that torrent download requires, such as
-  // TrackerWatcherCommand and so on.
-
-  // It is better to avoid to using BtTorrent specific classes here.
 #ifdef ENABLE_BITTORRENT
   {
     BtContextHandle btContext = _downloadContext;
     if(!btContext.isNull()) {
+      if(e->_requestGroupMan->isSameFileBeingDownloaded(this)) {
+	throw new DownloadFailureException(EX_DUPLICATE_FILE_DOWNLOAD,
+					   getFilePath().c_str());
+      }
       if(btContext->getFileEntries().size() > 1) {
 	// this is really multi file torrent.
 	// clear http/ftp uris because the current implementation does not
@@ -155,6 +155,7 @@ Commands RequestGroup::createInitialCommand(DownloadEngine* e)
 	_logger->debug("Clearing http/ftp URIs because the current implementation does not allow integrating multi-file torrent and http/ftp.");
 	_uris.clear();
       }
+
       initPieceStorage();
 
       BtProgressInfoFileHandle progressInfoFile =
@@ -216,6 +217,10 @@ Commands RequestGroup::createInitialCommand(DownloadEngine* e)
   if(_downloadContext->getTotalLength() == 0) {
     return createNextCommand(e, 1);
   }else {
+    if(e->_requestGroupMan->isSameFileBeingDownloaded(this)) {
+      throw new DownloadFailureException(EX_DUPLICATE_FILE_DOWNLOAD,
+					 getFilePath().c_str());
+    }
     initPieceStorage();
     BtProgressInfoFileHandle infoFile =
       new DefaultBtProgressInfoFile(_downloadContext, _pieceStorage, _option);
@@ -545,7 +550,12 @@ void RequestGroup::releaseRuntimeResource()
 #ifdef ENABLE_BITTORRENT
   BtContextHandle btContext = _downloadContext;
   if(!btContext.isNull()) {
-    BtRegistry::unregister(btContext->getInfoHashAsString());
+    BtContextHandle btContextInReg = BtRegistry::getBtContext(btContext->getInfoHashAsString());
+    if(!btContextInReg.isNull() &&
+       btContextInReg->getOwnerRequestGroup()->getGID() ==
+	btContext->getOwnerRequestGroup()->getGID()) {
+      BtRegistry::unregister(btContext->getInfoHashAsString());
+    }
   }
 #endif // ENABLE_BITTORRENT
   if(!_pieceStorage.isNull()) {