From 807ab22f8ef0565cde6a78b8d35f54073268766d Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Fri, 21 Jun 2019 06:43:48 +0100 Subject: [PATCH] test parsing of X-Have --- .../core/download/DownloadSession.groovy | 9 ++-- .../core/download/DownloadSessionTest.groovy | 46 +++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/download/DownloadSession.groovy b/core/src/main/groovy/com/muwire/core/download/DownloadSession.groovy index 678b7e09..edd5603d 100644 --- a/core/src/main/groovy/com/muwire/core/download/DownloadSession.groovy +++ b/core/src/main/groovy/com/muwire/core/download/DownloadSession.groovy @@ -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) + } } } } diff --git a/core/src/test/groovy/com/muwire/core/download/DownloadSessionTest.groovy b/core/src/test/groovy/com/muwire/core/download/DownloadSessionTest.groovy index 60b9c356..432fedd3 100644 --- a/core/src/test/groovy/com/muwire/core/download/DownloadSessionTest.groovy +++ b/core/src/test/groovy/com/muwire/core/download/DownloadSessionTest.groovy @@ -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 readAllHeaders(InputStream is) { Set rv = new HashSet<>() String header @@ -208,4 +240,18 @@ class DownloadSessionTest { rv.add(header) rv } + + private static String encodeXHave(List 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) + } }