BittorrentHelperTest.cc 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  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((off_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((off_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 =
  657. bencode2::decode(torrentData.begin(), torrentData.end());
  658. SharedHandle<ValueBase> infoDic = downcast<Dict>(tr)->get("info");
  659. std::string metadata = bencode2::encode(infoDic);
  660. SharedHandle<TorrentAttribute> attrs = getTorrentAttrs(dctx);
  661. CPPUNIT_ASSERT(metadata == attrs->metadata);
  662. CPPUNIT_ASSERT_EQUAL(metadata.size(), attrs->metadataSize);
  663. }
  664. void BittorrentHelperTest::testParseMagnet()
  665. {
  666. std::string magnet =
  667. "magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c&dn=aria2"
  668. "&tr=http://tracker1&tr=http://tracker2";
  669. SharedHandle<TorrentAttribute> attrs = bittorrent::parseMagnet(magnet);
  670. CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  671. util::toHex(attrs->infoHash));
  672. CPPUNIT_ASSERT_EQUAL(std::string("[METADATA]aria2"), attrs->name);
  673. CPPUNIT_ASSERT_EQUAL((size_t)2, attrs->announceList.size());
  674. CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"),
  675. attrs->announceList[0][0]);
  676. CPPUNIT_ASSERT_EQUAL(std::string("http://tracker2"),
  677. attrs->announceList[1][0]);
  678. magnet = "magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c";
  679. attrs = bittorrent::parseMagnet(magnet);
  680. CPPUNIT_ASSERT_EQUAL
  681. (std::string("[METADATA]248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  682. attrs->name);
  683. CPPUNIT_ASSERT(attrs->announceList.empty());
  684. magnet = "magnet:?xt=urn:sha1:7899bdb90a026c746f3cbc10839dd9b2a2a3e985&"
  685. "xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c";
  686. attrs = bittorrent::parseMagnet(magnet);
  687. CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  688. util::toHex(attrs->infoHash));
  689. }
  690. void BittorrentHelperTest::testParseMagnet_base32()
  691. {
  692. std::string infoHash = "248d0a1cd08284299de78d5c1ed359bb46717d8c";
  693. std::string base32InfoHash = base32::encode(fromHex(infoHash));
  694. std::string magnet = "magnet:?xt=urn:btih:"+base32InfoHash+"&dn=aria2";
  695. SharedHandle<TorrentAttribute> attrs = bittorrent::parseMagnet(magnet);
  696. CPPUNIT_ASSERT_EQUAL
  697. (std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"),
  698. util::toHex(attrs->infoHash));
  699. }
  700. void BittorrentHelperTest::testMetadata2Torrent()
  701. {
  702. std::string metadata = "METADATA";
  703. SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());
  704. CPPUNIT_ASSERT_EQUAL
  705. (std::string("d4:infoMETADATAe"), metadata2Torrent(metadata, attrs));
  706. attrs->announceList.push_back(std::vector<std::string>());
  707. attrs->announceList[0].push_back("http://localhost/announce");
  708. CPPUNIT_ASSERT_EQUAL
  709. (std::string("d"
  710. "13:announce-list"
  711. "ll25:http://localhost/announceee"
  712. "4:infoMETADATA"
  713. "e"),
  714. metadata2Torrent(metadata, attrs));
  715. }
  716. void BittorrentHelperTest::testTorrent2Magnet()
  717. {
  718. SharedHandle<DownloadContext> dctx(new DownloadContext());
  719. load(A2_TEST_DIR"/test.torrent", dctx, option_);
  720. CPPUNIT_ASSERT_EQUAL
  721. (std::string("magnet:?xt=urn:btih:248D0A1CD08284299DE78D5C1ED359BB46717D8C"
  722. "&dn=aria2-test"
  723. "&tr=http%3A%2F%2Ftracker1"
  724. "&tr=http%3A%2F%2Ftracker2"
  725. "&tr=http%3A%2F%2Ftracker3"),
  726. torrent2Magnet(getTorrentAttrs(dctx)));
  727. }
  728. void BittorrentHelperTest::testExtractPeerFromString()
  729. {
  730. std::string hextext = "100210354527354678541237324732171ae1";
  731. hextext += "20010db8bd0501d2288a1fc0000110ee1ae2";
  732. std::string peersstr = "36:"+fromHex(hextext);
  733. SharedHandle<ValueBase> str =
  734. bencode2::decode(peersstr.begin(), peersstr.end());
  735. std::deque<SharedHandle<Peer> > peers;
  736. extractPeer(str, AF_INET6, std::back_inserter(peers));
  737. CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
  738. CPPUNIT_ASSERT_EQUAL(std::string("1002:1035:4527:3546:7854:1237:3247:3217"),
  739. peers[0]->getIPAddress());
  740. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peers[0]->getPort());
  741. CPPUNIT_ASSERT_EQUAL(std::string("2001:db8:bd05:1d2:288a:1fc0:1:10ee"),
  742. peers[1]->getIPAddress());
  743. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, peers[1]->getPort());
  744. hextext = "c0a800011ae1";
  745. hextext += "c0a800021ae2";
  746. peersstr = "12:"+fromHex(hextext);
  747. str = bencode2::decode(peersstr.begin(), peersstr.end());
  748. peers.clear();
  749. extractPeer(str, AF_INET, std::back_inserter(peers));
  750. CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
  751. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peers[0]->getIPAddress());
  752. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peers[0]->getPort());
  753. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), peers[1]->getIPAddress());
  754. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, peers[1]->getPort());
  755. }
  756. void BittorrentHelperTest::testExtractPeerFromList()
  757. {
  758. std::string peersString =
  759. "d5:peersld2:ip11:192.168.0.17:peer id20:aria2-00000000000000"
  760. "4:porti2006eeee";
  761. SharedHandle<ValueBase> dict =
  762. bencode2::decode(peersString.begin(), peersString.end());
  763. std::deque<SharedHandle<Peer> > peers;
  764. extractPeer(downcast<Dict>(dict)->get("peers"), AF_INET, std::back_inserter(peers));
  765. CPPUNIT_ASSERT_EQUAL((size_t)1, peers.size());
  766. SharedHandle<Peer> peer = *peers.begin();
  767. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
  768. CPPUNIT_ASSERT_EQUAL((uint16_t)2006, peer->getPort());
  769. }
  770. void BittorrentHelperTest::testExtract2PeersFromList()
  771. {
  772. std::string peersString =
  773. "d5:peersld2:ip11:192.168.0.17:peer id20:aria2-00000000000000"
  774. "4:porti65535eed2:ip11:192.168.0.27:peer id20:aria2-00000000000000"
  775. "4:porti2007eeee";
  776. SharedHandle<ValueBase> dict =
  777. bencode2::decode(peersString.begin(), peersString.end());
  778. std::deque<SharedHandle<Peer> > peers;
  779. extractPeer(downcast<Dict>(dict)->get("peers"), AF_INET, std::back_inserter(peers));
  780. CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
  781. SharedHandle<Peer> peer = *peers.begin();
  782. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
  783. CPPUNIT_ASSERT_EQUAL((uint16_t)65535, peer->getPort());
  784. peer = *(peers.begin()+1);
  785. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.2"), peer->getIPAddress());
  786. CPPUNIT_ASSERT_EQUAL((uint16_t)2007, peer->getPort());
  787. }
  788. void BittorrentHelperTest::testPackcompact()
  789. {
  790. unsigned char compact[COMPACT_LEN_IPV6];
  791. CPPUNIT_ASSERT_EQUAL(18,
  792. packcompact(compact,
  793. "1002:1035:4527:3546:7854:1237:3247:3217",
  794. 6881));
  795. CPPUNIT_ASSERT_EQUAL(std::string("100210354527354678541237324732171ae1"),
  796. util::toHex(compact, 18));
  797. CPPUNIT_ASSERT_EQUAL(6, packcompact(compact, "192.168.0.1", 6881));
  798. CPPUNIT_ASSERT_EQUAL(std::string("c0a800011ae1"), util::toHex(compact, 6));
  799. CPPUNIT_ASSERT_EQUAL(0, packcompact(compact, "badaddr", 6881));
  800. }
  801. void BittorrentHelperTest::testUnpackcompact()
  802. {
  803. unsigned char compact6[] = {
  804. 0x10, 0x02, 0x10, 0x35, 0x45, 0x27, 0x35, 0x46,
  805. 0x78, 0x54, 0x12, 0x37, 0x32, 0x47, 0x32, 0x17,
  806. 0x1A, 0xE1 };
  807. std::pair<std::string, uint16_t> p =
  808. unpackcompact(compact6, AF_INET6);
  809. CPPUNIT_ASSERT_EQUAL(std::string("1002:1035:4527:3546:7854:1237:3247:3217"),
  810. p.first);
  811. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, p.second);
  812. unsigned char compact[] = { 0xC0, 0xa8, 0x00, 0x01, 0x1A, 0xE1 };
  813. p = unpackcompact(compact, AF_INET);
  814. CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), p.first);
  815. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, p.second);
  816. }
  817. void BittorrentHelperTest::testRemoveAnnounceUri()
  818. {
  819. SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());
  820. std::vector<std::string> tier1;
  821. tier1.push_back("http://host1/announce");
  822. std::vector<std::string> tier2;
  823. tier2.push_back("http://host2/announce");
  824. tier2.push_back("http://host3/announce");
  825. attrs->announceList.push_back(tier1);
  826. attrs->announceList.push_back(tier2);
  827. std::vector<std::string> removeUris;
  828. removeUris.push_back(tier1[0]);
  829. removeUris.push_back(tier2[0]);
  830. removeAnnounceUri(attrs, removeUris);
  831. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList.size());
  832. CPPUNIT_ASSERT_EQUAL(std::string("http://host3/announce"),
  833. attrs->announceList[0][0]);
  834. removeUris.clear();
  835. removeUris.push_back("*");
  836. removeAnnounceUri(attrs, removeUris);
  837. CPPUNIT_ASSERT(attrs->announceList.empty());
  838. }
  839. void BittorrentHelperTest::testAddAnnounceUri()
  840. {
  841. SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());
  842. std::vector<std::string> addUris;
  843. addUris.push_back("http://host1/announce");
  844. addUris.push_back("http://host2/announce");
  845. addAnnounceUri(attrs, addUris);
  846. CPPUNIT_ASSERT_EQUAL((size_t)2, attrs->announceList.size());
  847. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[0].size());
  848. CPPUNIT_ASSERT_EQUAL(std::string("http://host1/announce"),
  849. attrs->announceList[0][0]);
  850. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[1].size());
  851. CPPUNIT_ASSERT_EQUAL(std::string("http://host2/announce"),
  852. attrs->announceList[1][0]);
  853. }
  854. void BittorrentHelperTest::testAdjustAnnounceUri()
  855. {
  856. SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());
  857. std::vector<std::string> tier1;
  858. tier1.push_back("http://host1/announce");
  859. std::vector<std::string> tier2;
  860. tier2.push_back("http://host2/announce");
  861. tier2.push_back("http://host3/announce");
  862. attrs->announceList.push_back(tier1);
  863. attrs->announceList.push_back(tier2);
  864. SharedHandle<Option> option(new Option());
  865. option->put(PREF_BT_TRACKER, "http://host1/announce,http://host4/announce");
  866. option->put(PREF_BT_EXCLUDE_TRACKER,
  867. "http://host1/announce,http://host2/announce");
  868. adjustAnnounceUri(attrs, option);
  869. CPPUNIT_ASSERT_EQUAL((size_t)3, attrs->announceList.size());
  870. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[0].size());
  871. CPPUNIT_ASSERT_EQUAL(std::string("http://host3/announce"),
  872. attrs->announceList[0][0]);
  873. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[1].size());
  874. CPPUNIT_ASSERT_EQUAL(std::string("http://host1/announce"),
  875. attrs->announceList[1][0]);
  876. CPPUNIT_ASSERT_EQUAL((size_t)1, attrs->announceList[2].size());
  877. CPPUNIT_ASSERT_EQUAL(std::string("http://host4/announce"),
  878. attrs->announceList[2][0]);
  879. }
  880. } // namespace bittorrent
  881. } // namespace aria2