From 05b02834af4b5f977266ebfd6467cb15ebbd119a Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Fri, 21 Jun 2019 12:25:04 +0100 Subject: [PATCH] parse X-Alt --- .../core/download/DownloadSession.groovy | 15 +++++++- .../muwire/core/download/Downloader.groovy | 2 +- .../download/SourceDiscoveredEvent.groovy | 10 ++++++ .../core/download/DownloadSessionTest.groovy | 36 ++++++++++++++++++- 4 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 core/src/main/groovy/com/muwire/core/download/SourceDiscoveredEvent.groovy 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 7d8f9777..8744f681 100644 --- a/core/src/main/groovy/com/muwire/core/download/DownloadSession.groovy +++ b/core/src/main/groovy/com/muwire/core/download/DownloadSession.groovy @@ -3,7 +3,9 @@ package com.muwire.core.download; import net.i2p.data.Base64 import com.muwire.core.Constants +import com.muwire.core.EventBus import com.muwire.core.InfoHash +import com.muwire.core.Persona import com.muwire.core.connection.Endpoint import com.muwire.core.util.DataUtil @@ -25,6 +27,7 @@ class DownloadSession { private static int SAMPLES = 10 + private final EventBus eventBus private final String meB64 private final Pieces pieces private final InfoHash infoHash @@ -40,8 +43,9 @@ class DownloadSession { private ByteBuffer mapped - DownloadSession(String meB64, Pieces pieces, InfoHash infoHash, Endpoint endpoint, File file, + DownloadSession(EventBus eventBus, String meB64, Pieces pieces, InfoHash infoHash, Endpoint endpoint, File file, int pieceSize, long fileLength, Set available) { + this.eventBus = eventBus this.meB64 = meB64 this.pieces = pieces this.endpoint = endpoint @@ -120,6 +124,15 @@ class DownloadSession { String value = header.substring(colon + 1) headers[key] = value.trim() } + + // prase X-Alt if present + if (headers.containsKey("X-Alt")) { + headers["X-Alt"].split(",").each { + byte [] raw = Base64.decode(it) + Persona source = new Persona(new ByteArrayInputStream(raw)) + eventBus.publish(new SourceDiscoveredEvent(infoHash : infoHash, source : source)) + } + } // parse X-Have if present if (headers.containsKey("X-Have")) { diff --git a/core/src/main/groovy/com/muwire/core/download/Downloader.groovy b/core/src/main/groovy/com/muwire/core/download/Downloader.groovy index 4458b67b..e2c2d2d2 100644 --- a/core/src/main/groovy/com/muwire/core/download/Downloader.groovy +++ b/core/src/main/groovy/com/muwire/core/download/Downloader.groovy @@ -247,7 +247,7 @@ public class Downloader { currentState = WorkerState.DOWNLOADING boolean requestPerformed while(!pieces.isComplete()) { - currentSession = new DownloadSession(me.toBase64(), pieces, getInfoHash(), endpoint, incompleteFile, pieceSize, length) + currentSession = new DownloadSession(eventBus, me.toBase64(), pieces, getInfoHash(), endpoint, incompleteFile, pieceSize, length) requestPerformed = currentSession.request() if (!requestPerformed) break diff --git a/core/src/main/groovy/com/muwire/core/download/SourceDiscoveredEvent.groovy b/core/src/main/groovy/com/muwire/core/download/SourceDiscoveredEvent.groovy new file mode 100644 index 00000000..47bf88ec --- /dev/null +++ b/core/src/main/groovy/com/muwire/core/download/SourceDiscoveredEvent.groovy @@ -0,0 +1,10 @@ +package com.muwire.core.download + +import com.muwire.core.Event +import com.muwire.core.InfoHash +import com.muwire.core.Persona + +class SourceDiscoveredEvent extends Event { + InfoHash infoHash + Persona source +} 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 1a3327f4..aad57ebf 100644 --- a/core/src/test/groovy/com/muwire/core/download/DownloadSessionTest.groovy +++ b/core/src/test/groovy/com/muwire/core/download/DownloadSessionTest.groovy @@ -3,9 +3,13 @@ package com.muwire.core.download import static org.junit.Assert.fail import org.junit.After +import org.junit.Before import org.junit.Test +import com.muwire.core.EventBus import com.muwire.core.InfoHash +import com.muwire.core.Persona +import com.muwire.core.Personas import com.muwire.core.connection.Endpoint import com.muwire.core.files.FileHasher import static com.muwire.core.util.DataUtil.readTillRN @@ -16,6 +20,7 @@ import net.i2p.util.ConcurrentHashSet class DownloadSessionTest { + private EventBus eventBus private File source, target private InfoHash infoHash private Endpoint endpoint @@ -32,6 +37,12 @@ class DownloadSessionTest { private Set available = new ConcurrentHashSet<>() private volatile IOException thrown + + @Before + public void setUp() { + eventBus = new EventBus() + } + private void initSession(int size, def claimedPieces = []) { Random r = new Random() byte [] content = new byte[size] @@ -64,7 +75,7 @@ class DownloadSessionTest { toUploader = new PipedOutputStream(fromDownloader) endpoint = new Endpoint(null, fromUploader, toUploader, null) - session = new DownloadSession("",pieces, infoHash, endpoint, target, pieceSize, size, available) + session = new DownloadSession(eventBus, "",pieces, infoHash, endpoint, target, pieceSize, size, available) downloadThread = new Thread( { perform() } as Runnable) downloadThread.setDaemon(true) downloadThread.start() @@ -289,6 +300,29 @@ class DownloadSessionTest { assert start == 0 } + @Test + public void testXAlt() throws Exception { + Personas personas = new Personas() + def sources = [] + def listener = new Object() { + public void onSourceDiscoveredEvent(SourceDiscoveredEvent e) { + sources << e.source + } + } + eventBus.register(SourceDiscoveredEvent.class, listener) + + initSession(20) + readAllHeaders(fromDownloader) + toDownloader.write("416 don't have it\r\n".bytes) + toDownloader.write("X-Alt: ${personas.persona1.toBase64()},${personas.persona2.toBase64()}\r\n\r\n".bytes) + toDownloader.flush() + + Thread.sleep(150) + assert sources.contains(personas.persona1) + assert sources.contains(personas.persona2) + assert 2 == sources.size() + } + private static Set readAllHeaders(InputStream is) { Set rv = new HashSet<>() String header