BittorrentHelperTest.cc 37 KB

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