diff --git a/ChangeLog b/ChangeLog index cd5c7af2..3f07a357 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-08-30 Tatsuhiro Tsujikawa + + Added the ability to disable segmented download in .metalink. + aria2 can now recognize 'maxconnections' attribute in 'resources' and + 'url' tag. + * src/MetalinkEntry.{h, cc} + * src/RequestResource.{h, cc} + * src/MetalinkRequestInfo.cc + * src/Xml2MetalinkProcessor.cc + * test/Xml2MetalinkProcessorTest.cc + 2007-08-28 Tatsuhiro Tsujikawa Added parameterized URI support. diff --git a/TODO b/TODO index 6166eb5a..f2a7cbf0 100644 --- a/TODO +++ b/TODO @@ -39,7 +39,4 @@ * used globally -> common.h * Add pgp verification support. I have to use libgpgme?? -* Disable segmented download in .metalink - -* Add outfile auto renaming * Rewrite MetaFileUtil diff --git a/src/MetalinkEntry.cc b/src/MetalinkEntry.cc index 80e2def8..bfdbb5b2 100644 --- a/src/MetalinkEntry.cc +++ b/src/MetalinkEntry.cc @@ -36,10 +36,12 @@ #include "Util.h" #include -MetalinkEntry::MetalinkEntry() +MetalinkEntry::MetalinkEntry(): + maxConnections(-1) #ifdef ENABLE_MESSAGE_DIGEST - :checksum(0), - chunkChecksum(0) + , + checksum(0), + chunkChecksum(0) #endif // ENABLE_MESSAGE_DIGEST {} diff --git a/src/MetalinkEntry.h b/src/MetalinkEntry.h index 9774e6e0..a115194a 100644 --- a/src/MetalinkEntry.h +++ b/src/MetalinkEntry.h @@ -56,6 +56,7 @@ public: string language; string os; MetalinkResources resources; + int32_t maxConnections; #ifdef ENABLE_MESSAGE_DIGEST ChecksumHandle checksum; ChunkChecksumHandle chunkChecksum; @@ -71,6 +72,7 @@ public: this->version = metalinkEntry.version; this->language = metalinkEntry.language; this->os = metalinkEntry.os; + this->maxConnections = metalinkEntry.maxConnections; #ifdef ENABLE_MESSAGE_DIGEST this->checksum = metalinkEntry.checksum; this->chunkChecksum = metalinkEntry.chunkChecksum; diff --git a/src/MetalinkRequestInfo.cc b/src/MetalinkRequestInfo.cc index e1e8805c..6553477f 100644 --- a/src/MetalinkRequestInfo.cc +++ b/src/MetalinkRequestInfo.cc @@ -50,11 +50,17 @@ public: split(split) {} void operator()(const MetalinkResourceHandle& resource) { + int32_t maxConnections; + if(resource->maxConnections < 0) { + maxConnections = split; + } else { + maxConnections = min(resource->maxConnections, split); + } switch(resource->type) { case MetalinkResource::TYPE_HTTP: case MetalinkResource::TYPE_HTTPS: case MetalinkResource::TYPE_FTP: - for(int32_t s = 1; s <= split; s++) { + for(int32_t s = 1; s <= maxConnections; s++) { urlsPtr->push_back(resource->url); } break; @@ -152,7 +158,9 @@ RequestInfos MetalinkRequestInfo::execute() { rg->setHintFilename(entry->file->getBasename()); rg->setTopDir(entry->file->getDirname()); rg->setHintTotalLength(entry->getLength()); - rg->setNumConcurrentCommand(op->getAsInt(PREF_METALINK_SERVERS)); + rg->setNumConcurrentCommand(entry->maxConnections < 0 ? + op->getAsInt(PREF_METALINK_SERVERS) : + min(op->getAsInt(PREF_METALINK_SERVERS), entry->maxConnections)); #ifdef ENABLE_MESSAGE_DIGEST if(entry->chunkChecksum.isNull()) { diff --git a/src/MetalinkResource.cc b/src/MetalinkResource.cc index 51b2c898..6a6a039e 100644 --- a/src/MetalinkResource.cc +++ b/src/MetalinkResource.cc @@ -34,6 +34,8 @@ /* copyright --> */ #include "MetalinkResource.h" -MetalinkResource::MetalinkResource() {} +MetalinkResource::MetalinkResource(): + maxConnections(-1) +{} MetalinkResource::~MetalinkResource() {} diff --git a/src/MetalinkResource.h b/src/MetalinkResource.h index 6ea68a48..cd4eedeb 100644 --- a/src/MetalinkResource.h +++ b/src/MetalinkResource.h @@ -51,6 +51,7 @@ public: TYPE type; string location; int32_t preference; + int32_t maxConnections; public: MetalinkResource(); ~MetalinkResource(); @@ -61,6 +62,7 @@ public: this->type = metalinkResource.type; this->location = metalinkResource.location; this->preference = metalinkResource.preference; + this->maxConnections = metalinkResource.maxConnections; } return *this; } diff --git a/src/Xml2MetalinkProcessor.cc b/src/Xml2MetalinkProcessor.cc index 76770016..19cec2c8 100644 --- a/src/Xml2MetalinkProcessor.cc +++ b/src/Xml2MetalinkProcessor.cc @@ -140,17 +140,18 @@ MetalinkEntryHandle Xml2MetalinkProcessor::getEntry(const string& xpath) { } } xmlXPathFreeObject(pieceHashPathObj); - /* - string piecesPath = xpath+"/m:verification/m:pieces"; - string sha1PiecesPath = piecesPath+"[@type=\"sha1\"]"; - string md5PiecesPath = piecesPath+"[@type=\"md5\"]"; - if(xpathExists(sha1PiecesPath)) { - entry->chunkChecksum = getPieceHash(sha1PiecesPath, entry->getLength()); - } else if(xpathExists(md5PiecesPath)) { - entry->chunkChecksum = getPieceHash(md5PiecesPath, entry->getLength()); - } - */ #endif // ENABLE_MESSAGE_DIGEST + + string resourcesPath = xpath+"/m:resources[@maxconnections]"; + xmlXPathObjectPtr resourcesPathObj = xpathEvaluation(resourcesPath); + if(resourcesPathObj) { + xmlNodeSetPtr nodeSet = resourcesPathObj->nodesetval; + xmlNodePtr node = nodeSet->nodeTab[0]; + int32_t maxConnections = strtol(Util::trim(xmlAttribute(node, "maxconnections")).c_str(), 0, 10); + entry->maxConnections = maxConnections; + } + xmlXPathFreeObject(resourcesPathObj); + for(uint32_t index = 1; 1; index++) { MetalinkResourceHandle resource(getResource(xpath+"/m:resources/m:url["+Util::uitos(index)+"]")); if(!resource.get()) { @@ -227,6 +228,13 @@ MetalinkResourceHandle Xml2MetalinkProcessor::getResource(const string& xpath) { resource->url = Util::trim(xmlContent(node)); + { + string cnn = Util::trim(xmlAttribute(node, "maxconnections")); + if(!cnn.empty()) { + resource->maxConnections = strtol(cnn.c_str(), 0, 10); + } + } + xmlXPathFreeObject(result); return resource; diff --git a/test/Xml2MetalinkProcessorTest.cc b/test/Xml2MetalinkProcessorTest.cc index 53b5058d..27437668 100644 --- a/test/Xml2MetalinkProcessorTest.cc +++ b/test/Xml2MetalinkProcessorTest.cc @@ -37,6 +37,7 @@ void Xml2MetalinkProcessorTest::testParseFile() { CPPUNIT_ASSERT_EQUAL(string("0.5.2"), entry1->version); CPPUNIT_ASSERT_EQUAL(string("en-US"), entry1->language); CPPUNIT_ASSERT_EQUAL(string("Linux-x86"), entry1->os); + CPPUNIT_ASSERT_EQUAL((int32_t)1, entry1->maxConnections); #ifdef ENABLE_MESSAGE_DIGEST CPPUNIT_ASSERT_EQUAL(string("a96cf3f0266b91d87d5124cf94326422800b627d"), entry1->checksum->getMessageDigest()); @@ -49,6 +50,8 @@ void Xml2MetalinkProcessorTest::testParseFile() { CPPUNIT_ASSERT_EQUAL((int32_t)100, resource1->preference); CPPUNIT_ASSERT_EQUAL(string("ftp://ftphost/aria2-0.5.2.tar.bz2"), resource1->url); + CPPUNIT_ASSERT_EQUAL((int32_t)1, resource1->maxConnections); + resourceItr1++; MetalinkResourceHandle resource2 = *resourceItr1; CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, resource2->type); @@ -56,6 +59,7 @@ void Xml2MetalinkProcessorTest::testParseFile() { CPPUNIT_ASSERT_EQUAL((int32_t)100, resource2->preference); CPPUNIT_ASSERT_EQUAL(string("http://httphost/aria2-0.5.2.tar.bz2"), resource2->url); + CPPUNIT_ASSERT_EQUAL((int32_t)-1, resource2->maxConnections); entryItr++; @@ -65,6 +69,7 @@ void Xml2MetalinkProcessorTest::testParseFile() { CPPUNIT_ASSERT_EQUAL(string("0.5.1"), entry2->version); CPPUNIT_ASSERT_EQUAL(string("ja-JP"), entry2->language); CPPUNIT_ASSERT_EQUAL(string("Linux-m68k"), entry2->os); + CPPUNIT_ASSERT_EQUAL((int32_t)-1, entry2->maxConnections); #ifdef ENABLE_MESSAGE_DIGEST CPPUNIT_ASSERT_EQUAL(string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"), entry2->checksum->getMessageDigest()); diff --git a/test/test.xml b/test/test.xml index f071c064..9a99c339 100644 --- a/test/test.xml +++ b/test/test.xml @@ -14,8 +14,8 @@ a96cf3f0266b91d87d5124cf94326422800b627d fc4d834e89c18c99b2615d902750948c - - ftp://ftphost/aria2-0.5.2.tar.bz2 + + ftp://ftphost/aria2-0.5.2.tar.bz2 http://httphost/aria2-0.5.2.tar.bz2