BittorrentHelperTest.cc 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  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. SharedHandle<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. SharedHandle<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. SharedHandle<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. SharedHandle<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<SharedHandle<FileEntry> > fileEntries = dctx->getFileEntries();
  151. // There are 2 file entries.
  152. CPPUNIT_ASSERT_EQUAL((size_t)2, fileEntries.size());
  153. std::vector<SharedHandle<FileEntry> >::iterator itr = fileEntries.begin();
  154. SharedHandle<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. SharedHandle<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. SharedHandle<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<SharedHandle<FileEntry> > fileEntries = dctx->getFileEntries();
  172. // There is 1 file entry.
  173. CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries.size());
  174. std::vector<SharedHandle<FileEntry> >::iterator itr = fileEntries.begin();
  175. SharedHandle<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. SharedHandle<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. SharedHandle<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. SharedHandle<DownloadContext> dctx(new DownloadContext());
  194. load(A2_TEST_DIR"/test.torrent", dctx, option_);
  195. CPPUNIT_ASSERT_EQUAL(MULTI, getTorrentAttrs(dctx)->mode);
  196. }
  197. void BittorrentHelperTest::testGetFileModeSingle() {
  198. SharedHandle<DownloadContext> dctx(new DownloadContext());
  199. load(A2_TEST_DIR"/single.torrent", dctx, option_);
  200. CPPUNIT_ASSERT_EQUAL(SINGLE, getTorrentAttrs(dctx)->mode);
  201. }
  202. void BittorrentHelperTest::testGetNameMulti() {
  203. SharedHandle<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. SharedHandle<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. SharedHandle<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. SharedHandle<DownloadContext> dctx(new DownloadContext());
  226. load(A2_TEST_DIR"/single.torrent", dctx, option_);
  227. SharedHandle<TorrentAttribute> 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. SharedHandle<DownloadContext> dctx(new DownloadContext());
  236. load(A2_TEST_DIR"/test.torrent", dctx, option_);
  237. SharedHandle<TorrentAttribute> 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. SharedHandle<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. SharedHandle<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. std::vector<size_t> ansSet(vbegin(ans), vend(ans));
  279. CPPUNIT_ASSERT(std::equal(fastSet.begin(), fastSet.end(), ansSet.begin()));
  280. }
  281. ipaddr = "10.0.0.1";
  282. {
  283. std::vector<size_t> fastSet;
  284. computeFastSet(fastSet, ipaddr, numPieces, infoHash, fastSetSize);
  285. size_t ans[] = { 568, 188, 466, 452, 550, 662, 109, 226, 398, 11 };
  286. std::vector<size_t> ansSet(vbegin(ans), vend(ans));
  287. CPPUNIT_ASSERT(std::equal(fastSet.begin(), fastSet.end(), ansSet.begin()));
  288. }
  289. // See when pieces < fastSetSize
  290. numPieces = 9;
  291. {
  292. std::vector<size_t> fastSet;
  293. computeFastSet(fastSet, ipaddr, numPieces, infoHash, fastSetSize);
  294. size_t ans[] = { 8, 6, 7, 5, 1, 4, 0, 2, 3 };
  295. std::vector<size_t> ansSet(vbegin(ans), vend(ans));
  296. CPPUNIT_ASSERT(std::equal(fastSet.begin(), fastSet.end(), ansSet.begin()));
  297. }
  298. }
  299. void BittorrentHelperTest::testGetFileEntries_multiFileUrlList() {
  300. SharedHandle<DownloadContext> dctx(new DownloadContext());
  301. load(A2_TEST_DIR"/url-list-multiFile.torrent", dctx, option_);
  302. // This is multi-file torrent.
  303. const std::vector<SharedHandle<FileEntry> >& fileEntries =
  304. dctx->getFileEntries();
  305. // There are 2 file entries.
  306. CPPUNIT_ASSERT_EQUAL((size_t)2, fileEntries.size());
  307. std::vector<SharedHandle<FileEntry> >::const_iterator itr =
  308. fileEntries.begin();
  309. const SharedHandle<FileEntry>& fileEntry1 = *itr;
  310. CPPUNIT_ASSERT_EQUAL(std::string("./aria2-test@/aria2@/src@/aria2c@"),
  311. fileEntry1->getPath());
  312. const std::deque<std::string>& uris1 = fileEntry1->getRemainingUris();
  313. CPPUNIT_ASSERT_EQUAL((size_t)2, uris1.size());
  314. CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/dist/aria2-test%40/aria2%40/src%40/aria2c%40"),
  315. uris1[0]);
  316. CPPUNIT_ASSERT_EQUAL(std::string("http://mirror/dist/aria2-test%40/aria2%40/src%40/aria2c%40"),
  317. uris1[1]);
  318. ++itr;
  319. const SharedHandle<FileEntry>& fileEntry2 = *itr;
  320. CPPUNIT_ASSERT_EQUAL(std::string("./aria2-test@/aria2-0.2.2.tar.bz2"),
  321. fileEntry2->getPath());
  322. const std::deque<std::string>& uris2 = fileEntry2->getRemainingUris();
  323. CPPUNIT_ASSERT_EQUAL((size_t)2, uris2.size());
  324. CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/dist/aria2-test%40/aria2-0.2.2.tar.bz2"),
  325. uris2[0]);
  326. CPPUNIT_ASSERT_EQUAL(std::string("http://mirror/dist/aria2-test%40/aria2-0.2.2.tar.bz2"),
  327. uris2[1]);
  328. }
  329. void BittorrentHelperTest::testGetFileEntries_singleFileUrlList() {
  330. SharedHandle<DownloadContext> dctx(new DownloadContext());
  331. load(A2_TEST_DIR"/url-list-singleFile.torrent", dctx, option_);
  332. // This is single-file torrent.
  333. const std::vector<SharedHandle<FileEntry> >& fileEntries =
  334. dctx->getFileEntries();
  335. // There are 1 file entries.
  336. CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries.size());
  337. const SharedHandle<FileEntry>& fileEntry1 = fileEntries.front();
  338. CPPUNIT_ASSERT_EQUAL(std::string("./aria2.tar.bz2"),
  339. fileEntry1->getPath());
  340. const std::deque<std::string>& uris1 = fileEntry1->getRemainingUris();
  341. CPPUNIT_ASSERT_EQUAL((size_t)1, uris1.size());
  342. CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/dist/aria2.tar.bz2"),
  343. uris1[0]);
  344. }
  345. void BittorrentHelperTest::testGetFileEntries_singleFileUrlListEndsWithSlash() {
  346. SharedHandle<DownloadContext> dctx(new DownloadContext());
  347. load(A2_TEST_DIR"/url-list-singleFileEndsWithSlash.torrent", dctx, option_);
  348. // This is single-file torrent.
  349. const std::vector<SharedHandle<FileEntry> >& fileEntries =
  350. dctx->getFileEntries();
  351. // There are 1 file entries.
  352. CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries.size());
  353. const SharedHandle<FileEntry>& fileEntry1 = fileEntries.front();
  354. CPPUNIT_ASSERT_EQUAL(std::string("./aria2@.tar.bz2"),
  355. fileEntry1->getPath());
  356. const std::deque<std::string>& uris1 = fileEntry1->getRemainingUris();
  357. CPPUNIT_ASSERT_EQUAL((size_t)1, uris1.size());
  358. CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/dist/aria2%40.tar.bz2"),
  359. uris1[0]);
  360. }
  361. void BittorrentHelperTest::testLoadFromMemory_multiFileNonUtf8Path()
  362. {
  363. SharedHandle<List> path = List::g();
  364. path->append("path");
  365. path->append(fromHex("90a28a")+"E");
  366. SharedHandle<Dict> file = Dict::g();
  367. file->put("length", Integer::g(1024));
  368. file->put("path", path);
  369. SharedHandle<List> files = List::g();
  370. files->append(file);
  371. SharedHandle<Dict> info = Dict::g();
  372. info->put("files", files);
  373. info->put("piece length", Integer::g(1024));
  374. info->put("pieces", "01234567890123456789");
  375. info->put("name", fromHex("1b")+"$B%O%m!<"+fromHex("1b")+"(B");
  376. Dict dict;
  377. dict.put("info", info);
  378. SharedHandle<DownloadContext> dctx(new DownloadContext());
  379. loadFromMemory(bencode2::encode(&dict), dctx, option_, "default");
  380. const SharedHandle<FileEntry>& fe = dctx->getFirstFileEntry();
  381. CPPUNIT_ASSERT_EQUAL
  382. (std::string("./%1B%24B%25O%25m%21%3C%1B%28B/path/%90%A2%8AE"),
  383. fe->getPath());
  384. CPPUNIT_ASSERT_EQUAL
  385. (std::string("./%1B%24B%25O%25m%21%3C%1B%28B"), dctx->getBasePath());
  386. }
  387. void BittorrentHelperTest::testLoadFromMemory_singleFileNonUtf8Path()
  388. {
  389. SharedHandle<Dict> info = Dict::g();
  390. info->put("piece length", Integer::g(1024));
  391. info->put("pieces", "01234567890123456789");
  392. info->put("name", fromHex("90a28a")+"E");
  393. info->put("length", Integer::g(1024));
  394. Dict dict;
  395. dict.put("info", info);
  396. SharedHandle<DownloadContext> dctx(new DownloadContext());
  397. loadFromMemory(bencode2::encode(&dict), dctx, option_, "default");
  398. const SharedHandle<FileEntry>& fe = dctx->getFirstFileEntry();
  399. CPPUNIT_ASSERT_EQUAL(std::string("./%90%A2%8AE"), fe->getPath());
  400. }
  401. void BittorrentHelperTest::testLoadFromMemory()
  402. {
  403. 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";
  404. SharedHandle<DownloadContext> dctx(new DownloadContext());
  405. loadFromMemory(memory, dctx, option_, "default");
  406. std::string correctHash = "248d0a1cd08284299de78d5c1ed359bb46717d8c";
  407. CPPUNIT_ASSERT_EQUAL(correctHash, getInfoHashString(dctx));
  408. }
  409. void BittorrentHelperTest::testLoadFromMemory_somethingMissing()
  410. {
  411. // pieces missing
  412. try {
  413. std::string memory = "d8:announce36:http://aria.rednoah.com/announce.php4:infod4:name13:aria2.tar.bz26:lengthi262144eee";
  414. SharedHandle<DownloadContext> dctx(new DownloadContext());
  415. loadFromMemory(memory, dctx, option_, "default");
  416. CPPUNIT_FAIL("exception must be thrown.");
  417. } catch(Exception& e) {
  418. // OK
  419. }
  420. }
  421. void BittorrentHelperTest::testLoadFromMemory_overrideName()
  422. {
  423. 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";
  424. SharedHandle<DownloadContext> dctx(new DownloadContext());
  425. loadFromMemory(memory, dctx, option_, "default", "aria2-override.name");
  426. CPPUNIT_ASSERT_EQUAL(std::string("aria2-override.name"),
  427. getTorrentAttrs(dctx)->name);
  428. }
  429. void BittorrentHelperTest::testLoadFromMemory_multiFileDirTraversal()
  430. {
  431. std::string memory =
  432. "d8:announce27:http://example.com/announce4:infod5:filesld6:lengthi262144e4:pathl7:../dir14:dir28:file.imgeee4:name14:../name1/name212:piece lengthi262144e6:pieces20:00000000000000000000ee";
  433. SharedHandle<DownloadContext> dctx(new DownloadContext());
  434. try {
  435. loadFromMemory(memory, dctx, option_, "default");
  436. CPPUNIT_FAIL("Exception must be thrown.");
  437. } catch(RecoverableException& e) {
  438. // success
  439. }
  440. }
  441. void BittorrentHelperTest::testLoadFromMemory_singleFileDirTraversal()
  442. {
  443. std::string memory =
  444. "d8:announce27:http://example.com/announce4:infod4:name14:../name1/name26:lengthi262144e12:piece lengthi262144e6:pieces20:00000000000000000000ee";
  445. SharedHandle<DownloadContext> dctx(new DownloadContext());
  446. try {
  447. loadFromMemory(memory, dctx, option_, "default");
  448. } catch(RecoverableException& e) {
  449. // success
  450. }
  451. }
  452. void BittorrentHelperTest::testGetNodes()
  453. {
  454. {
  455. std::string memory =
  456. "d5:nodesl"
  457. "l11:192.168.0.1i6881ee"
  458. "l11:192.168.0.2i6882ee"
  459. "e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  460. "12:piece lengthi262144e"
  461. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  462. "ee";
  463. SharedHandle<DownloadContext> dctx(new DownloadContext());
  464. loadFromMemory(memory, dctx, option_, "default");
  465. SharedHandle<TorrentAttribute> attrs = getTorrentAttrs(dctx);
  466. CPPUNIT_ASSERT_EQUAL((size_t)2, attrs->nodes.size());
  467. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), attrs->nodes[0].first);
  468. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, attrs->nodes[0].second);
  469. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), attrs->nodes[1].first);
  470. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, attrs->nodes[1].second);
  471. }
  472. {
  473. // empty hostname
  474. std::string memory =
  475. "d5:nodesl"
  476. "l1: i6881ee"
  477. "l11:192.168.0.2i6882ee"
  478. "e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  479. "12:piece lengthi262144e"
  480. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  481. "ee";
  482. SharedHandle<DownloadContext> dctx(new DownloadContext());
  483. loadFromMemory(memory, dctx, option_, "default");
  484. SharedHandle<TorrentAttribute> attrs = getTorrentAttrs(dctx);
  485. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->nodes.size());
  486. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), attrs->nodes[0].first);
  487. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, attrs->nodes[0].second);
  488. }
  489. {
  490. // bad port
  491. std::string memory =
  492. "d5:nodesl"
  493. "l11:192.168.0.11:xe"
  494. "l11:192.168.0.2i6882ee"
  495. "e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  496. "12:piece lengthi262144e"
  497. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  498. "ee";
  499. SharedHandle<DownloadContext> dctx(new DownloadContext());
  500. loadFromMemory(memory, dctx, option_, "default");
  501. SharedHandle<TorrentAttribute> attrs = getTorrentAttrs(dctx);
  502. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->nodes.size());
  503. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), attrs->nodes[0].first);
  504. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, attrs->nodes[0].second);
  505. }
  506. {
  507. // port missing
  508. std::string memory =
  509. "d5:nodesl"
  510. "l11:192.168.0.1e"
  511. "l11:192.168.0.2i6882ee"
  512. "e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  513. "12:piece lengthi262144e"
  514. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  515. "ee";
  516. SharedHandle<DownloadContext> dctx(new DownloadContext());
  517. loadFromMemory(memory, dctx, option_, "default");
  518. SharedHandle<TorrentAttribute> attrs = getTorrentAttrs(dctx);
  519. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->nodes.size());
  520. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), attrs->nodes[0].first);
  521. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, attrs->nodes[0].second);
  522. }
  523. {
  524. // nodes is not a list
  525. std::string memory =
  526. "d5:nodes"
  527. "l11:192.168.0.1e"
  528. "4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  529. "12:piece lengthi262144e"
  530. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  531. "ee";
  532. SharedHandle<DownloadContext> dctx(new DownloadContext());
  533. loadFromMemory(memory, dctx, option_, "default");
  534. SharedHandle<TorrentAttribute> attrs = getTorrentAttrs(dctx);
  535. CPPUNIT_ASSERT_EQUAL((size_t)0, attrs->nodes.size());
  536. }
  537. {
  538. // the element of node is not Data
  539. std::string memory =
  540. "d5:nodesl"
  541. "ll11:192.168.0.1i6881eee"
  542. "l11:192.168.0.2i6882ee"
  543. "e4:infod4:name13:aria2.tar.bz26:lengthi262144e"
  544. "12:piece lengthi262144e"
  545. "6:pieces20:AAAAAAAAAAAAAAAAAAAA"
  546. "ee";
  547. SharedHandle<DownloadContext> dctx(new DownloadContext());
  548. loadFromMemory(memory, dctx, option_, "default");
  549. SharedHandle<TorrentAttribute> attrs = getTorrentAttrs(dctx);
  550. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->nodes.size());
  551. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), attrs->nodes[0].first);
  552. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, attrs->nodes[0].second);
  553. }
  554. }
  555. void BittorrentHelperTest::testGetBasePath()
  556. {
  557. SharedHandle<DownloadContext> singleCtx(new DownloadContext());
  558. load(A2_TEST_DIR"/single.torrent", singleCtx, option_);
  559. singleCtx->setFilePathWithIndex(1, "new-path");
  560. CPPUNIT_ASSERT_EQUAL(std::string("new-path"), singleCtx->getBasePath());
  561. option_->put(PREF_DIR, "downloads");
  562. SharedHandle<DownloadContext> multiCtx(new DownloadContext());
  563. load(A2_TEST_DIR"/test.torrent", multiCtx, option_);
  564. CPPUNIT_ASSERT_EQUAL(std::string("downloads/aria2-test"),
  565. multiCtx->getBasePath());
  566. }
  567. void BittorrentHelperTest::testSetFileFilter_single()
  568. {
  569. SharedHandle<DownloadContext> dctx(new DownloadContext());
  570. load(A2_TEST_DIR"/single.torrent", dctx, option_);
  571. CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
  572. SegList<int> sgl;
  573. dctx->setFileFilter(sgl);
  574. CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
  575. sgl.clear();
  576. sgl.add(1, 2);
  577. dctx->setFileFilter(sgl);
  578. CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
  579. // For single file torrent, file is always selected whatever range
  580. // is passed.
  581. sgl.clear();
  582. sgl.add(2, 3);
  583. dctx->setFileFilter(sgl);
  584. CPPUNIT_ASSERT(dctx->getFirstFileEntry()->isRequested());
  585. }
  586. void BittorrentHelperTest::testSetFileFilter_multi()
  587. {
  588. SharedHandle<DownloadContext> dctx(new DownloadContext());
  589. load(A2_TEST_DIR"/test.torrent", dctx, option_);
  590. CPPUNIT_ASSERT(dctx->getFileEntries()[0]->isRequested());
  591. CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
  592. SegList<int> sgl;
  593. dctx->setFileFilter(sgl);
  594. CPPUNIT_ASSERT(dctx->getFileEntries()[0]->isRequested());
  595. CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
  596. sgl.add(2, 3);
  597. dctx->setFileFilter(sgl);
  598. CPPUNIT_ASSERT(!dctx->getFileEntries()[0]->isRequested());
  599. CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
  600. sgl.clear();
  601. sgl.add(3, 4);
  602. dctx->setFileFilter(sgl);
  603. CPPUNIT_ASSERT(!dctx->getFileEntries()[0]->isRequested());
  604. CPPUNIT_ASSERT(!dctx->getFileEntries()[1]->isRequested());
  605. sgl.clear();
  606. util::parseIntSegments(sgl, "1,2");
  607. dctx->setFileFilter(sgl);
  608. CPPUNIT_ASSERT(dctx->getFileEntries()[0]->isRequested());
  609. CPPUNIT_ASSERT(dctx->getFileEntries()[1]->isRequested());
  610. }
  611. void BittorrentHelperTest::testUTF8Torrent()
  612. {
  613. SharedHandle<DownloadContext> dctx(new DownloadContext());
  614. load(A2_TEST_DIR"/utf8.torrent", dctx, option_);
  615. CPPUNIT_ASSERT_EQUAL(std::string("name in utf-8"),
  616. getTorrentAttrs(dctx)->name);
  617. CPPUNIT_ASSERT_EQUAL(std::string("./name in utf-8/path in utf-8"),
  618. dctx->getFirstFileEntry()->getPath());
  619. CPPUNIT_ASSERT_EQUAL(std::string("This is utf8 comment."),
  620. getTorrentAttrs(dctx)->comment);
  621. }
  622. void BittorrentHelperTest::testEtc()
  623. {
  624. SharedHandle<DownloadContext> dctx(new DownloadContext());
  625. load(A2_TEST_DIR"/test.torrent", dctx, option_);
  626. CPPUNIT_ASSERT_EQUAL(std::string("REDNOAH.COM RULES"),
  627. getTorrentAttrs(dctx)->comment);
  628. CPPUNIT_ASSERT_EQUAL(std::string("aria2"),
  629. getTorrentAttrs(dctx)->createdBy);
  630. CPPUNIT_ASSERT_EQUAL((time_t)1123456789,
  631. getTorrentAttrs(dctx)->creationDate);
  632. }
  633. void BittorrentHelperTest::testCheckBitfield()
  634. {
  635. unsigned char bitfield[] = { 0xff, 0xe0 };
  636. checkBitfield(bitfield, sizeof(bitfield), 11);
  637. try {
  638. checkBitfield(bitfield, sizeof(bitfield), 17);
  639. CPPUNIT_FAIL("exception must be thrown.");
  640. } catch(RecoverableException& e) {
  641. // success
  642. }
  643. // Change last byte
  644. bitfield[1] = 0xf0;
  645. try {
  646. checkBitfield(bitfield, sizeof(bitfield), 11);
  647. CPPUNIT_FAIL("exception must be thrown.");
  648. } catch(RecoverableException& e) {
  649. // success
  650. }
  651. }
  652. void BittorrentHelperTest::testMetadata() {
  653. SharedHandle<DownloadContext> dctx(new DownloadContext());
  654. load(A2_TEST_DIR"/test.torrent", dctx, option_);
  655. std::string torrentData = readFile(A2_TEST_DIR"/test.torrent");
  656. SharedHandle<ValueBase> tr = bencode2::decode(torrentData);
  657. SharedHandle<ValueBase> infoDic = downcast<Dict>(tr)->get("info");
  658. std::string metadata = bencode2::encode(infoDic);
  659. SharedHandle<TorrentAttribute> attrs = getTorrentAttrs(dctx);
  660. CPPUNIT_ASSERT(metadata == attrs->metadata);
  661. CPPUNIT_ASSERT_EQUAL(metadata.size(), attrs->metadataSize);
  662. }
  663. void BittorrentHelperTest::testParseMagnet()
  664. {
  665. std::string magnet =
  666. "magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c&dn=aria2"
  667. "&tr=http://tracker1&tr=http://tracker2";
  668. SharedHandle<TorrentAttribute> attrs = bittorrent::parseMagnet(magnet);
  669. CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  670. util::toHex(attrs->infoHash));
  671. CPPUNIT_ASSERT_EQUAL(std::string("[METADATA]aria2"), attrs->name);
  672. CPPUNIT_ASSERT_EQUAL((size_t)2, attrs->announceList.size());
  673. CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"),
  674. attrs->announceList[0][0]);
  675. CPPUNIT_ASSERT_EQUAL(std::string("http://tracker2"),
  676. attrs->announceList[1][0]);
  677. magnet = "magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c";
  678. attrs = bittorrent::parseMagnet(magnet);
  679. CPPUNIT_ASSERT_EQUAL
  680. (std::string("[METADATA]248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  681. attrs->name);
  682. CPPUNIT_ASSERT(attrs->announceList.empty());
  683. magnet = "magnet:?xt=urn:sha1:7899bdb90a026c746f3cbc10839dd9b2a2a3e985&"
  684. "xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c";
  685. attrs = bittorrent::parseMagnet(magnet);
  686. CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  687. util::toHex(attrs->infoHash));
  688. }
  689. void BittorrentHelperTest::testParseMagnet_base32()
  690. {
  691. std::string infoHash = "248d0a1cd08284299de78d5c1ed359bb46717d8c";
  692. std::string base32InfoHash = base32::encode(fromHex(infoHash));
  693. std::string magnet = "magnet:?xt=urn:btih:"+base32InfoHash+"&dn=aria2";
  694. SharedHandle<TorrentAttribute> attrs = bittorrent::parseMagnet(magnet);
  695. CPPUNIT_ASSERT_EQUAL
  696. (std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  697. util::toHex(attrs->infoHash));
  698. }
  699. void BittorrentHelperTest::testMetadata2Torrent()
  700. {
  701. std::string metadata = "METADATA";
  702. SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());
  703. CPPUNIT_ASSERT_EQUAL
  704. (std::string("d4:infoMETADATAe"), metadata2Torrent(metadata, attrs));
  705. attrs->announceList.push_back(std::vector<std::string>());
  706. attrs->announceList[0].push_back("http://localhost/announce");
  707. CPPUNIT_ASSERT_EQUAL
  708. (std::string("d"
  709. "13:announce-list"
  710. "ll25:http://localhost/announceee"
  711. "4:infoMETADATA"
  712. "e"),
  713. metadata2Torrent(metadata, attrs));
  714. }
  715. void BittorrentHelperTest::testTorrent2Magnet()
  716. {
  717. SharedHandle<DownloadContext> dctx(new DownloadContext());
  718. load(A2_TEST_DIR"/test.torrent", dctx, option_);
  719. CPPUNIT_ASSERT_EQUAL
  720. (std::string("magnet:?xt=urn:btih:248D0A1CD08284299DE78D5C1ED359BB46717D8C"
  721. "&dn=aria2-test"
  722. "&tr=http%3A%2F%2Ftracker1"
  723. "&tr=http%3A%2F%2Ftracker2"
  724. "&tr=http%3A%2F%2Ftracker3"),
  725. torrent2Magnet(getTorrentAttrs(dctx)));
  726. }
  727. void BittorrentHelperTest::testExtractPeerFromString()
  728. {
  729. std::string hextext = "100210354527354678541237324732171ae1";
  730. hextext += "20010db8bd0501d2288a1fc0000110ee1ae2";
  731. std::string peersstr = "36:"+fromHex(hextext);
  732. SharedHandle<ValueBase> str = bencode2::decode(peersstr);
  733. std::deque<SharedHandle<Peer> > peers;
  734. extractPeer(str, AF_INET6, std::back_inserter(peers));
  735. CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
  736. CPPUNIT_ASSERT_EQUAL(std::string("1002:1035:4527:3546:7854:1237:3247:3217"),
  737. peers[0]->getIPAddress());
  738. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peers[0]->getPort());
  739. CPPUNIT_ASSERT_EQUAL(std::string("2001:db8:bd05:1d2:288a:1fc0:1:10ee"),
  740. peers[1]->getIPAddress());
  741. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, peers[1]->getPort());
  742. hextext = "c0a800011ae1";
  743. hextext += "c0a800021ae2";
  744. peersstr = "12:"+fromHex(hextext);
  745. str = bencode2::decode(peersstr);
  746. peers.clear();
  747. extractPeer(str, AF_INET, std::back_inserter(peers));
  748. CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
  749. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peers[0]->getIPAddress());
  750. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peers[0]->getPort());
  751. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), peers[1]->getIPAddress());
  752. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, peers[1]->getPort());
  753. }
  754. void BittorrentHelperTest::testExtractPeerFromList()
  755. {
  756. std::string peersString =
  757. "d5:peersld2:ip11:192.168.0.17:peer id20:aria2-00000000000000"
  758. "4:porti2006eeee";
  759. SharedHandle<ValueBase> dict = bencode2::decode(peersString);
  760. std::deque<SharedHandle<Peer> > peers;
  761. extractPeer(downcast<Dict>(dict)->get("peers"), AF_INET, std::back_inserter(peers));
  762. CPPUNIT_ASSERT_EQUAL((size_t)1, peers.size());
  763. SharedHandle<Peer> peer = *peers.begin();
  764. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
  765. CPPUNIT_ASSERT_EQUAL((uint16_t)2006, peer->getPort());
  766. }
  767. void BittorrentHelperTest::testExtract2PeersFromList()
  768. {
  769. std::string peersString =
  770. "d5:peersld2:ip11:192.168.0.17:peer id20:aria2-00000000000000"
  771. "4:porti65535eed2:ip11:192.168.0.27:peer id20:aria2-00000000000000"
  772. "4:porti2007eeee";
  773. SharedHandle<ValueBase> dict = bencode2::decode(peersString);
  774. std::deque<SharedHandle<Peer> > peers;
  775. extractPeer(downcast<Dict>(dict)->get("peers"), AF_INET, std::back_inserter(peers));
  776. CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
  777. SharedHandle<Peer> peer = *peers.begin();
  778. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
  779. CPPUNIT_ASSERT_EQUAL((uint16_t)65535, peer->getPort());
  780. peer = *(peers.begin()+1);
  781. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), peer->getIPAddress());
  782. CPPUNIT_ASSERT_EQUAL((uint16_t)2007, peer->getPort());
  783. }
  784. void BittorrentHelperTest::testPackcompact()
  785. {
  786. unsigned char compact[COMPACT_LEN_IPV6];
  787. CPPUNIT_ASSERT_EQUAL(18,
  788. packcompact(compact,
  789. "1002:1035:4527:3546:7854:1237:3247:3217",
  790. 6881));
  791. CPPUNIT_ASSERT_EQUAL(std::string("100210354527354678541237324732171ae1"),
  792. util::toHex(compact, 18));
  793. CPPUNIT_ASSERT_EQUAL(6, packcompact(compact, "192.168.0.1", 6881));
  794. CPPUNIT_ASSERT_EQUAL(std::string("c0a800011ae1"), util::toHex(compact, 6));
  795. CPPUNIT_ASSERT_EQUAL(0, packcompact(compact, "badaddr", 6881));
  796. }
  797. void BittorrentHelperTest::testUnpackcompact()
  798. {
  799. unsigned char compact6[] = {
  800. 0x10, 0x02, 0x10, 0x35, 0x45, 0x27, 0x35, 0x46,
  801. 0x78, 0x54, 0x12, 0x37, 0x32, 0x47, 0x32, 0x17,
  802. 0x1A, 0xE1 };
  803. std::pair<std::string, uint16_t> p =
  804. unpackcompact(compact6, AF_INET6);
  805. CPPUNIT_ASSERT_EQUAL(std::string("1002:1035:4527:3546:7854:1237:3247:3217"),
  806. p.first);
  807. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, p.second);
  808. unsigned char compact[] = { 0xC0, 0xa8, 0x00, 0x01, 0x1A, 0xE1 };
  809. p = unpackcompact(compact, AF_INET);
  810. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), p.first);
  811. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, p.second);
  812. }
  813. void BittorrentHelperTest::testRemoveAnnounceUri()
  814. {
  815. SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());
  816. std::vector<std::string> tier1;
  817. tier1.push_back("http://host1/announce");
  818. std::vector<std::string> tier2;
  819. tier2.push_back("http://host2/announce");
  820. tier2.push_back("http://host3/announce");
  821. attrs->announceList.push_back(tier1);
  822. attrs->announceList.push_back(tier2);
  823. std::vector<std::string> removeUris;
  824. removeUris.push_back(tier1[0]);
  825. removeUris.push_back(tier2[0]);
  826. removeAnnounceUri(attrs, removeUris);
  827. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList.size());
  828. CPPUNIT_ASSERT_EQUAL(std::string("http://host3/announce"),
  829. attrs->announceList[0][0]);
  830. removeUris.clear();
  831. removeUris.push_back("*");
  832. removeAnnounceUri(attrs, removeUris);
  833. CPPUNIT_ASSERT(attrs->announceList.empty());
  834. }
  835. void BittorrentHelperTest::testAddAnnounceUri()
  836. {
  837. SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());
  838. std::vector<std::string> addUris;
  839. addUris.push_back("http://host1/announce");
  840. addUris.push_back("http://host2/announce");
  841. addAnnounceUri(attrs, addUris);
  842. CPPUNIT_ASSERT_EQUAL((size_t)2, attrs->announceList.size());
  843. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[0].size());
  844. CPPUNIT_ASSERT_EQUAL(std::string("http://host1/announce"),
  845. attrs->announceList[0][0]);
  846. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[1].size());
  847. CPPUNIT_ASSERT_EQUAL(std::string("http://host2/announce"),
  848. attrs->announceList[1][0]);
  849. }
  850. void BittorrentHelperTest::testAdjustAnnounceUri()
  851. {
  852. SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());
  853. std::vector<std::string> tier1;
  854. tier1.push_back("http://host1/announce");
  855. std::vector<std::string> tier2;
  856. tier2.push_back("http://host2/announce");
  857. tier2.push_back("http://host3/announce");
  858. attrs->announceList.push_back(tier1);
  859. attrs->announceList.push_back(tier2);
  860. SharedHandle<Option> option(new Option());
  861. option->put(PREF_BT_TRACKER, "http://host1/announce,http://host4/announce");
  862. option->put(PREF_BT_EXCLUDE_TRACKER,
  863. "http://host1/announce,http://host2/announce");
  864. adjustAnnounceUri(attrs, option);
  865. CPPUNIT_ASSERT_EQUAL((size_t)3, attrs->announceList.size());
  866. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[0].size());
  867. CPPUNIT_ASSERT_EQUAL(std::string("http://host3/announce"),
  868. attrs->announceList[0][0]);
  869. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[1].size());
  870. CPPUNIT_ASSERT_EQUAL(std::string("http://host1/announce"),
  871. attrs->announceList[1][0]);
  872. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[2].size());
  873. CPPUNIT_ASSERT_EQUAL(std::string("http://host4/announce"),
  874. attrs->announceList[2][0]);
  875. }
  876. } // namespace bittorrent
  877. } // namespace aria2