MetalinkProcessorTest.cc 37 KB

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