Skip to content

Commit 62184de

Browse files
committed
fixed bug: missing web-seeds in serialized torrent file
added proper handling of web-seed-urls to TorrentMetadata/Impl, TorrentParser and TorrentSerializer added some unit tests - PASSED manually tested end-to-end by creating a torrent with web-seed-urls and opening it in qbittorrent verifying that they are passed correctly - PASSED urls were shown properly
1 parent 90bdfbc commit 62184de

7 files changed

Lines changed: 134 additions & 3 deletions

File tree

common/src/main/java/com/turn/ttorrent/common/TorrentMetadata.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,10 @@ public interface TorrentMetadata extends TorrentHash {
7373
*/
7474
List<TorrentFile> getFiles();
7575

76+
/**
77+
* @return list of web seeds (URLs) or <code>null</code> if web seeds are not specified
78+
*/
79+
@Nullable
80+
List<String> getWebSeeds();
81+
7682
}

common/src/main/java/com/turn/ttorrent/common/TorrentMetadataImpl.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.turn.ttorrent.common;
22

3-
import org.jetbrains.annotations.NotNull;
43
import org.jetbrains.annotations.Nullable;
54

65
import java.util.List;
@@ -20,6 +19,8 @@ public class TorrentMetadataImpl implements TorrentMetadata {
2019
private final int myPieceLength;
2120
private final byte[] myPiecesHashes;
2221
private final String myHexString;
22+
@Nullable
23+
private final List<String> myWebSeeds;
2324

2425
TorrentMetadataImpl(byte[] infoHash,
2526
@Nullable List<List<String>> announceList,
@@ -31,7 +32,9 @@ public class TorrentMetadataImpl implements TorrentMetadata {
3132
List<TorrentFile> files,
3233
int pieceCount,
3334
int pieceLength,
34-
byte[] piecesHashes) {
35+
byte[] piecesHashes,
36+
@Nullable final List<String> webSeeds
37+
) {
3538
myInfoHash = infoHash;
3639
myAnnounceList = announceList;
3740
myMainAnnounce = mainAnnounce;
@@ -44,6 +47,7 @@ public class TorrentMetadataImpl implements TorrentMetadata {
4447
myPieceLength = pieceLength;
4548
myPiecesHashes = piecesHashes;
4649
myHexString = TorrentUtils.byteArrayToHexString(myInfoHash);
50+
myWebSeeds = webSeeds;
4751
}
4852

4953
@Override
@@ -56,6 +60,11 @@ public List<TorrentFile> getFiles() {
5660
return myFiles;
5761
}
5862

63+
@Override
64+
public List<String> getWebSeeds() {
65+
return myWebSeeds;
66+
}
67+
5968
@Nullable
6069
@Override
6170
public List<List<String>> getAnnounceList() {

common/src/main/java/com/turn/ttorrent/common/TorrentParser.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public TorrentMetadata parse(byte[] metadata) throws InvalidBEncodingException,
5454
final byte[] piecesHashes = getRequiredValueOrThrowException(infoTable, PIECES).getBytes();
5555

5656
final boolean torrentContainsManyFiles = infoTable.get(FILES) != null;
57+
final List<String> webSeeds = getWebSeeds(dictionaryMetadata);
5758

5859
final String dirName = getRequiredValueOrThrowException(infoTable, NAME).getString();
5960

@@ -82,10 +83,22 @@ public TorrentMetadata parse(byte[] metadata) throws InvalidBEncodingException,
8283
files,
8384
piecesCount,
8485
pieceLength,
85-
piecesHashes
86+
piecesHashes,
87+
webSeeds
8688
);
8789
}
8890

91+
private List<String> getWebSeeds(Map<String, BEValue> dictionaryMetadata) throws InvalidBEncodingException {
92+
List<String> result = new ArrayList<String>();
93+
final BEValue list = dictionaryMetadata.get(URL_LIST);
94+
if (list != null) {
95+
for (BEValue url : list.getList()) {
96+
result.add(url.getString());
97+
}
98+
}
99+
return result;
100+
}
101+
89102
private List<TorrentFile> parseFiles(Map<String, BEValue> infoTable, boolean torrentContainsManyFiles, String name) throws InvalidBEncodingException {
90103
if (!torrentContainsManyFiles) {
91104
final BEValue md5Sum = infoTable.get(MD5_SUM);

common/src/main/java/com/turn/ttorrent/common/TorrentSerializer.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ public byte[] serialize(TorrentMetadata metadata) throws IOException {
5555
}
5656
infoTable.put(FILES, new BEValue(files));
5757
}
58+
final List<String> webSeeds = metadata.getWebSeeds();
59+
if (webSeeds != null && !webSeeds.isEmpty()) {
60+
mapMetadata.put(URL_LIST, new BEValue(mapStringListToBEValueList(webSeeds)));
61+
}
5862

5963
mapMetadata.put(INFO_TABLE, new BEValue(infoTable));
6064

common/src/test/java/com/turn/ttorrent/common/TorrentParserTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,37 @@ public void missingRequiredFieldTest() {
9494
fail("", e);
9595
}
9696
}
97+
98+
public void webSeedsTest() throws IOException {
99+
final Map<String, BEValue> metadata = new HashMap<String, BEValue>();
100+
final HashMap<String, BEValue> infoTable = new HashMap<String, BEValue>();
101+
102+
metadata.put("announce", new BEValue("http://localhost/announce"));
103+
104+
infoTable.put("piece length", new BEValue(4));
105+
106+
infoTable.put("pieces", new BEValue(new byte[100]));
107+
infoTable.put("name", new BEValue("test.file"));
108+
infoTable.put("length", new BEValue(19));
109+
110+
List<BEValue> webSeeds = new ArrayList<BEValue>();
111+
webSeeds.add(new BEValue("http://localhost/webseed"));
112+
webSeeds.add(new BEValue("http://localhost/webseed2"));
113+
metadata.put("url-list", new BEValue(webSeeds));
114+
115+
metadata.put("info", new BEValue(infoTable));
116+
117+
final TorrentMetadata torrentMetadata = myTorrentParser.parse(BEncoder.bencode(metadata).array());
118+
119+
assertEquals(torrentMetadata.getPieceLength(), 4);
120+
assertEquals(torrentMetadata.getAnnounce(), "http://localhost/announce");
121+
assertEquals(torrentMetadata.getDirectoryName(), "test.file");
122+
assertNull(torrentMetadata.getAnnounceList());
123+
124+
List<String> actualWebSeeds = torrentMetadata.getWebSeeds();
125+
assertNotNull(actualWebSeeds);
126+
assertEquals(actualWebSeeds.get(0), "http://localhost/webseed");
127+
assertEquals(actualWebSeeds.get(1), "http://localhost/webseed2");
128+
}
129+
97130
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.turn.ttorrent.common;
2+
3+
import static org.testng.Assert.assertNotNull;
4+
import static org.testng.Assert.assertTrue;
5+
6+
import java.io.IOException;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import org.testng.annotations.BeforeMethod;
10+
import org.testng.annotations.Test;
11+
12+
@Test
13+
public class TorrentSerializerTest {
14+
15+
private TorrentSerializer myTorrentSerializer;
16+
17+
@BeforeMethod
18+
public void setUp() {
19+
myTorrentSerializer = new TorrentSerializer();
20+
}
21+
22+
public void testWebSeeds() throws IOException {
23+
List<String> webSeeds = new ArrayList<String>();
24+
webSeeds.add("http://localhost/webseed1");
25+
webSeeds.add("ftp://localhost/webseed2");
26+
webSeeds.add("https://localhost/ABC");
27+
28+
final List<TorrentFile> files = new ArrayList<TorrentFile>();
29+
final List<String> relativePath = new ArrayList<String>();
30+
relativePath.add("file.txt");
31+
files.add(new TorrentFile(relativePath, 10, null));
32+
final TorrentMetadataImpl metadata =
33+
new TorrentMetadataImpl(new byte[0], null, "main-announce", 19,
34+
"comment", "created by", "name", files, 10,
35+
10, new byte[10], webSeeds
36+
);
37+
38+
final byte[] output = myTorrentSerializer.serialize(metadata);
39+
assertNotNull(output);
40+
41+
final String outputString = new String(output);
42+
System.out.println(outputString);
43+
44+
for (String url : webSeeds) {
45+
assertTrue(
46+
outputString.contains(url.length() + ":" + url),
47+
"url not found in output: " + url + ", output: " + outputString
48+
);
49+
}
50+
}
51+
52+
}

common/src/test/java/com/turn/ttorrent/common/creation/MetadataBuilderTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,18 @@ public void testMultiFileWithOneFileValues() throws IOException {
132132
}
133133

134134
}
135+
136+
public void webSeedsTest() throws IOException {
137+
Map<String, BEValue> metadata = new MetadataBuilder()
138+
.addDataSource(new ByteArrayInputStream(new byte[]{1, 2}), "path/some_file", true)
139+
.setDirectoryName("root")
140+
.addWebSeedUrl("http://localhost:8080")
141+
.addWebSeedUrl("http://localhost:8081")
142+
.buildBEP().getMap();
143+
List<BEValue> urlList = metadata.get(URL_LIST).getList();
144+
assertEquals(urlList.size(), 2);
145+
assertEquals(urlList.get(0).getString(), "http://localhost:8080");
146+
assertEquals(urlList.get(1).getString(), "http://localhost:8081");
147+
}
148+
135149
}

0 commit comments

Comments
 (0)