2007-10-15 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

* src/Metalink2RequestGroup.cc (generate): Throw exception 
instead of
	catching it inside the method.
	When no file entry is found in a metalink without querying user
	preferences, throw the exception with the error message that 
suggests
	metalink file is probably broken. 
	* src/RequestGroup.cc (postDownloadProcessing): Catch exception 
here.
pull/1/head
Tatsuhiro Tsujikawa 2007-10-15 14:55:24 +00:00
parent 0ead885da5
commit e8a3167596
4 changed files with 108 additions and 94 deletions

View File

@ -1,3 +1,12 @@
2007-10-15 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/Metalink2RequestGroup.cc (generate): Throw exception instead of
catching it inside the method.
When no file entry is found in a metalink without querying user
preferences, throw the exception with the error message that suggests
metalink file is probably broken.
* src/RequestGroup.cc (postDownloadProcessing): Catch exception here.
2007-10-15 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2007-10-15 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Fixed the bug that prevents remote Metalink/Torrent file from begin Fixed the bug that prevents remote Metalink/Torrent file from begin

2
TODO
View File

@ -52,4 +52,4 @@
* Implement duplicate download checking in Bt * Implement duplicate download checking in Bt
* Implement the feature to treat http/ftp as auxuality download method for BitTorrent * Implement the feature to treat http/ftp as auxuality download method for BitTorrent
* Fixed the download error when sending "CWD //*" to the ftp server

View File

@ -40,7 +40,6 @@
#include "Xml2MetalinkProcessor.h" #include "Xml2MetalinkProcessor.h"
#include "Util.h" #include "Util.h"
#include "message.h" #include "message.h"
#include "RecoverableException.h"
#include "BtDependency.h" #include "BtDependency.h"
#include "SingleFileDownloadContext.h" #include "SingleFileDownloadContext.h"
@ -94,102 +93,101 @@ public:
RequestGroups Metalink2RequestGroup::generate(const string& metalinkFile) RequestGroups Metalink2RequestGroup::generate(const string& metalinkFile)
{ {
Xml2MetalinkProcessor proc; Xml2MetalinkProcessor proc;
try {
MetalinkerHandle metalinker = proc.parseFile(metalinkFile); MetalinkerHandle metalinker = proc.parseFile(metalinkFile);
MetalinkEntries entries = if(metalinker->entries.empty()) {
metalinker->queryEntry(_option->get(PREF_METALINK_VERSION), throw new DlAbortEx("No file entry found. Probably, the metalink file is not configured properly or broken.");
_option->get(PREF_METALINK_LANGUAGE), }
_option->get(PREF_METALINK_OS)); MetalinkEntries entries =
if(entries.size() == 0) { metalinker->queryEntry(_option->get(PREF_METALINK_VERSION),
return RequestGroups(); _option->get(PREF_METALINK_LANGUAGE),
_option->get(PREF_METALINK_OS));
if(entries.size() == 0) {
_logger->notice(EX_NO_RESULT_WITH_YOUR_PREFS);
return RequestGroups();
}
bool useIndex;
Integers selectIndexes;
Util::unfoldRange(_option->get(PREF_SELECT_FILE), selectIndexes);
if(selectIndexes.size()) {
useIndex = true;
} else {
useIndex = false;
}
RequestGroups groups;
int32_t count = 0;
for(MetalinkEntries::iterator itr = entries.begin(); itr != entries.end();
itr++, ++count) {
MetalinkEntryHandle& entry = *itr;
if(_option->defined(PREF_METALINK_LOCATION)) {
entry->setLocationPreference(_option->get(PREF_METALINK_LOCATION), 100);
} }
bool useIndex; if(useIndex) {
Integers selectIndexes; if(find(selectIndexes.begin(), selectIndexes.end(), count+1) == selectIndexes.end()) {
Util::unfoldRange(_option->get(PREF_SELECT_FILE), selectIndexes);
if(selectIndexes.size()) {
useIndex = true;
} else {
useIndex = false;
}
RequestGroups groups;
int32_t count = 0;
for(MetalinkEntries::iterator itr = entries.begin(); itr != entries.end();
itr++, ++count) {
MetalinkEntryHandle& entry = *itr;
if(_option->defined(PREF_METALINK_LOCATION)) {
entry->setLocationPreference(_option->get(PREF_METALINK_LOCATION), 100);
}
if(useIndex) {
if(find(selectIndexes.begin(), selectIndexes.end(), count+1) == selectIndexes.end()) {
continue;
}
}
entry->dropUnsupportedResource();
if(entry->resources.size() == 0) {
continue; continue;
} }
_logger->info(MSG_METALINK_QUEUEING, entry->getPath().c_str()); }
MetalinkResources::iterator itr = find_if(entry->resources.begin(), entry->dropUnsupportedResource();
entry->resources.end(), if(entry->resources.size() == 0) {
FindBitTorrentUrl()); continue;
RequestGroupHandle torrentRg = 0; }
// there is torrent entry _logger->info(MSG_METALINK_QUEUEING, entry->getPath().c_str());
if(itr != entry->resources.end()) { MetalinkResources::iterator itr = find_if(entry->resources.begin(),
Strings uris; entry->resources.end(),
uris.push_back((*itr)->url); FindBitTorrentUrl());
torrentRg = new RequestGroup(_option, uris); RequestGroupHandle torrentRg = 0;
SingleFileDownloadContextHandle dctx = // there is torrent entry
new SingleFileDownloadContext(_option->getAsInt(PREF_SEGMENT_SIZE), if(itr != entry->resources.end()) {
0,
"");
dctx->setDir(_option->get(PREF_DIR));
torrentRg->setDownloadContext(dctx);
torrentRg->clearPostDowloadHandler();
groups.push_back(torrentRg);
}
entry->reorderResourcesByPreference();
Strings uris; Strings uris;
for_each(entry->resources.begin(), entry->resources.end(), uris.push_back((*itr)->url);
AccumulateNonP2PUrl(&uris, _option->getAsInt(PREF_SPLIT))); torrentRg = new RequestGroup(_option, uris);
RequestGroupHandle rg = new RequestGroup(_option, uris);
// If piece hash is specified in the metalink,
// make segment size equal to piece hash size.
int32_t pieceLength;
if(entry->chunkChecksum.isNull()) {
pieceLength = _option->getAsInt(PREF_SEGMENT_SIZE);
} else {
pieceLength = entry->chunkChecksum->getChecksumLength();
}
SingleFileDownloadContextHandle dctx = SingleFileDownloadContextHandle dctx =
new SingleFileDownloadContext(pieceLength, new SingleFileDownloadContext(_option->getAsInt(PREF_SEGMENT_SIZE),
0, 0,
""); "");
dctx->setDir(_option->get(PREF_DIR)); dctx->setDir(_option->get(PREF_DIR));
if(!entry->chunkChecksum.isNull()) { torrentRg->setDownloadContext(dctx);
dctx->setPieceHashes(entry->chunkChecksum->getChecksums()); torrentRg->clearPostDowloadHandler();
dctx->setPieceHashAlgo(entry->chunkChecksum->getAlgo()); groups.push_back(torrentRg);
}
// TODO set checksum here to DownloadContext
// * hash and hash algorithm
rg->setDownloadContext(dctx);
rg->setHintFilename(entry->file->getBasename());
rg->setHintTotalLength(entry->getLength());
rg->setNumConcurrentCommand(entry->maxConnections < 0 ?
_option->getAsInt(PREF_METALINK_SERVERS) :
min<int32_t>(_option->getAsInt(PREF_METALINK_SERVERS), entry->maxConnections));
// Inject depenency between rg and torrentRg here if torrentRg.isNull() == false
if(!torrentRg.isNull()) {
rg->dependsOn(new BtDependency(rg, torrentRg, _option));
}
groups.push_back(rg);
} }
return groups; entry->reorderResourcesByPreference();
} catch(RecoverableException* ex) { Strings uris;
_logger->error(EX_EXCEPTION_CAUGHT, ex); for_each(entry->resources.begin(), entry->resources.end(),
delete ex; AccumulateNonP2PUrl(&uris, _option->getAsInt(PREF_SPLIT)));
return RequestGroups(); RequestGroupHandle rg = new RequestGroup(_option, uris);
// If piece hash is specified in the metalink,
// make segment size equal to piece hash size.
int32_t pieceLength;
if(entry->chunkChecksum.isNull()) {
pieceLength = _option->getAsInt(PREF_SEGMENT_SIZE);
} else {
pieceLength = entry->chunkChecksum->getChecksumLength();
}
SingleFileDownloadContextHandle dctx =
new SingleFileDownloadContext(pieceLength,
0,
"");
dctx->setDir(_option->get(PREF_DIR));
if(!entry->chunkChecksum.isNull()) {
dctx->setPieceHashes(entry->chunkChecksum->getChecksums());
dctx->setPieceHashAlgo(entry->chunkChecksum->getAlgo());
}
// TODO set checksum here to DownloadContext
// * hash and hash algorithm
rg->setDownloadContext(dctx);
rg->setHintFilename(entry->file->getBasename());
rg->setHintTotalLength(entry->getLength());
rg->setNumConcurrentCommand(entry->maxConnections < 0 ?
_option->getAsInt(PREF_METALINK_SERVERS) :
min<int32_t>(_option->getAsInt(PREF_METALINK_SERVERS), entry->maxConnections));
// Inject depenency between rg and torrentRg here if torrentRg.isNull() == false
if(!torrentRg.isNull()) {
rg->dependsOn(new BtDependency(rg, torrentRg, _option));
}
groups.push_back(rg);
} }
return groups;
} }

View File

@ -49,6 +49,7 @@
#include "LogFactory.h" #include "LogFactory.h"
#include "DiskAdaptor.h" #include "DiskAdaptor.h"
#include "DiskWriterFactory.h" #include "DiskWriterFactory.h"
#include "RecoverableException.h"
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
# include "CheckIntegrityCommand.h" # include "CheckIntegrityCommand.h"
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
@ -410,11 +411,17 @@ void RequestGroup::releaseRuntimeResource()
RequestGroups RequestGroup::postDownloadProcessing() RequestGroups RequestGroup::postDownloadProcessing()
{ {
_logger->debug("Finding PostDownloadHandler for path %s.", getFilePath().c_str()); _logger->debug("Finding PostDownloadHandler for path %s.", getFilePath().c_str());
for(PostDownloadHandlers::const_iterator itr = _postDownloadHandlers.begin(); try {
itr != _postDownloadHandlers.end(); ++itr) { for(PostDownloadHandlers::const_iterator itr = _postDownloadHandlers.begin();
if((*itr)->canHandle(getFilePath())) { itr != _postDownloadHandlers.end(); ++itr) {
return (*itr)->getNextRequestGroups(getFilePath()); if((*itr)->canHandle(getFilePath())) {
return (*itr)->getNextRequestGroups(getFilePath());
}
} }
} catch(RecoverableException* ex) {
_logger->error(EX_EXCEPTION_CAUGHT, ex);
delete ex;
return RequestGroups();
} }
_logger->debug("No PostDownloadHandler found."); _logger->debug("No PostDownloadHandler found.");
return RequestGroups(); return RequestGroups();