BittorrentHelperTest.cc 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045
  1. #include "bittorrent_helper.h"
  2. #include <cstring>
  3. #include <iostream>
  4. #include <cppunit/extensions/HelperMacros.h>
  5. #include "DownloadContext.h"
  6. #include "util.h"
  7. #include "RecoverableException.h"
  8. #include "AnnounceTier.h"
  9. #include "FixedNumberRandomizer.h"
  10. #include "FileEntry.h"
  11. #include "array_fun.h"
  12. #include "a2netcompat.h"
  13. #include "bencode2.h"
  14. #include "TestUtil.h"
  15. #include "base32.h"
  16. #include "Option.h"
  17. #include "prefs.h"
  18. namespace aria2 {
  19. namespace bittorrent {
  20. class BittorrentHelperTest : public CppUnit::TestFixture {
  21. CPPUNIT_TEST_SUITE(BittorrentHelperTest);
  22. CPPUNIT_TEST(testGetInfoHash);
  23. CPPUNIT_TEST(testGetPieceHash);
  24. CPPUNIT_TEST(testGetFileEntries);
  25. CPPUNIT_TEST(testGetTotalLength);
  26. CPPUNIT_TEST(testGetFileEntriesSingle);
  27. CPPUNIT_TEST(testGetTotalLengthSingle);
  28. CPPUNIT_TEST(testGetFileModeMulti);
  29. CPPUNIT_TEST(testGetFileModeSingle);
  30. CPPUNIT_TEST(testGetNameMulti);
  31. CPPUNIT_TEST(testGetNameSingle);
  32. CPPUNIT_TEST(testOverrideName);
  33. CPPUNIT_TEST(testGetAnnounceTier);
  34. CPPUNIT_TEST(testGetAnnounceTierAnnounceList);
  35. CPPUNIT_TEST(testGetPieceLength);
  36. CPPUNIT_TEST(testGetInfoHashAsString);
  37. CPPUNIT_TEST(testGetPeerId);
  38. CPPUNIT_TEST(testGetPeerAgent);
  39. CPPUNIT_TEST(testComputeFastSet);
  40. CPPUNIT_TEST(testGetFileEntries_multiFileUrlList);
  41. CPPUNIT_TEST(testGetFileEntries_singleFileUrlList);
  42. CPPUNIT_TEST(testGetFileEntries_singleFileUrlListEndsWithSlash);
  43. CPPUNIT_TEST(testLoadFromMemory);
  44. CPPUNIT_TEST(testLoadFromMemory_somethingMissing);
  45. CPPUNIT_TEST(testLoadFromMemory_overrideName);
  46. CPPUNIT_TEST(testLoadFromMemory_multiFileDirTraversal);
  47. CPPUNIT_TEST(testLoadFromMemory_singleFileDirTraversal);
  48. CPPUNIT_TEST(testLoadFromMemory_multiFileNonUtf8Path);
  49. CPPUNIT_TEST(testLoadFromMemory_singleFileNonUtf8Path);
  50. CPPUNIT_TEST(testGetNodes);
  51. CPPUNIT_TEST(testGetBasePath);
  52. CPPUNIT_TEST(testSetFileFilter_single);
  53. CPPUNIT_TEST(testSetFileFilter_multi);
  54. CPPUNIT_TEST(testUTF8Torrent);
  55. CPPUNIT_TEST(testEtc);
  56. CPPUNIT_TEST(testCheckBitfield);
  57. CPPUNIT_TEST(testMetadata);
  58. CPPUNIT_TEST(testParseMagnet);
  59. CPPUNIT_TEST(testParseMagnet_base32);
  60. CPPUNIT_TEST(testMetadata2Torrent);
  61. CPPUNIT_TEST(testTorrent2Magnet);
  62. CPPUNIT_TEST(testExtractPeerFromString);
  63. CPPUNIT_TEST(testExtractPeerFromList);
  64. CPPUNIT_TEST(testExtract2PeersFromList);
  65. CPPUNIT_TEST(testPackcompact);
  66. CPPUNIT_TEST(testUnpackcompact);
  67. CPPUNIT_TEST(testRemoveAnnounceUri);
  68. CPPUNIT_TEST(testAddAnnounceUri);
  69. CPPUNIT_TEST(testAdjustAnnounceUri);
  70. CPPUNIT_TEST_SUITE_END();
  71. public:
  72. std::shared_ptr<Option> option_;
  73. void setUp()
  74. {
  75. option_.reset(new Option());
  76. option_->put(PREF_DIR, ".");
  77. }
  78. void testGetInfoHash();
  79. void testGetPieceHash();
  80. void testGetFileEntries();
  81. void testGetTotalLength();
  82. void testGetFileEntriesSingle();
  83. void testGetTotalLengthSingle();
  84. void testGetFileModeMulti();
  85. void testGetFileModeSingle();
  86. void testGetNameMulti();
  87. void testGetNameSingle();
  88. void testOverrideName();
  89. void testGetAnnounceTier();
  90. void testGetAnnounceTierAnnounceList();
  91. void testGetPieceLength();
  92. void testGetInfoHashAsString();
  93. void testGetPeerId();
  94. void testGetPeerAgent();
  95. void testComputeFastSet();
  96. void testGetFileEntries_multiFileUrlList();
  97. void testGetFileEntries_singleFileUrlList();
  98. void testGetFileEntries_singleFileUrlListEndsWithSlash();
  99. void testLoadFromMemory();
  100. void testLoadFromMemory_somethingMissing();
  101. void testLoadFromMemory_overrideName();
  102. void testLoadFromMemory_multiFileDirTraversal();
  103. void testLoadFromMemory_singleFileDirTraversal();
  104. void testLoadFromMemory_multiFileNonUtf8Path();
  105. void testLoadFromMemory_singleFileNonUtf8Path();
  106. void testGetNodes();
  107. void testGetBasePath();
  108. void testSetFileFilter_single();
  109. void testSetFileFilter_multi();
  110. void testUTF8Torrent();
  111. void testEtc();
  112. void testCheckBitfield();
  113. void testMetadata();
  114. void testParseMagnet();
  115. void testParseMagnet_base32();
  116. void testMetadata2Torrent();
  117. void testTorrent2Magnet();
  118. void testExtractPeerFromString();
  119. void testExtractPeerFromList();
  120. void testExtract2PeersFromList();
  121. void testPackcompact();
  122. void testUnpackcompact();
  123. void testRemoveAnnounceUri();
  124. void testAddAnnounceUri();
  125. void testAdjustAnnounceUri();
  126. };
  127. CPPUNIT_TEST_SUITE_REGISTRATION(BittorrentHelperTest);
  128. void BittorrentHelperTest::testGetInfoHash()
  129. {
  130. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  131. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  132. std::string correctHash = "248d0a1cd08284299de78d5c1ed359bb46717d8c";
  133. CPPUNIT_ASSERT_EQUAL(correctHash, bittorrent::getInfoHashString(dctx));
  134. }
  135. void BittorrentHelperTest::testGetPieceHash()
  136. {
  137. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  138. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  139. CPPUNIT_ASSERT_EQUAL(std::string("AAAAAAAAAAAAAAAAAAAA"),
  140. dctx->getPieceHash(0));
  141. CPPUNIT_ASSERT_EQUAL(std::string("BBBBBBBBBBBBBBBBBBBB"),
  142. dctx->getPieceHash(1));
  143. CPPUNIT_ASSERT_EQUAL(std::string("CCCCCCCCCCCCCCCCCCCC"),
  144. dctx->getPieceHash(2));
  145. CPPUNIT_ASSERT_EQUAL(std::string(""), dctx->getPieceHash(3));
  146. CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), dctx->getPieceHashType());
  147. }
  148. void BittorrentHelperTest::testGetFileEntries()
  149. {
  150. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  151. option_->put(PREF_MAX_CONNECTION_PER_SERVER, "10");
  152. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  153. // This is multi-file torrent.
  154. std::vector<std::shared_ptr<FileEntry>> fileEntries = dctx->getFileEntries();
  155. // There are 2 file entries.
  156. CPPUNIT_ASSERT_EQUAL((size_t)2, fileEntries.size());
  157. std::vector<std::shared_ptr<FileEntry>>::iterator itr = fileEntries.begin();
  158. std::shared_ptr<FileEntry> fileEntry1 = *itr;
  159. CPPUNIT_ASSERT_EQUAL(std::string("./aria2-test/aria2/src/aria2c"),
  160. fileEntry1->getPath());
  161. CPPUNIT_ASSERT_EQUAL(std::string("aria2-test/aria2/src/aria2c"),
  162. fileEntry1->getOriginalName());
  163. CPPUNIT_ASSERT_EQUAL(10, fileEntry1->getMaxConnectionPerServer());
  164. itr++;
  165. std::shared_ptr<FileEntry> fileEntry2 = *itr;
  166. CPPUNIT_ASSERT_EQUAL(std::string("./aria2-test/aria2-0.2.2.tar.bz2"),
  167. fileEntry2->getPath());
  168. CPPUNIT_ASSERT_EQUAL(10, fileEntry2->getMaxConnectionPerServer());
  169. }
  170. void BittorrentHelperTest::testGetFileEntriesSingle()
  171. {
  172. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  173. option_->put(PREF_MAX_CONNECTION_PER_SERVER, "10");
  174. load(A2_TEST_DIR "/single.torrent", dctx, option_);
  175. // This is multi-file torrent.
  176. std::vector<std::shared_ptr<FileEntry>> fileEntries = dctx->getFileEntries();
  177. // There is 1 file entry.
  178. CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries.size());
  179. std::vector<std::shared_ptr<FileEntry>>::iterator itr = fileEntries.begin();
  180. std::shared_ptr<FileEntry> fileEntry1 = *itr;
  181. CPPUNIT_ASSERT_EQUAL(std::string("./aria2-0.8.2.tar.bz2"),
  182. fileEntry1->getPath());
  183. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.8.2.tar.bz2"),
  184. fileEntry1->getOriginalName());
  185. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.8.2.tar.bz2"),
  186. fileEntry1->getSuffixPath());
  187. CPPUNIT_ASSERT_EQUAL(10, fileEntry1->getMaxConnectionPerServer());
  188. }
  189. void BittorrentHelperTest::testGetTotalLength()
  190. {
  191. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  192. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  193. CPPUNIT_ASSERT_EQUAL((int64_t)384LL, dctx->getTotalLength());
  194. }
  195. void BittorrentHelperTest::testGetTotalLengthSingle()
  196. {
  197. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  198. load(A2_TEST_DIR "/single.torrent", dctx, option_);
  199. CPPUNIT_ASSERT_EQUAL((int64_t)384LL, dctx->getTotalLength());
  200. }
  201. void BittorrentHelperTest::testGetFileModeMulti()
  202. {
  203. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  204. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  205. CPPUNIT_ASSERT_EQUAL(BT_FILE_MODE_MULTI, getTorrentAttrs(dctx)->mode);
  206. }
  207. void BittorrentHelperTest::testGetFileModeSingle()
  208. {
  209. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  210. load(A2_TEST_DIR "/single.torrent", dctx, option_);
  211. CPPUNIT_ASSERT_EQUAL(BT_FILE_MODE_SINGLE, getTorrentAttrs(dctx)->mode);
  212. }
  213. void BittorrentHelperTest::testGetNameMulti()
  214. {
  215. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  216. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  217. CPPUNIT_ASSERT_EQUAL(std::string("aria2-test"), getTorrentAttrs(dctx)->name);
  218. }
  219. void BittorrentHelperTest::testGetNameSingle()
  220. {
  221. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  222. load(A2_TEST_DIR "/single.torrent", dctx, option_);
  223. CPPUNIT_ASSERT_EQUAL(std::string("./aria2-0.8.2.tar.bz2"),
  224. dctx->getBasePath());
  225. CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.8.2.tar.bz2"),
  226. getTorrentAttrs(dctx)->name);
  227. }
  228. void BittorrentHelperTest::testOverrideName()
  229. {
  230. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  231. load(A2_TEST_DIR "/test.torrent", dctx, option_, "aria2-override.name");
  232. CPPUNIT_ASSERT_EQUAL(std::string("./aria2-override.name"),
  233. dctx->getBasePath());
  234. CPPUNIT_ASSERT_EQUAL(std::string("aria2-override.name"),
  235. getTorrentAttrs(dctx)->name);
  236. }
  237. void BittorrentHelperTest::testGetAnnounceTier()
  238. {
  239. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  240. load(A2_TEST_DIR "/single.torrent", dctx, option_);
  241. auto attrs = getTorrentAttrs(dctx);
  242. // There is 1 tier.
  243. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList.size());
  244. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[0].size());
  245. CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com/announce.php"),
  246. attrs->announceList[0][0]);
  247. }
  248. void BittorrentHelperTest::testGetAnnounceTierAnnounceList()
  249. {
  250. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  251. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  252. auto attrs = getTorrentAttrs(dctx);
  253. // There are 3 tiers.
  254. CPPUNIT_ASSERT_EQUAL((size_t)3, attrs->announceList.size());
  255. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[0].size());
  256. CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"),
  257. attrs->announceList[0][0]);
  258. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[1].size());
  259. CPPUNIT_ASSERT_EQUAL(std::string("http://tracker2"),
  260. attrs->announceList[1][0]);
  261. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[2].size());
  262. CPPUNIT_ASSERT_EQUAL(std::string("http://tracker3"),
  263. attrs->announceList[2][0]);
  264. }
  265. void BittorrentHelperTest::testGetPieceLength()
  266. {
  267. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  268. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  269. CPPUNIT_ASSERT_EQUAL(128, dctx->getPieceLength());
  270. }
  271. void BittorrentHelperTest::testGetInfoHashAsString()
  272. {
  273. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  274. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  275. CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  276. getInfoHashString(dctx));
  277. }
  278. void BittorrentHelperTest::testGetPeerId()
  279. {
  280. std::string peerId = generatePeerId("aria2-");
  281. CPPUNIT_ASSERT(peerId.find("aria2-") == 0);
  282. CPPUNIT_ASSERT_EQUAL((size_t)20, peerId.size());
  283. }
  284. void BittorrentHelperTest::testGetPeerAgent()
  285. {
  286. std::string peerAgent = generateStaticPeerAgent("aria2/-1.-1.-1");
  287. CPPUNIT_ASSERT_EQUAL(std::string("aria2/-1.-1.-1"), peerAgent);
  288. CPPUNIT_ASSERT_EQUAL(std::string("aria2/-1.-1.-1"), bittorrent::getStaticPeerAgent());
  289. }
  290. void BittorrentHelperTest::testComputeFastSet()
  291. {
  292. std::string ipaddr = "192.168.0.1";
  293. unsigned char infoHash[20];
  294. memset(infoHash, 0, sizeof(infoHash));
  295. infoHash[0] = 0xff;
  296. int fastSetSize = 10;
  297. size_t numPieces = 1000;
  298. {
  299. auto fastSet = computeFastSet(ipaddr, numPieces, infoHash, fastSetSize);
  300. size_t ans[] = {686, 459, 278, 200, 404, 834, 64, 203, 760, 950};
  301. CPPUNIT_ASSERT(std::equal(fastSet.begin(), fastSet.end(), std::begin(ans)));
  302. }
  303. ipaddr = "10.0.0.1";
  304. {
  305. auto fastSet = computeFastSet(ipaddr, numPieces, infoHash, fastSetSize);
  306. size_t ans[] = {568, 188, 466, 452, 550, 662, 109, 226, 398, 11};
  307. CPPUNIT_ASSERT(std::equal(fastSet.begin(), fastSet.end(), std::begin(ans)));
  308. }
  309. // See when pieces < fastSetSize
  310. numPieces = 9;
  311. {
  312. auto fastSet = computeFastSet(ipaddr, numPieces, infoHash, fastSetSize);
  313. size_t ans[] = {8, 6, 7, 5, 1, 4, 0, 2, 3};
  314. CPPUNIT_ASSERT(std::equal(fastSet.begin(), fastSet.end(), std::begin(ans)));
  315. }
  316. }
  317. void BittorrentHelperTest::testGetFileEntries_multiFileUrlList()
  318. {
  319. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  320. load(A2_TEST_DIR "/url-list-multiFile.torrent", dctx, option_);
  321. // This is multi-file torrent.
  322. const std::vector<std::shared_ptr<FileEntry>>& fileEntries =
  323. dctx->getFileEntries();
  324. // There are 2 file entries.
  325. CPPUNIT_ASSERT_EQUAL((size_t)2, fileEntries.size());
  326. std::vector<std::shared_ptr<FileEntry>>::const_iterator itr =
  327. fileEntries.begin();
  328. const std::shared_ptr<FileEntry>& fileEntry1 = *itr;
  329. CPPUNIT_ASSERT_EQUAL(std::string("./aria2-test@/aria2@/src@/aria2c@"),
  330. fileEntry1->getPath());
  331. CPPUNIT_ASSERT_EQUAL(std::string("aria2-test@/aria2@/src@/aria2c@"),
  332. fileEntry1->getSuffixPath());
  333. const std::deque<std::string>& uris1 = fileEntry1->getRemainingUris();
  334. CPPUNIT_ASSERT_EQUAL((size_t)2, uris1.size());
  335. CPPUNIT_ASSERT_EQUAL(
  336. std::string(
  337. "http://localhost/dist/aria2-test%40/aria2%40/src%40/aria2c%40"),
  338. uris1[0]);
  339. CPPUNIT_ASSERT_EQUAL(
  340. std::string("http://mirror/dist/aria2-test%40/aria2%40/src%40/aria2c%40"),
  341. uris1[1]);
  342. ++itr;
  343. const std::shared_ptr<FileEntry>& fileEntry2 = *itr;
  344. CPPUNIT_ASSERT_EQUAL(std::string("./aria2-test@/aria2-0.2.2.tar.bz2"),
  345. fileEntry2->getPath());
  346. const std::deque<std::string>& uris2 = fileEntry2->getRemainingUris();
  347. CPPUNIT_ASSERT_EQUAL((size_t)2, uris2.size());
  348. CPPUNIT_ASSERT_EQUAL(
  349. std::string("http://localhost/dist/aria2-test%40/aria2-0.2.2.tar.bz2"),
  350. uris2[0]);
  351. CPPUNIT_ASSERT_EQUAL(
  352. std::string("http://mirror/dist/aria2-test%40/aria2-0.2.2.tar.bz2"),
  353. uris2[1]);
  354. }
  355. void BittorrentHelperTest::testGetFileEntries_singleFileUrlList()
  356. {
  357. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  358. load(A2_TEST_DIR "/url-list-singleFile.torrent", dctx, option_);
  359. // This is single-file torrent.
  360. const std::vector<std::shared_ptr<FileEntry>>& fileEntries =
  361. dctx->getFileEntries();
  362. // There are 1 file entries.
  363. CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries.size());
  364. const std::shared_ptr<FileEntry>& fileEntry1 = fileEntries.front();
  365. CPPUNIT_ASSERT_EQUAL(std::string("./aria2.tar.bz2"), fileEntry1->getPath());
  366. const std::deque<std::string>& uris1 = fileEntry1->getRemainingUris();
  367. CPPUNIT_ASSERT_EQUAL((size_t)1, uris1.size());
  368. CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/dist/aria2.tar.bz2"),
  369. uris1[0]);
  370. }
  371. void BittorrentHelperTest::testGetFileEntries_singleFileUrlListEndsWithSlash()
  372. {
  373. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  374. load(A2_TEST_DIR "/url-list-singleFileEndsWithSlash.torrent", dctx, option_);
  375. // This is single-file torrent.
  376. const std::vector<std::shared_ptr<FileEntry>>& fileEntries =
  377. dctx->getFileEntries();
  378. // There are 1 file entries.
  379. CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries.size());
  380. const std::shared_ptr<FileEntry>& fileEntry1 = fileEntries.front();
  381. CPPUNIT_ASSERT_EQUAL(std::string("./aria2@.tar.bz2"), fileEntry1->getPath());
  382. const std::deque<std::string>& uris1 = fileEntry1->getRemainingUris();
  383. CPPUNIT_ASSERT_EQUAL((size_t)1, uris1.size());
  384. CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/dist/aria2%40.tar.bz2"),
  385. uris1[0]);
  386. }
  387. void BittorrentHelperTest::testLoadFromMemory_multiFileNonUtf8Path()
  388. {
  389. auto path = List::g();
  390. path->append("path");
  391. path->append(fromHex("90a28a") + "E");
  392. auto file = Dict::g();
  393. file->put("length", Integer::g(1_k));
  394. file->put("path", std::move(path));
  395. auto files = List::g();
  396. files->append(std::move(file));
  397. auto info = Dict::g();
  398. info->put("files", std::move(files));
  399. info->put("piece length", Integer::g(1_k));
  400. info->put("pieces", "01234567890123456789");
  401. info->put("name", fromHex("1b") + "$B%O%m!<" + fromHex("1b") + "(B");
  402. Dict dict;
  403. dict.put("info", std::move(info));
  404. auto dctx = std::make_shared<DownloadContext>();
  405. loadFromMemory(bencode2::encode(&dict), dctx, option_, "default");
  406. auto& fe = dctx->getFirstFileEntry();
  407. CPPUNIT_ASSERT_EQUAL(
  408. std::string("./%1B%24B%25O%25m%21%3C%1B%28B/path/%90%A2%8AE"),
  409. fe->getPath());
  410. CPPUNIT_ASSERT_EQUAL(
  411. std::string("%1B%24B%25O%25m%21%3C%1B%28B/path/%90%A2%8AE"),
  412. fe->getSuffixPath());
  413. CPPUNIT_ASSERT_EQUAL(std::string("./%1B%24B%25O%25m%21%3C%1B%28B"),
  414. dctx->getBasePath());
  415. }
  416. void BittorrentHelperTest::testLoadFromMemory_singleFileNonUtf8Path()
  417. {
  418. auto info = Dict::g();
  419. info->put("piece length", Integer::g(1_k));
  420. info->put("pieces", "01234567890123456789");
  421. info->put("name", fromHex("90a28a") + "E");
  422. info->put("length", Integer::g(1_k));
  423. Dict dict;
  424. dict.put("info", std::move(info));
  425. auto dctx = std::make_shared<DownloadContext>();
  426. loadFromMemory(bencode2::encode(&dict), dctx, option_, "default");
  427. const std::shared_ptr<FileEntry>& fe = dctx->getFirstFileEntry();
  428. CPPUNIT_ASSERT_EQUAL(std::string("./%90%A2%8AE"), fe->getPath());
  429. CPPUNIT_ASSERT_EQUAL(std::string("%90%A2%8AE"), fe->getSuffixPath());
  430. }
  431. void BittorrentHelperTest::testLoadFromMemory()
  432. {
  433. std::string memory = "d8:announce36:http://aria.rednoah.com/"
  434. "announce.php13:announce-listll16:http://tracker1 "
  435. "el15:http://tracker2el15:http://"
  436. "tracker3ee7:comment17:REDNOAH.COM RULES13:creation "
  437. "datei1123456789e4:infod5:filesld6:lengthi284e4:pathl5:"
  438. "aria23:src6:aria2ceed6:lengthi100e4:pathl19:aria2-0.2."
  439. "2.tar.bz2eee4:name10:aria2-test12:piece "
  440. "lengthi128e6:pieces60:"
  441. "AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCC"
  442. "CCCCCee";
  443. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  444. loadFromMemory(memory, dctx, option_, "default");
  445. std::string correctHash = "248d0a1cd08284299de78d5c1ed359bb46717d8c";
  446. CPPUNIT_ASSERT_EQUAL(correctHash, getInfoHashString(dctx));
  447. }
  448. void BittorrentHelperTest::testLoadFromMemory_somethingMissing()
  449. {
  450. // pieces missing
  451. try {
  452. std::string memory = "d8:announce36:http://aria.rednoah.com/"
  453. "announce.php4:infod4:name13:aria2.tar.bz26:"
  454. "lengthi262144eee";
  455. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  456. loadFromMemory(memory, dctx, option_, "default");
  457. CPPUNIT_FAIL("exception must be thrown.");
  458. }
  459. catch (Exception& e) {
  460. // OK
  461. }
  462. }
  463. void BittorrentHelperTest::testLoadFromMemory_overrideName()
  464. {
  465. std::string memory = "d8:announce36:http://aria.rednoah.com/"
  466. "announce.php13:announce-listll16:http://tracker1 "
  467. "el15:http://tracker2el15:http://"
  468. "tracker3ee7:comment17:REDNOAH.COM RULES13:creation "
  469. "datei1123456789e4:infod5:filesld6:lengthi284e4:pathl5:"
  470. "aria23:src6:aria2ceed6:lengthi100e4:pathl19:aria2-0.2."
  471. "2.tar.bz2eee4:name10:aria2-test12:piece "
  472. "lengthi128e6:pieces60:"
  473. "AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCC"
  474. "CCCCCee";
  475. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  476. loadFromMemory(memory, dctx, option_, "default", "aria2-override.name");
  477. CPPUNIT_ASSERT_EQUAL(std::string("aria2-override.name"),
  478. getTorrentAttrs(dctx)->name);
  479. }
  480. void BittorrentHelperTest::testLoadFromMemory_multiFileDirTraversal()
  481. {
  482. std::string memory = "d8:announce27:http://example.com/"
  483. "announce4:infod5:filesld6:lengthi262144e4:pathl7:../"
  484. "dir14:dir28:file.imgeee4:name14:../name1/name212:piece "
  485. "lengthi262144e6:pieces20:00000000000000000000ee";
  486. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  487. try {
  488. loadFromMemory(memory, dctx, option_, "default");
  489. CPPUNIT_FAIL("Exception must be thrown.");
  490. }
  491. catch (RecoverableException& e) {
  492. // success
  493. }
  494. }
  495. void BittorrentHelperTest::testLoadFromMemory_singleFileDirTraversal()
  496. {
  497. std::string memory = "d8:announce27:http://example.com/"
  498. "announce4:infod4:name14:../name1/"
  499. "name26:lengthi262144e12:piece "
  500. "lengthi262144e6:pieces20:00000000000000000000ee";
  501. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  502. try {
  503. loadFromMemory(memory, dctx, option_, "default");
  504. }
  505. catch (RecoverableException& e) {
  506. // success
  507. }
  508. }
  509. void BittorrentHelperTest::testGetNodes()
  510. {
  511. {
  512. std::string memory = "d5:nodesl"
  513. "l11:192.168.0.1i6881ee"
  514. "l11:192.168.0.2i6882ee"
  515. "e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  516. "12:piece lengthi262144e"
  517. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  518. "ee";
  519. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  520. loadFromMemory(memory, dctx, option_, "default");
  521. auto attrs = getTorrentAttrs(dctx);
  522. CPPUNIT_ASSERT_EQUAL((size_t)2, attrs->nodes.size());
  523. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), attrs->nodes[0].first);
  524. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, attrs->nodes[0].second);
  525. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), attrs->nodes[1].first);
  526. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, attrs->nodes[1].second);
  527. }
  528. {
  529. // empty hostname
  530. std::string memory = "d5:nodesl"
  531. "l1: i6881ee"
  532. "l11:192.168.0.2i6882ee"
  533. "e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  534. "12:piece lengthi262144e"
  535. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  536. "ee";
  537. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  538. loadFromMemory(memory, dctx, option_, "default");
  539. auto attrs = getTorrentAttrs(dctx);
  540. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->nodes.size());
  541. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), attrs->nodes[0].first);
  542. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, attrs->nodes[0].second);
  543. }
  544. {
  545. // bad port
  546. std::string memory = "d5:nodesl"
  547. "l11:192.168.0.11:xe"
  548. "l11:192.168.0.2i6882ee"
  549. "e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  550. "12:piece lengthi262144e"
  551. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  552. "ee";
  553. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  554. loadFromMemory(memory, dctx, option_, "default");
  555. auto attrs = getTorrentAttrs(dctx);
  556. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->nodes.size());
  557. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), attrs->nodes[0].first);
  558. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, attrs->nodes[0].second);
  559. }
  560. {
  561. // port missing
  562. std::string memory = "d5:nodesl"
  563. "l11:192.168.0.1e"
  564. "l11:192.168.0.2i6882ee"
  565. "e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  566. "12:piece lengthi262144e"
  567. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  568. "ee";
  569. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  570. loadFromMemory(memory, dctx, option_, "default");
  571. auto attrs = getTorrentAttrs(dctx);
  572. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->nodes.size());
  573. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), attrs->nodes[0].first);
  574. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, attrs->nodes[0].second);
  575. }
  576. {
  577. // nodes is not a list
  578. std::string memory = "d5:nodes"
  579. "l11:192.168.0.1e"
  580. "4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  581. "12:piece lengthi262144e"
  582. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  583. "ee";
  584. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  585. loadFromMemory(memory, dctx, option_, "default");
  586. auto attrs = getTorrentAttrs(dctx);
  587. CPPUNIT_ASSERT_EQUAL((size_t)0, attrs->nodes.size());
  588. }
  589. {
  590. // the element of node is not Data
  591. std::string memory = "d5:nodesl"
  592. "ll11:192.168.0.1i6881eee"
  593. "l11:192.168.0.2i6882ee"
  594. "e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  595. "12:piece lengthi262144e"
  596. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  597. "ee";
  598. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  599. loadFromMemory(memory, dctx, option_, "default");
  600. auto attrs = getTorrentAttrs(dctx);
  601. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->nodes.size());
  602. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), attrs->nodes[0].first);
  603. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, attrs->nodes[0].second);
  604. }
  605. }
  606. void BittorrentHelperTest::testGetBasePath()
  607. {
  608. std::shared_ptr<DownloadContext> singleCtx(new DownloadContext());
  609. load(A2_TEST_DIR "/single.torrent", singleCtx, option_);
  610. singleCtx->setFilePathWithIndex(1, "new-path");
  611. CPPUNIT_ASSERT_EQUAL(std::string("new-path"), singleCtx->getBasePath());
  612. option_->put(PREF_DIR, "downloads");
  613. std::shared_ptr<DownloadContext> multiCtx(new DownloadContext());
  614. load(A2_TEST_DIR "/test.torrent", multiCtx, option_);
  615. CPPUNIT_ASSERT_EQUAL(std::string("downloads/aria2-test"),
  616. multiCtx->getBasePath());
  617. }
  618. void BittorrentHelperTest::testSetFileFilter_single()
  619. {
  620. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  621. load(A2_TEST_DIR "/single.torrent", dctx, option_);
  622. CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
  623. dctx->setFileFilter(SegList<int>());
  624. CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
  625. dctx->setFileFilter(util::parseIntSegments("1,2"));
  626. CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
  627. // For single file torrent, file is always selected whatever range
  628. // is passed.
  629. dctx->setFileFilter(util::parseIntSegments("2,3"));
  630. CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
  631. }
  632. void BittorrentHelperTest::testSetFileFilter_multi()
  633. {
  634. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  635. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  636. CPPUNIT_ASSERT(dctx->getFileEntries()[0]->isRequested());
  637. CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
  638. dctx->setFileFilter(SegList<int>());
  639. CPPUNIT_ASSERT(dctx->getFileEntries()[0]->isRequested());
  640. CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
  641. dctx->setFileFilter(util::parseIntSegments("2,3"));
  642. CPPUNIT_ASSERT(!dctx->getFileEntries()[0]->isRequested());
  643. CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
  644. dctx->setFileFilter(util::parseIntSegments("3,4"));
  645. CPPUNIT_ASSERT(!dctx->getFileEntries()[0]->isRequested());
  646. CPPUNIT_ASSERT(!dctx->getFileEntries()[1]->isRequested());
  647. dctx->setFileFilter(util::parseIntSegments("1,2"));
  648. CPPUNIT_ASSERT(dctx->getFileEntries()[0]->isRequested());
  649. CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
  650. }
  651. void BittorrentHelperTest::testUTF8Torrent()
  652. {
  653. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  654. load(A2_TEST_DIR "/utf8.torrent", dctx, option_);
  655. CPPUNIT_ASSERT_EQUAL(std::string("name in utf-8"),
  656. getTorrentAttrs(dctx)->name);
  657. CPPUNIT_ASSERT_EQUAL(std::string("./name in utf-8/path in utf-8"),
  658. dctx->getFirstFileEntry()->getPath());
  659. CPPUNIT_ASSERT_EQUAL(std::string("This is utf8 comment."),
  660. getTorrentAttrs(dctx)->comment);
  661. }
  662. void BittorrentHelperTest::testEtc()
  663. {
  664. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  665. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  666. CPPUNIT_ASSERT_EQUAL(std::string("REDNOAH.COM RULES"),
  667. getTorrentAttrs(dctx)->comment);
  668. CPPUNIT_ASSERT_EQUAL(std::string("aria2"), getTorrentAttrs(dctx)->createdBy);
  669. CPPUNIT_ASSERT_EQUAL((time_t)1123456789, getTorrentAttrs(dctx)->creationDate);
  670. }
  671. void BittorrentHelperTest::testCheckBitfield()
  672. {
  673. unsigned char bitfield[] = {0xff, 0xe0};
  674. checkBitfield(bitfield, sizeof(bitfield), 11);
  675. try {
  676. checkBitfield(bitfield, sizeof(bitfield), 17);
  677. CPPUNIT_FAIL("exception must be thrown.");
  678. }
  679. catch (RecoverableException& e) {
  680. // success
  681. }
  682. // Change last byte
  683. bitfield[1] = 0xf0;
  684. try {
  685. checkBitfield(bitfield, sizeof(bitfield), 11);
  686. CPPUNIT_FAIL("exception must be thrown.");
  687. }
  688. catch (RecoverableException& e) {
  689. // success
  690. }
  691. }
  692. void BittorrentHelperTest::testMetadata()
  693. {
  694. auto dctx = std::make_shared<DownloadContext>();
  695. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  696. std::string torrentData = readFile(A2_TEST_DIR "/test.torrent");
  697. auto tr = bencode2::decode(torrentData);
  698. auto infoDic = downcast<Dict>(tr)->get("info");
  699. std::string metadata = bencode2::encode(infoDic);
  700. auto attrs = getTorrentAttrs(dctx);
  701. CPPUNIT_ASSERT(metadata == attrs->metadata);
  702. CPPUNIT_ASSERT_EQUAL(metadata.size(), attrs->metadataSize);
  703. }
  704. void BittorrentHelperTest::testParseMagnet()
  705. {
  706. std::string magnet =
  707. "magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c&dn=aria2"
  708. "&tr=http://tracker1&tr=http://tracker2";
  709. auto attrs = bittorrent::parseMagnet(magnet);
  710. CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  711. util::toHex(attrs->infoHash));
  712. CPPUNIT_ASSERT_EQUAL(std::string("[METADATA]aria2"), attrs->name);
  713. CPPUNIT_ASSERT_EQUAL((size_t)2, attrs->announceList.size());
  714. CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"),
  715. attrs->announceList[0][0]);
  716. CPPUNIT_ASSERT_EQUAL(std::string("http://tracker2"),
  717. attrs->announceList[1][0]);
  718. magnet = "magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c";
  719. attrs = bittorrent::parseMagnet(magnet);
  720. CPPUNIT_ASSERT_EQUAL(
  721. std::string("[METADATA]248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  722. attrs->name);
  723. CPPUNIT_ASSERT(attrs->announceList.empty());
  724. magnet = "magnet:?xt=urn:sha1:7899bdb90a026c746f3cbc10839dd9b2a2a3e985&"
  725. "xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c";
  726. attrs = bittorrent::parseMagnet(magnet);
  727. CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  728. util::toHex(attrs->infoHash));
  729. }
  730. void BittorrentHelperTest::testParseMagnet_base32()
  731. {
  732. std::string infoHash = "248d0a1cd08284299de78d5c1ed359bb46717d8c";
  733. std::string base32InfoHash = base32::encode(fromHex(infoHash));
  734. std::string magnet = "magnet:?xt=urn:btih:" + base32InfoHash + "&dn=aria2";
  735. auto attrs = bittorrent::parseMagnet(magnet);
  736. CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  737. util::toHex(attrs->infoHash));
  738. }
  739. void BittorrentHelperTest::testMetadata2Torrent()
  740. {
  741. TorrentAttribute attrs;
  742. std::string metadata = "METADATA";
  743. CPPUNIT_ASSERT_EQUAL(std::string("d4:infoMETADATAe"),
  744. metadata2Torrent(metadata, &attrs));
  745. attrs.announceList.push_back(std::vector<std::string>());
  746. attrs.announceList[0].push_back("http://localhost/announce");
  747. CPPUNIT_ASSERT_EQUAL(std::string("d"
  748. "13:announce-list"
  749. "ll25:http://localhost/announceee"
  750. "4:infoMETADATA"
  751. "e"),
  752. metadata2Torrent(metadata, &attrs));
  753. }
  754. void BittorrentHelperTest::testTorrent2Magnet()
  755. {
  756. std::shared_ptr<DownloadContext> dctx(new DownloadContext());
  757. load(A2_TEST_DIR "/test.torrent", dctx, option_);
  758. CPPUNIT_ASSERT_EQUAL(
  759. std::string("magnet:?xt=urn:btih:248D0A1CD08284299DE78D5C1ED359BB46717D8C"
  760. "&dn=aria2-test"
  761. "&tr=http%3A%2F%2Ftracker1"
  762. "&tr=http%3A%2F%2Ftracker2"
  763. "&tr=http%3A%2F%2Ftracker3"),
  764. torrent2Magnet(getTorrentAttrs(dctx)));
  765. }
  766. void BittorrentHelperTest::testExtractPeerFromString()
  767. {
  768. std::string hextext = "100210354527354678541237324732171ae1";
  769. hextext += "20010db8bd0501d2288a1fc0000110ee1ae2";
  770. std::string peersstr = "36:" + fromHex(hextext);
  771. auto str = bencode2::decode(peersstr);
  772. std::deque<std::shared_ptr<Peer>> peers;
  773. extractPeer(str.get(), AF_INET6, std::back_inserter(peers));
  774. CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
  775. CPPUNIT_ASSERT_EQUAL(std::string("1002:1035:4527:3546:7854:1237:3247:3217"),
  776. peers[0]->getIPAddress());
  777. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peers[0]->getPort());
  778. CPPUNIT_ASSERT_EQUAL(std::string("2001:db8:bd05:1d2:288a:1fc0:1:10ee"),
  779. peers[1]->getIPAddress());
  780. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, peers[1]->getPort());
  781. hextext = "c0a800011ae1";
  782. hextext += "c0a800021ae2";
  783. peersstr = "12:" + fromHex(hextext);
  784. str = bencode2::decode(peersstr);
  785. peers.clear();
  786. extractPeer(str.get(), AF_INET, std::back_inserter(peers));
  787. CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
  788. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peers[0]->getIPAddress());
  789. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peers[0]->getPort());
  790. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), peers[1]->getIPAddress());
  791. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, peers[1]->getPort());
  792. }
  793. void BittorrentHelperTest::testExtractPeerFromList()
  794. {
  795. std::string peersString =
  796. "d5:peersld2:ip11:192.168.0.17:peer id20:aria2-00000000000000"
  797. "4:porti2006eeee";
  798. auto dict = bencode2::decode(peersString);
  799. std::deque<std::shared_ptr<Peer>> peers;
  800. extractPeer(downcast<Dict>(dict)->get("peers"), AF_INET,
  801. std::back_inserter(peers));
  802. CPPUNIT_ASSERT_EQUAL((size_t)1, peers.size());
  803. auto& peer = *peers.begin();
  804. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
  805. CPPUNIT_ASSERT_EQUAL((uint16_t)2006, peer->getPort());
  806. }
  807. void BittorrentHelperTest::testExtract2PeersFromList()
  808. {
  809. std::string peersString =
  810. "d5:peersld2:ip11:192.168.0.17:peer id20:aria2-00000000000000"
  811. "4:porti65535eed2:ip11:192.168.0.27:peer id20:aria2-00000000000000"
  812. "4:porti2007eeee";
  813. auto dict = bencode2::decode(peersString);
  814. std::deque<std::shared_ptr<Peer>> peers;
  815. extractPeer(downcast<Dict>(dict)->get("peers"), AF_INET,
  816. std::back_inserter(peers));
  817. CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
  818. auto& peer = *peers.begin();
  819. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
  820. CPPUNIT_ASSERT_EQUAL((uint16_t)65535, peer->getPort());
  821. peer = *(peers.begin() + 1);
  822. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), peer->getIPAddress());
  823. CPPUNIT_ASSERT_EQUAL((uint16_t)2007, peer->getPort());
  824. }
  825. void BittorrentHelperTest::testPackcompact()
  826. {
  827. unsigned char compact[COMPACT_LEN_IPV6];
  828. CPPUNIT_ASSERT_EQUAL(
  829. (size_t)18,
  830. packcompact(compact, "1002:1035:4527:3546:7854:1237:3247:3217", 6881));
  831. CPPUNIT_ASSERT_EQUAL(std::string("100210354527354678541237324732171ae1"),
  832. util::toHex(compact, 18));
  833. CPPUNIT_ASSERT_EQUAL((size_t)6, packcompact(compact, "192.168.0.1", 6881));
  834. CPPUNIT_ASSERT_EQUAL(std::string("c0a800011ae1"), util::toHex(compact, 6));
  835. CPPUNIT_ASSERT_EQUAL((size_t)0, packcompact(compact, "badaddr", 6881));
  836. }
  837. void BittorrentHelperTest::testUnpackcompact()
  838. {
  839. unsigned char compact6[] = {0x10, 0x02, 0x10, 0x35, 0x45, 0x27,
  840. 0x35, 0x46, 0x78, 0x54, 0x12, 0x37,
  841. 0x32, 0x47, 0x32, 0x17, 0x1A, 0xE1};
  842. std::pair<std::string, uint16_t> p = unpackcompact(compact6, AF_INET6);
  843. CPPUNIT_ASSERT_EQUAL(std::string("1002:1035:4527:3546:7854:1237:3247:3217"),
  844. p.first);
  845. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, p.second);
  846. unsigned char compact[] = {0xC0, 0xa8, 0x00, 0x01, 0x1A, 0xE1};
  847. p = unpackcompact(compact, AF_INET);
  848. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), p.first);
  849. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, p.second);
  850. }
  851. void BittorrentHelperTest::testRemoveAnnounceUri()
  852. {
  853. TorrentAttribute attrs;
  854. std::vector<std::string> tier1;
  855. tier1.push_back("http://host1/announce");
  856. std::vector<std::string> tier2;
  857. tier2.push_back("http://host2/announce");
  858. tier2.push_back("http://host3/announce");
  859. attrs.announceList.push_back(tier1);
  860. attrs.announceList.push_back(tier2);
  861. std::vector<std::string> removeUris;
  862. removeUris.push_back(tier1[0]);
  863. removeUris.push_back(tier2[0]);
  864. removeAnnounceUri(&attrs, removeUris);
  865. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs.announceList.size());
  866. CPPUNIT_ASSERT_EQUAL(std::string("http://host3/announce"),
  867. attrs.announceList[0][0]);
  868. removeUris.clear();
  869. removeUris.push_back("*");
  870. removeAnnounceUri(&attrs, removeUris);
  871. CPPUNIT_ASSERT(attrs.announceList.empty());
  872. }
  873. void BittorrentHelperTest::testAddAnnounceUri()
  874. {
  875. TorrentAttribute attrs;
  876. std::vector<std::string> addUris;
  877. addUris.push_back("http://host1/announce");
  878. addUris.push_back("http://host2/announce");
  879. addAnnounceUri(&attrs, addUris);
  880. CPPUNIT_ASSERT_EQUAL((size_t)2, attrs.announceList.size());
  881. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs.announceList[0].size());
  882. CPPUNIT_ASSERT_EQUAL(std::string("http://host1/announce"),
  883. attrs.announceList[0][0]);
  884. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs.announceList[1].size());
  885. CPPUNIT_ASSERT_EQUAL(std::string("http://host2/announce"),
  886. attrs.announceList[1][0]);
  887. }
  888. void BittorrentHelperTest::testAdjustAnnounceUri()
  889. {
  890. TorrentAttribute attrs;
  891. std::vector<std::string> tier1;
  892. tier1.push_back("http://host1/announce");
  893. std::vector<std::string> tier2;
  894. tier2.push_back("http://host2/announce");
  895. tier2.push_back("http://host3/announce");
  896. attrs.announceList.push_back(tier1);
  897. attrs.announceList.push_back(tier2);
  898. std::shared_ptr<Option> option(new Option());
  899. option->put(PREF_BT_TRACKER, "http://host1/announce,http://host4/announce");
  900. option->put(PREF_BT_EXCLUDE_TRACKER,
  901. "http://host1/announce,http://host2/announce");
  902. adjustAnnounceUri(&attrs, option);
  903. CPPUNIT_ASSERT_EQUAL((size_t)3, attrs.announceList.size());
  904. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs.announceList[0].size());
  905. CPPUNIT_ASSERT_EQUAL(std::string("http://host3/announce"),
  906. attrs.announceList[0][0]);
  907. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs.announceList[1].size());
  908. CPPUNIT_ASSERT_EQUAL(std::string("http://host1/announce"),
  909. attrs.announceList[1][0]);
  910. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs.announceList[2].size());
  911. CPPUNIT_ASSERT_EQUAL(std::string("http://host4/announce"),
  912. attrs.announceList[2][0]);
  913. }
  914. } // namespace bittorrent
  915. } // namespace aria2