MetalinkProcessorTest.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. #include "MetalinkProcessor.h"
  2. #include <iostream>
  3. #include <cppunit/extensions/HelperMacros.h>
  4. #include "MetalinkParserStateMachine.h"
  5. #include "Exception.h"
  6. #include "DefaultDiskWriter.h"
  7. #include "ByteArrayDiskWriter.h"
  8. #include "Metalinker.h"
  9. #include "MetalinkEntry.h"
  10. #include "MetalinkResource.h"
  11. #include "MetalinkMetaurl.h"
  12. #ifdef ENABLE_MESSAGE_DIGEST
  13. # include "ChunkChecksum.h"
  14. # include "Checksum.h"
  15. #endif // ENABLE_MESSAGE_DIGEST
  16. #include "Signature.h"
  17. namespace aria2 {
  18. class MetalinkProcessorTest:public CppUnit::TestFixture {
  19. CPPUNIT_TEST_SUITE(MetalinkProcessorTest);
  20. CPPUNIT_TEST(testParseFileV4);
  21. CPPUNIT_TEST(testParseFileV4_dirtraversal);
  22. CPPUNIT_TEST(testParseFileV4_attrs);
  23. CPPUNIT_TEST(testParseFile);
  24. CPPUNIT_TEST(testParseFile_dirtraversal);
  25. CPPUNIT_TEST(testParseFromBinaryStream);
  26. CPPUNIT_TEST(testMalformedXML);
  27. CPPUNIT_TEST(testMalformedXML2);
  28. CPPUNIT_TEST(testBadSize);
  29. CPPUNIT_TEST(testBadMaxConn);
  30. CPPUNIT_TEST(testNoName);
  31. CPPUNIT_TEST(testBadURLPrefs);
  32. CPPUNIT_TEST(testBadURLMaxConn);
  33. #ifdef ENABLE_MESSAGE_DIGEST
  34. CPPUNIT_TEST(testUnsupportedType);
  35. CPPUNIT_TEST(testMultiplePieces);
  36. CPPUNIT_TEST(testBadPieceNo);
  37. CPPUNIT_TEST(testBadPieceLength);
  38. CPPUNIT_TEST(testUnsupportedType_piece);
  39. #endif // ENABLE_MESSAGE_DIGEST
  40. CPPUNIT_TEST(testLargeFileSize);
  41. CPPUNIT_TEST(testXmlPrefixV3);
  42. CPPUNIT_TEST_SUITE_END();
  43. private:
  44. public:
  45. void testParseFileV4();
  46. void testParseFileV4_dirtraversal();
  47. void testParseFileV4_attrs();
  48. void testParseFile();
  49. void testParseFile_dirtraversal();
  50. void testParseFromBinaryStream();
  51. void testMalformedXML();
  52. void testMalformedXML2();
  53. void testBadSize();
  54. void testBadMaxConn();
  55. void testNoName();
  56. void testBadURLPrefs();
  57. void testBadURLMaxConn();
  58. #ifdef ENABLE_MESSAGE_DIGEST
  59. void testUnsupportedType();
  60. void testMultiplePieces();
  61. void testBadPieceNo();
  62. void testBadPieceLength();
  63. void testUnsupportedType_piece();
  64. #endif // ENABLE_MESSAGE_DIGEST
  65. void testLargeFileSize();
  66. void testXmlPrefixV3();
  67. };
  68. CPPUNIT_TEST_SUITE_REGISTRATION( MetalinkProcessorTest );
  69. void MetalinkProcessorTest::testParseFileV4()
  70. {
  71. MetalinkProcessor proc;
  72. SharedHandle<Metalinker> m = proc.parseFile("metalink4.xml");
  73. SharedHandle<MetalinkEntry> e;
  74. SharedHandle<MetalinkResource> r;
  75. SharedHandle<MetalinkMetaurl> mu;
  76. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  77. e = m->entries[0];
  78. CPPUNIT_ASSERT_EQUAL(std::string("example.ext"), e->getPath());
  79. CPPUNIT_ASSERT_EQUAL((uint64_t)786430LL, e->getLength());
  80. CPPUNIT_ASSERT_EQUAL(-1, e->maxConnections);
  81. #ifdef ENABLE_MESSAGE_DIGEST
  82. CPPUNIT_ASSERT_EQUAL(std::string("80bc95fd391772fa61c91ed68567f0980bb45fd9"),
  83. e->checksum->getMessageDigest());
  84. CPPUNIT_ASSERT(!e->checksum.isNull());
  85. CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), e->checksum->getAlgo());
  86. CPPUNIT_ASSERT(!e->chunkChecksum.isNull());
  87. CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), e->chunkChecksum->getAlgo());
  88. CPPUNIT_ASSERT_EQUAL((size_t)262144, e->chunkChecksum->getChecksumLength());
  89. CPPUNIT_ASSERT_EQUAL((size_t)3, e->chunkChecksum->countChecksum());
  90. CPPUNIT_ASSERT_EQUAL(std::string("metalinkhash1"),
  91. e->chunkChecksum->getChecksum(0));
  92. CPPUNIT_ASSERT_EQUAL(std::string("metalinkhash2"),
  93. e->chunkChecksum->getChecksum(1));
  94. CPPUNIT_ASSERT_EQUAL(std::string("metalinkhash3"),
  95. e->chunkChecksum->getChecksum(2));
  96. #endif // ENABLE_MESSAGE_DIGEST
  97. CPPUNIT_ASSERT(!e->getSignature().isNull());
  98. CPPUNIT_ASSERT_EQUAL(std::string("application/pgp-signature"),
  99. e->getSignature()->getType());
  100. CPPUNIT_ASSERT_EQUAL(std::string("a signature"),
  101. e->getSignature()->getBody());
  102. CPPUNIT_ASSERT_EQUAL((size_t)2, e->resources.size());
  103. r = e->resources[0];
  104. CPPUNIT_ASSERT_EQUAL(std::string("ftp://ftp.example.com/example.ext"),
  105. r->url);
  106. CPPUNIT_ASSERT_EQUAL(std::string("de"), r->location);
  107. CPPUNIT_ASSERT_EQUAL(1, r->priority);
  108. CPPUNIT_ASSERT_EQUAL(std::string("ftp"),
  109. MetalinkResource::getTypeString(r->type));
  110. CPPUNIT_ASSERT_EQUAL(-1, r->maxConnections);
  111. #ifdef ENABLE_BITTORRENT
  112. CPPUNIT_ASSERT_EQUAL((size_t)1, e->metaurls.size());
  113. mu = e->metaurls[0];
  114. CPPUNIT_ASSERT_EQUAL(std::string("http://example.com/example.ext.torrent"),
  115. mu->url);
  116. CPPUNIT_ASSERT_EQUAL(2, mu->priority);
  117. CPPUNIT_ASSERT_EQUAL(std::string("torrent"), mu->mediatype);
  118. #else // !ENABLE_BITTORRENT
  119. CPPUNIT_ASSERT_EQUAL((size_t)0, e->metaurls.size());
  120. #endif // !ENABLE_BITTORRENT
  121. }
  122. void MetalinkProcessorTest::testParseFileV4_dirtraversal()
  123. {
  124. MetalinkProcessor proc;
  125. SharedHandle<Metalinker> m = proc.parseFile("metalink4-dirtraversal.xml");
  126. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  127. CPPUNIT_ASSERT_EQUAL((size_t)0, m->entries[0]->resources.size());
  128. CPPUNIT_ASSERT_EQUAL((size_t)0, m->entries[0]->metaurls.size());
  129. }
  130. void MetalinkProcessorTest::testParseFileV4_attrs()
  131. {
  132. MetalinkProcessor proc;
  133. SharedHandle<Metalinker> m = proc.parseFile("metalink4-attrs.xml");
  134. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  135. std::deque<SharedHandle<MetalinkResource> > resources =
  136. m->entries[0]->resources;
  137. CPPUNIT_ASSERT_EQUAL((size_t)3, resources.size());
  138. CPPUNIT_ASSERT_EQUAL(999999, resources[0]->priority);
  139. CPPUNIT_ASSERT_EQUAL(999999, resources[1]->priority);
  140. CPPUNIT_ASSERT_EQUAL(999999, resources[2]->priority);
  141. std::vector<SharedHandle<MetalinkMetaurl> > metaurls =
  142. m->entries[0]->metaurls;
  143. #ifdef ENABLE_BITTORRENT
  144. CPPUNIT_ASSERT_EQUAL((size_t)3, metaurls.size());
  145. CPPUNIT_ASSERT_EQUAL(999999, metaurls[0]->priority);
  146. CPPUNIT_ASSERT_EQUAL(999999, metaurls[1]->priority);
  147. CPPUNIT_ASSERT_EQUAL(999999, metaurls[2]->priority);
  148. #else // !ENABLE_BITTORRENT
  149. CPPUNIT_ASSERT_EQUAL((size_t)0, metaurls.size());
  150. #endif // !ENABLE_BITTORRENT
  151. }
  152. void MetalinkProcessorTest::testParseFile()
  153. {
  154. MetalinkProcessor proc;
  155. try {
  156. SharedHandle<Metalinker> metalinker = proc.parseFile("test.xml");
  157. std::deque<SharedHandle<MetalinkEntry> >::iterator entryItr = metalinker->entries.begin();
  158. SharedHandle<MetalinkEntry> entry1 = *entryItr;
  159. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), entry1->getPath());
  160. CPPUNIT_ASSERT_EQUAL((uint64_t)0ULL, entry1->getLength());
  161. CPPUNIT_ASSERT_EQUAL(std::string("0.5.2"), entry1->version);
  162. CPPUNIT_ASSERT_EQUAL(std::string("en-US"), entry1->languages[0]);
  163. CPPUNIT_ASSERT_EQUAL(std::string("Linux-x86"), entry1->oses[0]);
  164. CPPUNIT_ASSERT_EQUAL(1, entry1->maxConnections);
  165. #ifdef ENABLE_MESSAGE_DIGEST
  166. CPPUNIT_ASSERT_EQUAL(std::string("a96cf3f0266b91d87d5124cf94326422800b627d"),
  167. entry1->checksum->getMessageDigest());
  168. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), entry1->checksum->getAlgo());
  169. #endif // ENABLE_MESSAGE_DIGEST
  170. CPPUNIT_ASSERT(!entry1->getSignature().isNull());
  171. CPPUNIT_ASSERT_EQUAL(std::string("pgp"), entry1->getSignature()->getType());
  172. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2.sig"),
  173. entry1->getSignature()->getFile());
  174. // Note that last '\n' character is trimmed.
  175. CPPUNIT_ASSERT_EQUAL
  176. (std::string
  177. ("-----BEGIN PGP SIGNATURE-----\n"
  178. "Version: GnuPG v1.4.9 (GNU/Linux)\n"
  179. "\n"
  180. "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  181. "ffffffffffffffffffffffff\n"
  182. "fffff\n"
  183. "-----END PGP SIGNATURE-----"),
  184. entry1->getSignature()->getBody());
  185. std::deque<SharedHandle<MetalinkResource> >::iterator resourceItr1 = entry1->resources.begin();
  186. SharedHandle<MetalinkResource> resource1 = *resourceItr1;
  187. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, resource1->type);
  188. CPPUNIT_ASSERT_EQUAL(std::string("jp"), resource1->location);
  189. CPPUNIT_ASSERT_EQUAL(1, resource1->priority);
  190. CPPUNIT_ASSERT_EQUAL(std::string("ftp://ftphost/aria2-0.5.2.tar.bz2"),
  191. resource1->url);
  192. CPPUNIT_ASSERT_EQUAL(1, resource1->maxConnections);
  193. resourceItr1++;
  194. SharedHandle<MetalinkResource> resource2 = *resourceItr1;
  195. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, resource2->type);
  196. CPPUNIT_ASSERT_EQUAL(std::string("us"), resource2->location);
  197. CPPUNIT_ASSERT_EQUAL(1, resource2->priority);
  198. CPPUNIT_ASSERT_EQUAL(std::string("http://httphost/aria2-0.5.2.tar.bz2"),
  199. resource2->url);
  200. CPPUNIT_ASSERT_EQUAL(-1, resource2->maxConnections);
  201. entryItr++;
  202. SharedHandle<MetalinkEntry> entry2 = *entryItr;
  203. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.1.tar.bz2"), entry2->getPath());
  204. CPPUNIT_ASSERT_EQUAL((uint64_t)345689ULL, entry2->getLength());
  205. CPPUNIT_ASSERT_EQUAL(std::string("0.5.1"), entry2->version);
  206. CPPUNIT_ASSERT_EQUAL(std::string("ja-JP"), entry2->languages[0]);
  207. CPPUNIT_ASSERT_EQUAL(std::string("Linux-m68k"), entry2->oses[0]);
  208. CPPUNIT_ASSERT_EQUAL(-1, entry2->maxConnections);
  209. #ifdef ENABLE_MESSAGE_DIGEST
  210. CPPUNIT_ASSERT_EQUAL(std::string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
  211. entry2->checksum->getMessageDigest());
  212. CPPUNIT_ASSERT_EQUAL((size_t)2, entry2->chunkChecksum->countChecksum());
  213. CPPUNIT_ASSERT_EQUAL((size_t)262144, entry2->chunkChecksum->getChecksumLength());
  214. CPPUNIT_ASSERT_EQUAL(std::string("179463a88d79cbf0b1923991708aead914f26142"),
  215. entry2->chunkChecksum->getChecksum(0));
  216. CPPUNIT_ASSERT_EQUAL(std::string("fecf8bc9a1647505fe16746f94e97a477597dbf3"),
  217. entry2->chunkChecksum->getChecksum(1));
  218. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), entry2->checksum->getAlgo());
  219. #endif // ENABLE_MESSAGE_DIGEST
  220. // See that signature is null
  221. CPPUNIT_ASSERT(entry2->getSignature().isNull());
  222. entryItr++;
  223. // test case: verification hash is not provided
  224. SharedHandle<MetalinkEntry> entry3 = *entryItr;
  225. CPPUNIT_ASSERT_EQUAL(std::string("NoVerificationHash"), entry3->getPath());
  226. #ifdef ENABLE_MESSAGE_DIGEST
  227. CPPUNIT_ASSERT(entry3->checksum.isNull());
  228. CPPUNIT_ASSERT(entry3->chunkChecksum.isNull());
  229. #endif // ENABLE_MESSAGE_DIGEST
  230. entryItr++;
  231. // test case: unsupported verification hash is included
  232. SharedHandle<MetalinkEntry> entry4 = *entryItr;
  233. CPPUNIT_ASSERT_EQUAL(std::string("UnsupportedVerificationHashTypeIncluded"), entry4->getPath());
  234. #ifdef ENABLE_MESSAGE_DIGEST
  235. CPPUNIT_ASSERT_EQUAL(std::string("sha1"),
  236. entry4->checksum->getAlgo());
  237. CPPUNIT_ASSERT_EQUAL(std::string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
  238. entry4->checksum->getMessageDigest());
  239. CPPUNIT_ASSERT_EQUAL(std::string("sha1"),
  240. entry4->chunkChecksum->getAlgo());
  241. #endif // ENABLE_MESSAGE_DIGEST
  242. } catch(Exception& e) {
  243. CPPUNIT_FAIL(e.stackTrace());
  244. }
  245. }
  246. void MetalinkProcessorTest::testParseFile_dirtraversal()
  247. {
  248. MetalinkProcessor proc;
  249. SharedHandle<Metalinker> metalinker =
  250. proc.parseFile("metalink3-dirtraversal.xml");
  251. CPPUNIT_ASSERT_EQUAL((size_t)1, metalinker->entries.size());
  252. SharedHandle<MetalinkEntry> e = metalinker->entries[0];
  253. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.3.tar.bz2"), e->getPath());
  254. CPPUNIT_ASSERT(!e->getSignature().isNull());
  255. CPPUNIT_ASSERT_EQUAL(std::string(""), e->getSignature()->getFile());
  256. }
  257. void MetalinkProcessorTest::testParseFromBinaryStream()
  258. {
  259. MetalinkProcessor proc;
  260. DefaultDiskWriterHandle dw(new DefaultDiskWriter("test.xml"));
  261. dw->openExistingFile();
  262. try {
  263. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  264. std::deque<SharedHandle<MetalinkEntry> >::iterator entryItr = m->entries.begin();
  265. SharedHandle<MetalinkEntry> entry1 = *entryItr;
  266. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), entry1->getPath());
  267. } catch(Exception& e) {
  268. CPPUNIT_FAIL(e.stackTrace());
  269. }
  270. }
  271. void MetalinkProcessorTest::testMalformedXML()
  272. {
  273. MetalinkProcessor proc;
  274. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  275. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\"><files></file></metalink>");
  276. try {
  277. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  278. CPPUNIT_FAIL("exception must be thrown.");
  279. } catch(Exception& e) {
  280. std::cerr << e.stackTrace() << std::endl;
  281. }
  282. }
  283. void MetalinkProcessorTest::testMalformedXML2()
  284. {
  285. MetalinkProcessor proc;
  286. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  287. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\"><files></files>");
  288. try {
  289. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  290. CPPUNIT_FAIL("exception must be thrown.");
  291. } catch(Exception& e) {
  292. std::cerr << e.stackTrace() << std::endl;
  293. }
  294. }
  295. void MetalinkProcessorTest::testBadSize()
  296. {
  297. MetalinkProcessor proc;
  298. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  299. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  300. "<files>"
  301. "<file name=\"aria2-0.5.2.tar.bz2\">"
  302. " <size>abc</size>"
  303. " <version>0.5.2</version>"
  304. " <language>en-US</language>"
  305. " <os>Linux-x86</os>"
  306. "</file>"
  307. "</files>"
  308. "</metalink>");
  309. try {
  310. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  311. std::deque<SharedHandle<MetalinkEntry> >::iterator entryItr = m->entries.begin();
  312. SharedHandle<MetalinkEntry> e = *entryItr;
  313. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), e->getPath());
  314. CPPUNIT_ASSERT_EQUAL((uint64_t)0ULL, e->getLength());
  315. CPPUNIT_ASSERT_EQUAL(std::string("0.5.2"), e->version);
  316. CPPUNIT_ASSERT_EQUAL(std::string("en-US"), e->languages[0]);
  317. CPPUNIT_ASSERT_EQUAL(std::string("Linux-x86"), e->oses[0]);
  318. } catch(Exception& e) {
  319. CPPUNIT_FAIL(e.stackTrace());
  320. }
  321. }
  322. void MetalinkProcessorTest::testBadMaxConn()
  323. {
  324. MetalinkProcessor proc;
  325. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  326. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  327. "<files>"
  328. "<file name=\"aria2-0.5.2.tar.bz2\">"
  329. " <size>43743838</size>"
  330. " <version>0.5.2</version>"
  331. " <language>en-US</language>"
  332. " <os>Linux-x86</os>"
  333. " <resources maxconnections=\"abc\"/>"
  334. "</file>"
  335. "</files>"
  336. "</metalink>");
  337. try {
  338. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  339. std::deque<SharedHandle<MetalinkEntry> >::iterator entryItr = m->entries.begin();
  340. SharedHandle<MetalinkEntry> e = *entryItr;
  341. CPPUNIT_ASSERT_EQUAL((uint64_t)43743838ULL, e->getLength());
  342. } catch(Exception& e) {
  343. CPPUNIT_FAIL(e.stackTrace());
  344. }
  345. }
  346. void MetalinkProcessorTest::testNoName()
  347. {
  348. MetalinkProcessor proc;
  349. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  350. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  351. "<files>"
  352. "<file>"
  353. " <size>1024</size>"
  354. " <version>0.0.1</version>"
  355. " <language>GB</language>"
  356. " <os>Linux-x64</os>"
  357. "</file>"
  358. "<file name=\"aria2-0.5.2.tar.bz2\">"
  359. " <size>43743838</size>"
  360. " <version>0.5.2</version>"
  361. " <language>en-US</language>"
  362. " <os>Linux-x86</os>"
  363. "</file>"
  364. "</files>"
  365. "</metalink>");
  366. try {
  367. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  368. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  369. std::deque<SharedHandle<MetalinkEntry> >::iterator entryItr = m->entries.begin();
  370. SharedHandle<MetalinkEntry> e = *entryItr;
  371. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), e->getPath());
  372. } catch(Exception& e) {
  373. CPPUNIT_FAIL(e.stackTrace());
  374. }
  375. }
  376. void MetalinkProcessorTest::testBadURLPrefs()
  377. {
  378. MetalinkProcessor proc;
  379. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  380. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  381. "<files>"
  382. "<file name=\"aria2-0.5.2.tar.bz2\">"
  383. " <size>43743838</size>"
  384. " <version>0.5.2</version>"
  385. " <language>en-US</language>"
  386. " <os>Linux-x86</os>"
  387. " <resources>"
  388. " <url type=\"ftp\" maxconnections=\"1\" preference=\"xyz\""
  389. " location=\"jp\">ftp://mirror/</url>"
  390. " </resources>"
  391. "</file>"
  392. "</files>"
  393. "</metalink>");
  394. try {
  395. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  396. SharedHandle<MetalinkEntry> e = m->entries[0];
  397. SharedHandle<MetalinkResource> r = e->resources[0];
  398. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, r->type);
  399. CPPUNIT_ASSERT_EQUAL(MetalinkResource::getLowestPriority(), r->priority);
  400. CPPUNIT_ASSERT_EQUAL(1, r->maxConnections);
  401. CPPUNIT_ASSERT_EQUAL(std::string("jp"), r->location);
  402. } catch(Exception& e) {
  403. CPPUNIT_FAIL(e.stackTrace());
  404. }
  405. }
  406. void MetalinkProcessorTest::testBadURLMaxConn()
  407. {
  408. MetalinkProcessor proc;
  409. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  410. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  411. "<files>"
  412. "<file name=\"aria2-0.5.2.tar.bz2\">"
  413. " <size>43743838</size>"
  414. " <version>0.5.2</version>"
  415. " <language>en-US</language>"
  416. " <os>Linux-x86</os>"
  417. " <resources>"
  418. " <url maxconnections=\"xyz\" type=\"ftp\""
  419. " preference=\"100\""
  420. " location=\"jp\">ftp://mirror/</url>"
  421. " </resources>"
  422. "</file>"
  423. "</files>"
  424. "</metalink>");
  425. try {
  426. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  427. SharedHandle<MetalinkEntry> e = m->entries[0];
  428. SharedHandle<MetalinkResource> r = e->resources[0];
  429. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, r->type);
  430. CPPUNIT_ASSERT_EQUAL(1, r->priority);
  431. CPPUNIT_ASSERT_EQUAL(-1, r->maxConnections);
  432. CPPUNIT_ASSERT_EQUAL(std::string("jp"), r->location);
  433. } catch(Exception& e) {
  434. CPPUNIT_FAIL(e.stackTrace());
  435. }
  436. }
  437. #ifdef ENABLE_MESSAGE_DIGEST
  438. void MetalinkProcessorTest::testUnsupportedType()
  439. {
  440. MetalinkProcessor proc;
  441. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  442. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  443. "<files>"
  444. "<file name=\"aria2-0.5.2.tar.bz2\">"
  445. " <size>43743838</size>"
  446. " <version>0.5.2</version>"
  447. " <language>en-US</language>"
  448. " <os>Linux-x86</os>"
  449. " <resources>"
  450. " <url type=\"ftp\">ftp://mirror/</url>"
  451. " <url type=\"magnet\">magnet:xt=XYZ</url>"
  452. " <url type=\"http\">http://mirror/</url>"
  453. " </resources>"
  454. "</file>"
  455. "</files>"
  456. "</metalink>");
  457. try {
  458. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  459. SharedHandle<MetalinkEntry> e = m->entries[0];
  460. CPPUNIT_ASSERT_EQUAL((size_t)3, e->resources.size());
  461. SharedHandle<MetalinkResource> r1 = e->resources[0];
  462. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, r1->type);
  463. SharedHandle<MetalinkResource> r2 = e->resources[1];
  464. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_NOT_SUPPORTED, r2->type);
  465. SharedHandle<MetalinkResource> r3 = e->resources[2];
  466. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, r3->type);
  467. } catch(Exception& e) {
  468. CPPUNIT_FAIL(e.stackTrace());
  469. }
  470. }
  471. void MetalinkProcessorTest::testMultiplePieces()
  472. {
  473. MetalinkProcessor proc;
  474. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  475. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  476. "<files>"
  477. "<file name=\"aria2.tar.bz2\">"
  478. " <verification>"
  479. " <pieces length=\"1024\" type=\"sha1\">"
  480. " </pieces>"
  481. " <pieces length=\"512\" type=\"md5\">"
  482. " </pieces>"
  483. " </verification>"
  484. "</file>"
  485. "</files>"
  486. "</metalink>");
  487. try {
  488. // aria2 prefers sha1
  489. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  490. SharedHandle<MetalinkEntry> e = m->entries[0];
  491. SharedHandle<ChunkChecksum> c = e->chunkChecksum;
  492. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), c->getAlgo());
  493. CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
  494. } catch(Exception& e) {
  495. CPPUNIT_FAIL(e.stackTrace());
  496. }
  497. }
  498. void MetalinkProcessorTest::testBadPieceNo()
  499. {
  500. MetalinkProcessor proc;
  501. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  502. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  503. "<files>"
  504. "<file name=\"aria2.tar.bz2\">"
  505. " <verification>"
  506. " <pieces length=\"512\" type=\"sha1\">"
  507. " <hash piece=\"0\">abc</hash>"
  508. " <hash piece=\"xyz\">xyz</hash>"
  509. " </pieces>"
  510. " <pieces length=\"1024\" type=\"sha1\">"
  511. " <hash piece=\"0\">abc</hash>"
  512. " </pieces>"
  513. " </verification>"
  514. "</file>"
  515. "</files>"
  516. "</metalink>");
  517. try {
  518. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  519. SharedHandle<MetalinkEntry> e = m->entries[0];
  520. SharedHandle<ChunkChecksum> c = e->chunkChecksum;
  521. CPPUNIT_ASSERT(!c.isNull());
  522. CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
  523. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), c->getAlgo());
  524. } catch(Exception& e) {
  525. CPPUNIT_FAIL(e.stackTrace());
  526. }
  527. }
  528. void MetalinkProcessorTest::testBadPieceLength()
  529. {
  530. MetalinkProcessor proc;
  531. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  532. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  533. "<files>"
  534. "<file name=\"aria2.tar.bz2\">"
  535. " <verification>"
  536. " <pieces length=\"xyz\" type=\"sha1\">"
  537. " <hash piece=\"0\">abc</hash>"
  538. " </pieces>"
  539. " <pieces length=\"1024\" type=\"sha1\">"
  540. " <hash piece=\"0\">abc</hash>"
  541. " </pieces>"
  542. " </verification>"
  543. "</file>"
  544. "</files>"
  545. "</metalink>");
  546. try {
  547. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  548. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  549. SharedHandle<MetalinkEntry> e = m->entries[0];
  550. SharedHandle<ChunkChecksum> c = e->chunkChecksum;
  551. CPPUNIT_ASSERT(!c.isNull());
  552. CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
  553. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), c->getAlgo());
  554. } catch(Exception& e) {
  555. CPPUNIT_FAIL(e.stackTrace());
  556. }
  557. }
  558. void MetalinkProcessorTest::testUnsupportedType_piece()
  559. {
  560. MetalinkProcessor proc;
  561. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  562. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  563. "<files>"
  564. "<file name=\"aria2.tar.bz2\">"
  565. " <verification>"
  566. " <pieces length=\"512\" type=\"ARIA2\">"
  567. " <hash piece=\"0\">abc</hash>"
  568. " </pieces>"
  569. " <pieces length=\"1024\" type=\"sha1\">"
  570. " <hash piece=\"0\">abc</hash>"
  571. " </pieces>"
  572. " </verification>"
  573. "</file>"
  574. "</files>"
  575. "</metalink>");
  576. try {
  577. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  578. SharedHandle<MetalinkEntry> e = m->entries[0];
  579. SharedHandle<ChunkChecksum> c = e->chunkChecksum;
  580. CPPUNIT_ASSERT(!c.isNull());
  581. CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
  582. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), c->getAlgo());
  583. } catch(Exception& e) {
  584. CPPUNIT_FAIL(e.stackTrace());
  585. }
  586. }
  587. #endif // ENABLE_MESSAGE_DIGEST
  588. void MetalinkProcessorTest::testLargeFileSize()
  589. {
  590. MetalinkProcessor proc;
  591. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  592. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  593. "<files>"
  594. "<file name=\"dvd.iso\">"
  595. " <size>9223372036854775807</size>"
  596. " <resources>"
  597. " <url type=\"http\">ftp://mirror/</url>"
  598. " </resources>"
  599. "</file>"
  600. "</files>"
  601. "</metalink>");
  602. try {
  603. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  604. SharedHandle<MetalinkEntry> e = m->entries[0];
  605. CPPUNIT_ASSERT_EQUAL((uint64_t)9223372036854775807ULL, e->getLength());
  606. } catch(Exception& e) {
  607. CPPUNIT_FAIL(e.stackTrace());
  608. }
  609. }
  610. void MetalinkProcessorTest::testXmlPrefixV3()
  611. {
  612. MetalinkProcessor proc;
  613. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  614. dw->setString("<m:metalink version=\"3.0\" xmlns:m=\"http://www.metalinker.org/\">"
  615. "<m:files>"
  616. "<m:file name=\"dvd.iso\">"
  617. " <m:size>9223372036854775807</m:size>"
  618. " <m:resources>"
  619. " <m:url type=\"http\">ftp://mirror/</m:url>"
  620. " </m:resources>"
  621. "</m:file>"
  622. "</m:files>"
  623. "</m:metalink>");
  624. try {
  625. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  626. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  627. SharedHandle<MetalinkEntry> e = m->entries[0];
  628. CPPUNIT_ASSERT_EQUAL((uint64_t)9223372036854775807ULL, e->getLength());
  629. } catch(Exception& e) {
  630. CPPUNIT_FAIL(e.stackTrace());
  631. }
  632. }
  633. } // namespace aria2