test parsing of X-Have

pull/5/head
Zlatin Balevsky 2019-06-21 06:43:48 +01:00
parent a26ad229ee
commit 807ab22f8e
2 changed files with 51 additions and 4 deletions

View File

@ -114,7 +114,7 @@ class DownloadSession {
throw new IOException("invalid header $header")
String key = header.substring(0, colon)
String value = header.substring(colon + 1)
headers[key] = value
headers[key] = value.trim()
}
// parse X-Have if present
@ -135,7 +135,7 @@ class DownloadSession {
if (range == null)
throw new IOException("Code 200 but no Content-Range")
def group = (range =~ /^ (\d+)-(\d+)$/)
def group = (range =~ /^(\d+)-(\d+)$/)
if (group.size() != 1)
throw new IOException("invalid Content-Range header $range")
@ -225,9 +225,10 @@ class DownloadSession {
byte [] availablePieces = Base64.decode(xHave)
availablePieces.eachWithIndex {b, i ->
for (int j = 0; j < 8 ; j++) {
int mask = 0x80 >> j
if ((b & mask) == mask)
byte mask = 0x80 >>> j
if ((b & mask) == mask) {
available.add(i * 8 + j)
}
}
}
}

View File

@ -201,6 +201,38 @@ class DownloadSessionTest {
assert thrown != null
}
@Test
public void test416Have() {
initSession(20)
readAllHeaders(fromDownloader)
toDownloader.write("416 don't have it\r\n".bytes)
toDownloader.write("X-Have: ${encodeXHave([0], 1)}\r\n\r\n".bytes)
toDownloader.flush()
Thread.sleep(150)
assert performed
assert available.contains(0)
assert thrown == null
}
@Test
public void test416Have2Pieces() {
int pieceSize = FileHasher.getPieceSize(1)
int size = (1 << pieceSize) + 1
initSession(size)
readAllHeaders(fromDownloader)
toDownloader.write("416 don't have it\r\n".bytes)
toDownloader.write("X-Have: ${encodeXHave([1], 2)}\r\n\r\n".bytes)
toDownloader.flush()
Thread.sleep(150)
assert performed
assert available.contains(1)
assert thrown == null
}
private static Set<String> readAllHeaders(InputStream is) {
Set<String> rv = new HashSet<>()
String header
@ -208,4 +240,18 @@ class DownloadSessionTest {
rv.add(header)
rv
}
private static String encodeXHave(List<Integer> pieces, int totalPieces) {
int bytes = totalPieces / 8
if (totalPieces % 8 != 0)
bytes++
byte[] raw = new byte[bytes]
pieces.each {
int byteIdx = it / 8
int offset = it % 8
int mask = 0x80 >>> offset
raw[byteIdx] |= mask
}
Base64.encode(raw)
}
}