MetalinkProcessorTest.cc 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  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. #include "StringFormat.h"
  18. #include "RecoverableException.h"
  19. namespace aria2 {
  20. class MetalinkProcessorTest:public CppUnit::TestFixture {
  21. CPPUNIT_TEST_SUITE(MetalinkProcessorTest);
  22. CPPUNIT_TEST(testParseFileV4);
  23. CPPUNIT_TEST(testParseFileV4_attrs);
  24. CPPUNIT_TEST(testParseFile);
  25. CPPUNIT_TEST(testParseFile_dirtraversal);
  26. CPPUNIT_TEST(testParseFromBinaryStream);
  27. CPPUNIT_TEST(testMalformedXML);
  28. CPPUNIT_TEST(testMalformedXML2);
  29. CPPUNIT_TEST(testBadSize);
  30. CPPUNIT_TEST(testBadSizeV4);
  31. CPPUNIT_TEST(testBadMaxConn);
  32. CPPUNIT_TEST(testNoName);
  33. CPPUNIT_TEST(testBadURLPrefs);
  34. CPPUNIT_TEST(testBadURLMaxConn);
  35. #ifdef ENABLE_MESSAGE_DIGEST
  36. CPPUNIT_TEST(testUnsupportedType);
  37. CPPUNIT_TEST(testMultiplePieces);
  38. CPPUNIT_TEST(testBadPieceNo);
  39. CPPUNIT_TEST(testBadPieceLength);
  40. CPPUNIT_TEST(testUnsupportedType_piece);
  41. #endif // ENABLE_MESSAGE_DIGEST
  42. CPPUNIT_TEST(testLargeFileSize);
  43. CPPUNIT_TEST(testXmlPrefixV3);
  44. CPPUNIT_TEST_SUITE_END();
  45. private:
  46. public:
  47. void testParseFileV4();
  48. void testParseFileV4_attrs();
  49. void testParseFile();
  50. void testParseFile_dirtraversal();
  51. void testParseFromBinaryStream();
  52. void testMalformedXML();
  53. void testMalformedXML2();
  54. void testBadSize();
  55. void testBadSizeV4();
  56. void testBadMaxConn();
  57. void testNoName();
  58. void testBadURLPrefs();
  59. void testBadURLMaxConn();
  60. #ifdef ENABLE_MESSAGE_DIGEST
  61. void testUnsupportedType();
  62. void testMultiplePieces();
  63. void testBadPieceNo();
  64. void testBadPieceLength();
  65. void testUnsupportedType_piece();
  66. #endif // ENABLE_MESSAGE_DIGEST
  67. void testLargeFileSize();
  68. void testXmlPrefixV3();
  69. };
  70. CPPUNIT_TEST_SUITE_REGISTRATION( MetalinkProcessorTest );
  71. void MetalinkProcessorTest::testParseFileV4()
  72. {
  73. MetalinkProcessor proc;
  74. SharedHandle<Metalinker> m = proc.parseFile("metalink4.xml");
  75. SharedHandle<MetalinkEntry> e;
  76. SharedHandle<MetalinkResource> r;
  77. SharedHandle<MetalinkMetaurl> mu;
  78. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  79. e = m->entries[0];
  80. CPPUNIT_ASSERT_EQUAL(std::string("example.ext"), e->getPath());
  81. CPPUNIT_ASSERT_EQUAL((uint64_t)786430LL, e->getLength());
  82. CPPUNIT_ASSERT_EQUAL(-1, e->maxConnections);
  83. #ifdef ENABLE_MESSAGE_DIGEST
  84. CPPUNIT_ASSERT_EQUAL(std::string("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"),
  85. e->checksum->getMessageDigest());
  86. CPPUNIT_ASSERT(!e->checksum.isNull());
  87. CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), e->checksum->getAlgo());
  88. CPPUNIT_ASSERT(!e->chunkChecksum.isNull());
  89. CPPUNIT_ASSERT_EQUAL(std::string("sha-256"), e->chunkChecksum->getAlgo());
  90. CPPUNIT_ASSERT_EQUAL((size_t)262144, e->chunkChecksum->getChecksumLength());
  91. CPPUNIT_ASSERT_EQUAL((size_t)3, e->chunkChecksum->countChecksum());
  92. CPPUNIT_ASSERT_EQUAL(std::string("0245178074fd042e19b7c3885b360fc21064b30e73f5626c7e3b005d048069c5"),
  93. e->chunkChecksum->getChecksum(0));
  94. CPPUNIT_ASSERT_EQUAL(std::string("487ba2299be7f759d7c7bf6a4ac3a32cee81f1bb9332fc485947e32918864fb2"),
  95. e->chunkChecksum->getChecksum(1));
  96. CPPUNIT_ASSERT_EQUAL(std::string("37290d74ac4d186e3a8e5785d259d2ec04fac91ae28092e7620ec8bc99e830aa"),
  97. e->chunkChecksum->getChecksum(2));
  98. #endif // ENABLE_MESSAGE_DIGEST
  99. CPPUNIT_ASSERT(!e->getSignature().isNull());
  100. CPPUNIT_ASSERT_EQUAL(std::string("application/pgp-signature"),
  101. e->getSignature()->getType());
  102. CPPUNIT_ASSERT_EQUAL(std::string("a signature"),
  103. e->getSignature()->getBody());
  104. CPPUNIT_ASSERT_EQUAL((size_t)2, e->resources.size());
  105. r = e->resources[0];
  106. CPPUNIT_ASSERT_EQUAL(std::string("ftp://ftp.example.com/example.ext"),
  107. r->url);
  108. CPPUNIT_ASSERT_EQUAL(std::string("de"), r->location);
  109. CPPUNIT_ASSERT_EQUAL(1, r->priority);
  110. CPPUNIT_ASSERT_EQUAL(std::string("ftp"),
  111. MetalinkResource::getTypeString(r->type));
  112. CPPUNIT_ASSERT_EQUAL(-1, r->maxConnections);
  113. #ifdef ENABLE_BITTORRENT
  114. CPPUNIT_ASSERT_EQUAL((size_t)1, e->metaurls.size());
  115. mu = e->metaurls[0];
  116. CPPUNIT_ASSERT_EQUAL(std::string("http://example.com/example.ext.torrent"),
  117. mu->url);
  118. CPPUNIT_ASSERT_EQUAL(2, mu->priority);
  119. CPPUNIT_ASSERT_EQUAL(std::string("torrent"), mu->mediatype);
  120. #else // !ENABLE_BITTORRENT
  121. CPPUNIT_ASSERT_EQUAL((size_t)0, e->metaurls.size());
  122. #endif // !ENABLE_BITTORRENT
  123. }
  124. void MetalinkProcessorTest::testParseFileV4_attrs()
  125. {
  126. MetalinkProcessor proc;
  127. SharedHandle<Metalinker> m;
  128. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  129. {
  130. // Testing file@name
  131. const char* tmpl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  132. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  133. "<file name=\"%s\">"
  134. "<url>http://example.org</url>"
  135. "</file>"
  136. "</metalink>";
  137. dw->setString(StringFormat(tmpl, "foo").str());
  138. m = proc.parseFromBinaryStream(dw);
  139. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  140. // empty name
  141. dw->setString(StringFormat(tmpl, "").str());
  142. try {
  143. m = proc.parseFromBinaryStream(dw);
  144. CPPUNIT_FAIL("exception must be thrown.");
  145. } catch(RecoverableException& e) {
  146. // success
  147. }
  148. // dir traversing
  149. dw->setString(StringFormat(tmpl, "../doughnuts").str());
  150. try {
  151. m = proc.parseFromBinaryStream(dw);
  152. CPPUNIT_FAIL("exception must be thrown.");
  153. } catch(RecoverableException& e) {
  154. // success
  155. }
  156. }
  157. {
  158. // Testing url@priority
  159. const char* tmpl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  160. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  161. "<file name=\"example.ext\">"
  162. "<url priority=\"%s\">http://example.org</url>"
  163. "</file>"
  164. "</metalink>";
  165. dw->setString(StringFormat(tmpl, "0").str());
  166. try {
  167. m = proc.parseFromBinaryStream(dw);
  168. CPPUNIT_FAIL("exception must be thrown.");
  169. } catch(RecoverableException& e) {
  170. // success
  171. }
  172. dw->setString(StringFormat(tmpl, "1").str());
  173. m = proc.parseFromBinaryStream(dw);
  174. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  175. dw->setString(StringFormat(tmpl, "100").str());
  176. m = proc.parseFromBinaryStream(dw);
  177. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  178. dw->setString(StringFormat(tmpl, "999999").str());
  179. m = proc.parseFromBinaryStream(dw);
  180. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  181. dw->setString(StringFormat(tmpl, "1000000").str());
  182. try {
  183. m = proc.parseFromBinaryStream(dw);
  184. CPPUNIT_FAIL("exception must be thrown.");
  185. } catch(RecoverableException& e) {
  186. // success
  187. }
  188. dw->setString(StringFormat(tmpl, "A").str());
  189. try {
  190. m = proc.parseFromBinaryStream(dw);
  191. CPPUNIT_FAIL("exception must be thrown.");
  192. } catch(RecoverableException& e) {}
  193. }
  194. {
  195. // Testing metaurl@priority
  196. const char* tmpl =
  197. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  198. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  199. "<file name=\"example.ext\">"
  200. "<metaurl priority=\"%s\" mediatype=\"torrent\">http://example.org</metaurl>"
  201. "</file>"
  202. "</metalink>";
  203. dw->setString(StringFormat(tmpl, "0").str());
  204. try {
  205. m = proc.parseFromBinaryStream(dw);
  206. CPPUNIT_FAIL("exception must be thrown.");
  207. } catch(RecoverableException& e) {
  208. // success
  209. }
  210. dw->setString(StringFormat(tmpl, "1").str());
  211. m = proc.parseFromBinaryStream(dw);
  212. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  213. dw->setString(StringFormat(tmpl, "100").str());
  214. m = proc.parseFromBinaryStream(dw);
  215. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  216. dw->setString(StringFormat(tmpl, "999999").str());
  217. m = proc.parseFromBinaryStream(dw);
  218. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  219. dw->setString(StringFormat(tmpl, "1000000").str());
  220. try {
  221. m = proc.parseFromBinaryStream(dw);
  222. CPPUNIT_FAIL("exception must be thrown.");
  223. } catch(RecoverableException& e) {
  224. // success
  225. }
  226. dw->setString(StringFormat(tmpl, "A").str());
  227. try {
  228. m = proc.parseFromBinaryStream(dw);
  229. CPPUNIT_FAIL("exception must be thrown.");
  230. } catch(RecoverableException& e) {}
  231. }
  232. {
  233. // Testing metaurl@mediatype
  234. // no mediatype
  235. dw->setString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  236. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  237. "<file name=\"example.ext\">"
  238. "<metaurl>http://example.org</metaurl>"
  239. "</file>"
  240. "</metalink>");
  241. try {
  242. m = proc.parseFromBinaryStream(dw);
  243. CPPUNIT_FAIL("exception must be thrown.");
  244. } catch(RecoverableException& e) {
  245. // success
  246. }
  247. const char* tmpl =
  248. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  249. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  250. "<file name=\"example.ext\">"
  251. "<metaurl mediatype=\"%s\">http://example.org</metaurl>"
  252. "</file>"
  253. "</metalink>";
  254. dw->setString(StringFormat(tmpl, "torrent").str());
  255. m = proc.parseFromBinaryStream(dw);
  256. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  257. // empty mediatype
  258. dw->setString(StringFormat(tmpl, "").str());
  259. try {
  260. m = proc.parseFromBinaryStream(dw);
  261. CPPUNIT_FAIL("exception must be thrown.");
  262. } catch(RecoverableException& e) {
  263. // success
  264. }
  265. }
  266. {
  267. // Testing metaurl@name
  268. const char* tmpl =
  269. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  270. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  271. "<file name=\"example.ext\">"
  272. "<metaurl mediatype=\"torrent\" name=\"%s\">http://example.org</metaurl>"
  273. "</file>"
  274. "</metalink>";
  275. dw->setString(StringFormat(tmpl, "foo").str());
  276. m = proc.parseFromBinaryStream(dw);
  277. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  278. // dir traversing
  279. dw->setString(StringFormat(tmpl, "../doughnuts").str());
  280. try {
  281. m = proc.parseFromBinaryStream(dw);
  282. CPPUNIT_FAIL("exception must be thrown.");
  283. } catch(RecoverableException& e) {
  284. // success
  285. }
  286. // empty name
  287. dw->setString(StringFormat(tmpl, "").str());
  288. try {
  289. m = proc.parseFromBinaryStream(dw);
  290. CPPUNIT_FAIL("exception must be thrown.");
  291. } catch(RecoverableException& e) {
  292. // success
  293. }
  294. }
  295. {
  296. // Testing pieces@length
  297. // No pieces@length
  298. dw->setString
  299. ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  300. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  301. "<file name=\"example.ext\">"
  302. "<url>http://example.org</url>"
  303. "<pieces type=\"sha-1\">"
  304. "<hash>0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33</hash>"
  305. "</pieces>"
  306. "</file>"
  307. "</metalink>");
  308. try {
  309. m = proc.parseFromBinaryStream(dw);
  310. CPPUNIT_FAIL("exception must be thrown.");
  311. } catch(RecoverableException& e) {}
  312. const char* tmpl =
  313. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  314. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  315. "<file name=\"example.ext\">"
  316. "<url>http://example.org</url>"
  317. "<pieces length=\"%s\" type=\"sha-1\">"
  318. "<hash>0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33</hash>"
  319. "</pieces>"
  320. "</file>"
  321. "</metalink>";
  322. dw->setString(StringFormat(tmpl, "262144").str());
  323. m = proc.parseFromBinaryStream(dw);
  324. // empty
  325. try {
  326. dw->setString(StringFormat(tmpl, "").str());
  327. m = proc.parseFromBinaryStream(dw);
  328. CPPUNIT_FAIL("exception must be thrown.");
  329. } catch(RecoverableException& e) {}
  330. // not a number
  331. try {
  332. dw->setString(StringFormat(tmpl, "A").str());
  333. m = proc.parseFromBinaryStream(dw);
  334. CPPUNIT_FAIL("exception must be thrown.");
  335. } catch(RecoverableException& e) {}
  336. }
  337. {
  338. // Testing pieces@type
  339. // No pieces@type
  340. dw->setString
  341. ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  342. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  343. "<file name=\"example.ext\">"
  344. "<url>http://example.org</url>"
  345. "<pieces length=\"262144\">"
  346. "<hash>0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33</hash>"
  347. "</pieces>"
  348. "</file>"
  349. "</metalink>");
  350. try {
  351. m = proc.parseFromBinaryStream(dw);
  352. CPPUNIT_FAIL("exception must be thrown.");
  353. } catch(RecoverableException& e) {}
  354. const char* tmpl =
  355. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  356. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  357. "<file name=\"example.ext\">"
  358. "<url>http://example.org</url>"
  359. "<pieces length=\"262144\" type=\"%s\">"
  360. "<hash>0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33</hash>"
  361. "</pieces>"
  362. "</file>"
  363. "</metalink>";
  364. dw->setString(StringFormat(tmpl, "sha-1").str());
  365. m = proc.parseFromBinaryStream(dw);
  366. // empty
  367. try {
  368. dw->setString(StringFormat(tmpl, "").str());
  369. m = proc.parseFromBinaryStream(dw);
  370. CPPUNIT_FAIL("exception must be thrown.");
  371. } catch(RecoverableException& e) {}
  372. }
  373. {
  374. // Testing hash@type
  375. // No hash@type
  376. dw->setString
  377. ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  378. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  379. "<file name=\"example.ext\">"
  380. "<url>http://example.org</url>"
  381. "<hash>0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33</hash>"
  382. "</file>"
  383. "</metalink>");
  384. try {
  385. m = proc.parseFromBinaryStream(dw);
  386. CPPUNIT_FAIL("exception must be thrown.");
  387. } catch(RecoverableException& e) {}
  388. const char* tmpl =
  389. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  390. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  391. "<file name=\"example.ext\">"
  392. "<url>http://example.org</url>"
  393. "<hash type=\"%s\">0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33</hash>"
  394. "</file>"
  395. "</metalink>";
  396. dw->setString(StringFormat(tmpl, "sha-1").str());
  397. m = proc.parseFromBinaryStream(dw);
  398. // empty
  399. try {
  400. dw->setString(StringFormat(tmpl, "").str());
  401. m = proc.parseFromBinaryStream(dw);
  402. CPPUNIT_FAIL("exception must be thrown.");
  403. } catch(RecoverableException& e) {}
  404. }
  405. {
  406. // Testing signature@mediatype
  407. // No hash@type
  408. dw->setString
  409. ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  410. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  411. "<file name=\"example.ext\">"
  412. "<url>http://example.org</url>"
  413. "<signature>sig</signature>"
  414. "</file>"
  415. "</metalink>");
  416. try {
  417. m = proc.parseFromBinaryStream(dw);
  418. CPPUNIT_FAIL("exception must be thrown.");
  419. } catch(RecoverableException& e) {}
  420. const char* tmpl =
  421. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  422. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  423. "<file name=\"example.ext\">"
  424. "<url>http://example.org</url>"
  425. "<signature mediatype=\"%s\">sig</signature>"
  426. "</file>"
  427. "</metalink>";
  428. dw->setString(StringFormat(tmpl, "application/pgp-signature").str());
  429. m = proc.parseFromBinaryStream(dw);
  430. // empty
  431. try {
  432. dw->setString(StringFormat(tmpl, "").str());
  433. m = proc.parseFromBinaryStream(dw);
  434. CPPUNIT_FAIL("exception must be thrown.");
  435. } catch(RecoverableException& e) {}
  436. }
  437. }
  438. void MetalinkProcessorTest::testParseFile()
  439. {
  440. MetalinkProcessor proc;
  441. try {
  442. SharedHandle<Metalinker> metalinker = proc.parseFile("test.xml");
  443. std::vector<SharedHandle<MetalinkEntry> >::iterator entryItr =
  444. metalinker->entries.begin();
  445. SharedHandle<MetalinkEntry> entry1 = *entryItr;
  446. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), entry1->getPath());
  447. CPPUNIT_ASSERT_EQUAL((uint64_t)0ULL, entry1->getLength());
  448. CPPUNIT_ASSERT_EQUAL(std::string("0.5.2"), entry1->version);
  449. CPPUNIT_ASSERT_EQUAL(std::string("en-US"), entry1->languages[0]);
  450. CPPUNIT_ASSERT_EQUAL(std::string("Linux-x86"), entry1->oses[0]);
  451. CPPUNIT_ASSERT_EQUAL(1, entry1->maxConnections);
  452. #ifdef ENABLE_MESSAGE_DIGEST
  453. CPPUNIT_ASSERT_EQUAL(std::string("a96cf3f0266b91d87d5124cf94326422800b627d"),
  454. entry1->checksum->getMessageDigest());
  455. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), entry1->checksum->getAlgo());
  456. #endif // ENABLE_MESSAGE_DIGEST
  457. CPPUNIT_ASSERT(!entry1->getSignature().isNull());
  458. CPPUNIT_ASSERT_EQUAL(std::string("pgp"), entry1->getSignature()->getType());
  459. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2.sig"),
  460. entry1->getSignature()->getFile());
  461. // Note that last '\n' character is trimmed.
  462. CPPUNIT_ASSERT_EQUAL
  463. (std::string
  464. ("-----BEGIN PGP SIGNATURE-----\n"
  465. "Version: GnuPG v1.4.9 (GNU/Linux)\n"
  466. "\n"
  467. "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n"
  468. "ffffffffffffffffffffffff\n"
  469. "fffff\n"
  470. "-----END PGP SIGNATURE-----"),
  471. entry1->getSignature()->getBody());
  472. std::vector<SharedHandle<MetalinkResource> >::iterator resourceItr1 =
  473. entry1->resources.begin();
  474. SharedHandle<MetalinkResource> resource1 = *resourceItr1;
  475. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, resource1->type);
  476. CPPUNIT_ASSERT_EQUAL(std::string("jp"), resource1->location);
  477. CPPUNIT_ASSERT_EQUAL(1, resource1->priority);
  478. CPPUNIT_ASSERT_EQUAL(std::string("ftp://ftphost/aria2-0.5.2.tar.bz2"),
  479. resource1->url);
  480. CPPUNIT_ASSERT_EQUAL(1, resource1->maxConnections);
  481. resourceItr1++;
  482. SharedHandle<MetalinkResource> resource2 = *resourceItr1;
  483. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, resource2->type);
  484. CPPUNIT_ASSERT_EQUAL(std::string("us"), resource2->location);
  485. CPPUNIT_ASSERT_EQUAL(1, resource2->priority);
  486. CPPUNIT_ASSERT_EQUAL(std::string("http://httphost/aria2-0.5.2.tar.bz2"),
  487. resource2->url);
  488. CPPUNIT_ASSERT_EQUAL(-1, resource2->maxConnections);
  489. entryItr++;
  490. SharedHandle<MetalinkEntry> entry2 = *entryItr;
  491. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.1.tar.bz2"), entry2->getPath());
  492. CPPUNIT_ASSERT_EQUAL((uint64_t)345689ULL, entry2->getLength());
  493. CPPUNIT_ASSERT_EQUAL(std::string("0.5.1"), entry2->version);
  494. CPPUNIT_ASSERT_EQUAL(std::string("ja-JP"), entry2->languages[0]);
  495. CPPUNIT_ASSERT_EQUAL(std::string("Linux-m68k"), entry2->oses[0]);
  496. CPPUNIT_ASSERT_EQUAL(-1, entry2->maxConnections);
  497. #ifdef ENABLE_MESSAGE_DIGEST
  498. CPPUNIT_ASSERT_EQUAL(std::string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
  499. entry2->checksum->getMessageDigest());
  500. CPPUNIT_ASSERT_EQUAL((size_t)2, entry2->chunkChecksum->countChecksum());
  501. CPPUNIT_ASSERT_EQUAL((size_t)262144, entry2->chunkChecksum->getChecksumLength());
  502. CPPUNIT_ASSERT_EQUAL(std::string("179463a88d79cbf0b1923991708aead914f26142"),
  503. entry2->chunkChecksum->getChecksum(0));
  504. CPPUNIT_ASSERT_EQUAL(std::string("fecf8bc9a1647505fe16746f94e97a477597dbf3"),
  505. entry2->chunkChecksum->getChecksum(1));
  506. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), entry2->checksum->getAlgo());
  507. #endif // ENABLE_MESSAGE_DIGEST
  508. // See that signature is null
  509. CPPUNIT_ASSERT(entry2->getSignature().isNull());
  510. entryItr++;
  511. // test case: verification hash is not provided
  512. SharedHandle<MetalinkEntry> entry3 = *entryItr;
  513. CPPUNIT_ASSERT_EQUAL(std::string("NoVerificationHash"), entry3->getPath());
  514. #ifdef ENABLE_MESSAGE_DIGEST
  515. CPPUNIT_ASSERT(entry3->checksum.isNull());
  516. CPPUNIT_ASSERT(entry3->chunkChecksum.isNull());
  517. #endif // ENABLE_MESSAGE_DIGEST
  518. entryItr++;
  519. // test case: unsupported verification hash is included
  520. SharedHandle<MetalinkEntry> entry4 = *entryItr;
  521. CPPUNIT_ASSERT_EQUAL(std::string("UnsupportedVerificationHashTypeIncluded"), entry4->getPath());
  522. #ifdef ENABLE_MESSAGE_DIGEST
  523. CPPUNIT_ASSERT_EQUAL(std::string("sha1"),
  524. entry4->checksum->getAlgo());
  525. CPPUNIT_ASSERT_EQUAL(std::string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
  526. entry4->checksum->getMessageDigest());
  527. CPPUNIT_ASSERT_EQUAL(std::string("sha1"),
  528. entry4->chunkChecksum->getAlgo());
  529. #endif // ENABLE_MESSAGE_DIGEST
  530. } catch(Exception& e) {
  531. CPPUNIT_FAIL(e.stackTrace());
  532. }
  533. }
  534. void MetalinkProcessorTest::testParseFile_dirtraversal()
  535. {
  536. MetalinkProcessor proc;
  537. SharedHandle<Metalinker> metalinker =
  538. proc.parseFile("metalink3-dirtraversal.xml");
  539. CPPUNIT_ASSERT_EQUAL((size_t)1, metalinker->entries.size());
  540. SharedHandle<MetalinkEntry> e = metalinker->entries[0];
  541. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.3.tar.bz2"), e->getPath());
  542. CPPUNIT_ASSERT(!e->getSignature().isNull());
  543. CPPUNIT_ASSERT_EQUAL(std::string(""), e->getSignature()->getFile());
  544. }
  545. void MetalinkProcessorTest::testParseFromBinaryStream()
  546. {
  547. MetalinkProcessor proc;
  548. DefaultDiskWriterHandle dw(new DefaultDiskWriter("test.xml"));
  549. dw->openExistingFile();
  550. try {
  551. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  552. std::vector<SharedHandle<MetalinkEntry> >::iterator entryItr =
  553. m->entries.begin();
  554. SharedHandle<MetalinkEntry> entry1 = *entryItr;
  555. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), entry1->getPath());
  556. } catch(Exception& e) {
  557. CPPUNIT_FAIL(e.stackTrace());
  558. }
  559. }
  560. void MetalinkProcessorTest::testMalformedXML()
  561. {
  562. MetalinkProcessor proc;
  563. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  564. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\"><files></file></metalink>");
  565. try {
  566. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  567. CPPUNIT_FAIL("exception must be thrown.");
  568. } catch(Exception& e) {
  569. std::cerr << e.stackTrace() << std::endl;
  570. }
  571. }
  572. void MetalinkProcessorTest::testMalformedXML2()
  573. {
  574. MetalinkProcessor proc;
  575. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  576. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\"><files></files>");
  577. try {
  578. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  579. CPPUNIT_FAIL("exception must be thrown.");
  580. } catch(Exception& e) {
  581. std::cerr << e.stackTrace() << std::endl;
  582. }
  583. }
  584. void MetalinkProcessorTest::testBadSizeV4()
  585. {
  586. MetalinkProcessor proc;
  587. SharedHandle<Metalinker> m;
  588. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  589. const char* tmpl =
  590. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  591. "<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\">"
  592. "<file name=\"foo\">"
  593. "<size>%s</size>"
  594. "<url>http://example.org</url>"
  595. "</file>"
  596. "</metalink>";
  597. dw->setString(StringFormat(tmpl, "9223372036854775807").str());
  598. m = proc.parseFromBinaryStream(dw);
  599. dw->setString(StringFormat(tmpl, "-1").str());
  600. try {
  601. m = proc.parseFromBinaryStream(dw);
  602. CPPUNIT_FAIL("exception must be thrown.");
  603. } catch(RecoverableException& e) {}
  604. }
  605. void MetalinkProcessorTest::testBadSize()
  606. {
  607. MetalinkProcessor proc;
  608. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  609. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  610. "<files>"
  611. "<file name=\"aria2-0.5.2.tar.bz2\">"
  612. " <size>abc</size>"
  613. " <version>0.5.2</version>"
  614. " <language>en-US</language>"
  615. " <os>Linux-x86</os>"
  616. "</file>"
  617. "</files>"
  618. "</metalink>");
  619. try {
  620. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  621. std::vector<SharedHandle<MetalinkEntry> >::iterator entryItr =
  622. m->entries.begin();
  623. SharedHandle<MetalinkEntry> e = *entryItr;
  624. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), e->getPath());
  625. CPPUNIT_ASSERT_EQUAL((uint64_t)0ULL, e->getLength());
  626. CPPUNIT_ASSERT_EQUAL(std::string("0.5.2"), e->version);
  627. CPPUNIT_ASSERT_EQUAL(std::string("en-US"), e->languages[0]);
  628. CPPUNIT_ASSERT_EQUAL(std::string("Linux-x86"), e->oses[0]);
  629. } catch(Exception& e) {
  630. CPPUNIT_FAIL(e.stackTrace());
  631. }
  632. }
  633. void MetalinkProcessorTest::testBadMaxConn()
  634. {
  635. MetalinkProcessor proc;
  636. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  637. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  638. "<files>"
  639. "<file name=\"aria2-0.5.2.tar.bz2\">"
  640. " <size>43743838</size>"
  641. " <version>0.5.2</version>"
  642. " <language>en-US</language>"
  643. " <os>Linux-x86</os>"
  644. " <resources maxconnections=\"abc\"/>"
  645. "</file>"
  646. "</files>"
  647. "</metalink>");
  648. try {
  649. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  650. std::vector<SharedHandle<MetalinkEntry> >::iterator entryItr =
  651. m->entries.begin();
  652. SharedHandle<MetalinkEntry> e = *entryItr;
  653. CPPUNIT_ASSERT_EQUAL((uint64_t)43743838ULL, e->getLength());
  654. } catch(Exception& e) {
  655. CPPUNIT_FAIL(e.stackTrace());
  656. }
  657. }
  658. void MetalinkProcessorTest::testNoName()
  659. {
  660. MetalinkProcessor proc;
  661. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  662. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  663. "<files>"
  664. "<file>"
  665. " <size>1024</size>"
  666. " <version>0.0.1</version>"
  667. " <language>GB</language>"
  668. " <os>Linux-x64</os>"
  669. "</file>"
  670. "<file name=\"aria2-0.5.2.tar.bz2\">"
  671. " <size>43743838</size>"
  672. " <version>0.5.2</version>"
  673. " <language>en-US</language>"
  674. " <os>Linux-x86</os>"
  675. "</file>"
  676. "</files>"
  677. "</metalink>");
  678. try {
  679. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  680. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  681. std::vector<SharedHandle<MetalinkEntry> >::iterator entryItr =
  682. m->entries.begin();
  683. SharedHandle<MetalinkEntry> e = *entryItr;
  684. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), e->getPath());
  685. } catch(Exception& e) {
  686. CPPUNIT_FAIL(e.stackTrace());
  687. }
  688. }
  689. void MetalinkProcessorTest::testBadURLPrefs()
  690. {
  691. MetalinkProcessor proc;
  692. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  693. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  694. "<files>"
  695. "<file name=\"aria2-0.5.2.tar.bz2\">"
  696. " <size>43743838</size>"
  697. " <version>0.5.2</version>"
  698. " <language>en-US</language>"
  699. " <os>Linux-x86</os>"
  700. " <resources>"
  701. " <url type=\"ftp\" maxconnections=\"1\" preference=\"xyz\""
  702. " location=\"jp\">ftp://mirror/</url>"
  703. " </resources>"
  704. "</file>"
  705. "</files>"
  706. "</metalink>");
  707. try {
  708. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  709. SharedHandle<MetalinkEntry> e = m->entries[0];
  710. SharedHandle<MetalinkResource> r = e->resources[0];
  711. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, r->type);
  712. CPPUNIT_ASSERT_EQUAL(MetalinkResource::getLowestPriority(), r->priority);
  713. CPPUNIT_ASSERT_EQUAL(1, r->maxConnections);
  714. CPPUNIT_ASSERT_EQUAL(std::string("jp"), r->location);
  715. } catch(Exception& e) {
  716. CPPUNIT_FAIL(e.stackTrace());
  717. }
  718. }
  719. void MetalinkProcessorTest::testBadURLMaxConn()
  720. {
  721. MetalinkProcessor proc;
  722. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  723. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  724. "<files>"
  725. "<file name=\"aria2-0.5.2.tar.bz2\">"
  726. " <size>43743838</size>"
  727. " <version>0.5.2</version>"
  728. " <language>en-US</language>"
  729. " <os>Linux-x86</os>"
  730. " <resources>"
  731. " <url maxconnections=\"xyz\" type=\"ftp\""
  732. " preference=\"100\""
  733. " location=\"jp\">ftp://mirror/</url>"
  734. " </resources>"
  735. "</file>"
  736. "</files>"
  737. "</metalink>");
  738. try {
  739. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  740. SharedHandle<MetalinkEntry> e = m->entries[0];
  741. SharedHandle<MetalinkResource> r = e->resources[0];
  742. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, r->type);
  743. CPPUNIT_ASSERT_EQUAL(1, r->priority);
  744. CPPUNIT_ASSERT_EQUAL(-1, r->maxConnections);
  745. CPPUNIT_ASSERT_EQUAL(std::string("jp"), r->location);
  746. } catch(Exception& e) {
  747. CPPUNIT_FAIL(e.stackTrace());
  748. }
  749. }
  750. #ifdef ENABLE_MESSAGE_DIGEST
  751. void MetalinkProcessorTest::testUnsupportedType()
  752. {
  753. MetalinkProcessor proc;
  754. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  755. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  756. "<files>"
  757. "<file name=\"aria2-0.5.2.tar.bz2\">"
  758. " <size>43743838</size>"
  759. " <version>0.5.2</version>"
  760. " <language>en-US</language>"
  761. " <os>Linux-x86</os>"
  762. " <resources>"
  763. " <url type=\"ftp\">ftp://mirror/</url>"
  764. " <url type=\"magnet\">magnet:xt=XYZ</url>"
  765. " <url type=\"http\">http://mirror/</url>"
  766. " </resources>"
  767. "</file>"
  768. "</files>"
  769. "</metalink>");
  770. try {
  771. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  772. SharedHandle<MetalinkEntry> e = m->entries[0];
  773. CPPUNIT_ASSERT_EQUAL((size_t)3, e->resources.size());
  774. SharedHandle<MetalinkResource> r1 = e->resources[0];
  775. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, r1->type);
  776. SharedHandle<MetalinkResource> r2 = e->resources[1];
  777. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_NOT_SUPPORTED, r2->type);
  778. SharedHandle<MetalinkResource> r3 = e->resources[2];
  779. CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, r3->type);
  780. } catch(Exception& e) {
  781. CPPUNIT_FAIL(e.stackTrace());
  782. }
  783. }
  784. void MetalinkProcessorTest::testMultiplePieces()
  785. {
  786. MetalinkProcessor proc;
  787. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  788. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  789. "<files>"
  790. "<file name=\"aria2.tar.bz2\">"
  791. " <verification>"
  792. " <pieces length=\"1024\" type=\"sha1\">"
  793. " </pieces>"
  794. " <pieces length=\"512\" type=\"md5\">"
  795. " </pieces>"
  796. " </verification>"
  797. "</file>"
  798. "</files>"
  799. "</metalink>");
  800. try {
  801. // aria2 prefers sha1
  802. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  803. SharedHandle<MetalinkEntry> e = m->entries[0];
  804. SharedHandle<ChunkChecksum> c = e->chunkChecksum;
  805. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), c->getAlgo());
  806. CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
  807. } catch(Exception& e) {
  808. CPPUNIT_FAIL(e.stackTrace());
  809. }
  810. }
  811. void MetalinkProcessorTest::testBadPieceNo()
  812. {
  813. MetalinkProcessor proc;
  814. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  815. dw->setString
  816. ("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  817. "<files>"
  818. "<file name=\"aria2.tar.bz2\">"
  819. " <verification>"
  820. " <pieces length=\"512\" type=\"sha1\">"
  821. " <hash piece=\"0\">44213f9f4d59b557314fadcd233232eebcac8012</hash>"
  822. " <hash piece=\"xyz\">44213f9f4d59b557314fadcd233232eebcac8012</hash>"
  823. " </pieces>"
  824. " <pieces length=\"1024\" type=\"sha1\">"
  825. " <hash piece=\"0\">44213f9f4d59b557314fadcd233232eebcac8012</hash>"
  826. " </pieces>"
  827. " </verification>"
  828. "</file>"
  829. "</files>"
  830. "</metalink>");
  831. try {
  832. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  833. SharedHandle<MetalinkEntry> e = m->entries[0];
  834. SharedHandle<ChunkChecksum> c = e->chunkChecksum;
  835. CPPUNIT_ASSERT(!c.isNull());
  836. CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
  837. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), c->getAlgo());
  838. } catch(Exception& e) {
  839. CPPUNIT_FAIL(e.stackTrace());
  840. }
  841. }
  842. void MetalinkProcessorTest::testBadPieceLength()
  843. {
  844. MetalinkProcessor proc;
  845. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  846. dw->setString
  847. ("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  848. "<files>"
  849. "<file name=\"aria2.tar.bz2\">"
  850. " <verification>"
  851. " <pieces length=\"xyz\" type=\"sha1\">"
  852. " <hash piece=\"0\">44213f9f4d59b557314fadcd233232eebcac8012</hash>"
  853. " </pieces>"
  854. " <pieces length=\"1024\" type=\"sha1\">"
  855. " <hash piece=\"0\">44213f9f4d59b557314fadcd233232eebcac8012</hash>"
  856. " </pieces>"
  857. " </verification>"
  858. "</file>"
  859. "</files>"
  860. "</metalink>");
  861. try {
  862. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  863. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  864. SharedHandle<MetalinkEntry> e = m->entries[0];
  865. SharedHandle<ChunkChecksum> c = e->chunkChecksum;
  866. CPPUNIT_ASSERT(!c.isNull());
  867. CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
  868. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), c->getAlgo());
  869. } catch(Exception& e) {
  870. CPPUNIT_FAIL(e.stackTrace());
  871. }
  872. }
  873. void MetalinkProcessorTest::testUnsupportedType_piece()
  874. {
  875. MetalinkProcessor proc;
  876. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  877. dw->setString
  878. ("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  879. "<files>"
  880. "<file name=\"aria2.tar.bz2\">"
  881. " <verification>"
  882. " <pieces length=\"512\" type=\"ARIA2\">"
  883. " <hash piece=\"0\">44213f9f4d59b557314fadcd233232eebcac8012</hash>"
  884. " </pieces>"
  885. " <pieces length=\"1024\" type=\"sha1\">"
  886. " <hash piece=\"0\">44213f9f4d59b557314fadcd233232eebcac8012</hash>"
  887. " </pieces>"
  888. " </verification>"
  889. "</file>"
  890. "</files>"
  891. "</metalink>");
  892. try {
  893. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  894. SharedHandle<MetalinkEntry> e = m->entries[0];
  895. SharedHandle<ChunkChecksum> c = e->chunkChecksum;
  896. CPPUNIT_ASSERT(!c.isNull());
  897. CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
  898. CPPUNIT_ASSERT_EQUAL(std::string("sha1"), c->getAlgo());
  899. } catch(Exception& e) {
  900. CPPUNIT_FAIL(e.stackTrace());
  901. }
  902. }
  903. #endif // ENABLE_MESSAGE_DIGEST
  904. void MetalinkProcessorTest::testLargeFileSize()
  905. {
  906. MetalinkProcessor proc;
  907. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  908. dw->setString("<metalink version=\"3.0\" xmlns=\"http://www.metalinker.org/\">"
  909. "<files>"
  910. "<file name=\"dvd.iso\">"
  911. " <size>9223372036854775807</size>"
  912. " <resources>"
  913. " <url type=\"http\">ftp://mirror/</url>"
  914. " </resources>"
  915. "</file>"
  916. "</files>"
  917. "</metalink>");
  918. try {
  919. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  920. SharedHandle<MetalinkEntry> e = m->entries[0];
  921. CPPUNIT_ASSERT_EQUAL((uint64_t)9223372036854775807ULL, e->getLength());
  922. } catch(Exception& e) {
  923. CPPUNIT_FAIL(e.stackTrace());
  924. }
  925. }
  926. void MetalinkProcessorTest::testXmlPrefixV3()
  927. {
  928. MetalinkProcessor proc;
  929. SharedHandle<ByteArrayDiskWriter> dw(new ByteArrayDiskWriter());
  930. dw->setString("<m:metalink version=\"3.0\" xmlns:m=\"http://www.metalinker.org/\">"
  931. "<m:files>"
  932. "<m:file name=\"dvd.iso\">"
  933. " <m:size>9223372036854775807</m:size>"
  934. " <m:resources>"
  935. " <m:url type=\"http\">ftp://mirror/</m:url>"
  936. " </m:resources>"
  937. "</m:file>"
  938. "</m:files>"
  939. "</m:metalink>");
  940. try {
  941. SharedHandle<Metalinker> m = proc.parseFromBinaryStream(dw);
  942. CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size());
  943. SharedHandle<MetalinkEntry> e = m->entries[0];
  944. CPPUNIT_ASSERT_EQUAL((uint64_t)9223372036854775807ULL, e->getLength());
  945. } catch(Exception& e) {
  946. CPPUNIT_FAIL(e.stackTrace());
  947. }
  948. }
  949. } // namespace aria2