diff --git a/core/src/main/groovy/com/muwire/core/connection/ConnectionAcceptor.groovy b/core/src/main/groovy/com/muwire/core/connection/ConnectionAcceptor.groovy index c8bb8087..0af8c80f 100644 --- a/core/src/main/groovy/com/muwire/core/connection/ConnectionAcceptor.groovy +++ b/core/src/main/groovy/com/muwire/core/connection/ConnectionAcceptor.groovy @@ -165,6 +165,11 @@ class ConnectionAcceptor { private void processGET(Endpoint e) { + byte[] et = new byte[3] + final DataInputStream dis = new DataInputStream(e.getInputStream()) + dis.readFully(et) + if (et != "ET ".getBytes(StandardCharsets.US_ASCII)) + throw new IOException("Invalid GET connection") // TODO: implement } diff --git a/core/src/main/groovy/com/muwire/core/files/FileManager.groovy b/core/src/main/groovy/com/muwire/core/files/FileManager.groovy index 7699197a..e208239e 100644 --- a/core/src/main/groovy/com/muwire/core/files/FileManager.groovy +++ b/core/src/main/groovy/com/muwire/core/files/FileManager.groovy @@ -10,7 +10,7 @@ class FileManager { final EventBus eventBus - final Map> rootToFiles = new HashMap<>() + final Map> rootToFiles = Collections.synchronizedMap(new HashMap<>()) final Map fileToSharedFile = Collections.synchronizedMap(new HashMap<>()) final Map> nameToFiles = new HashMap<>() final SearchIndex index = new SearchIndex() @@ -56,6 +56,7 @@ class FileManager { void onFileUnsharedEvent(FileUnsharedEvent e) { SharedFile sf = e.unsharedFile byte [] root = sf.getInfoHash().getRoot() + Set existing Set existing = rootToFiles.get(root) if (existing != null) { existing.remove(sf) @@ -83,12 +84,17 @@ class FileManager { return new HashMap<>(fileToSharedFile) } } + + Set getSharedFiles(byte []root) { + return rootToFiles.get(root) + } void onSearchEvent(SearchEvent e) { // hash takes precedence ResultsEvent re = null if (e.searchHash != null) { - Set found = rootToFiles.get e.searchHash + Set found + found = rootToFiles.get e.searchHash if (found != null && !found.isEmpty()) re = new ResultsEvent(results: found.asList(), uuid: e.uuid) } else { diff --git a/core/src/main/groovy/com/muwire/core/upload/Range.groovy b/core/src/main/groovy/com/muwire/core/upload/Range.groovy new file mode 100644 index 00000000..34871153 --- /dev/null +++ b/core/src/main/groovy/com/muwire/core/upload/Range.groovy @@ -0,0 +1,10 @@ +package com.muwire.core.upload + +class Range { + final long start, end + + Range(long start, long end) { + this.start = start + this.end = end + } +} diff --git a/core/src/main/groovy/com/muwire/core/upload/Request.groovy b/core/src/main/groovy/com/muwire/core/upload/Request.groovy new file mode 100644 index 00000000..b29f14b6 --- /dev/null +++ b/core/src/main/groovy/com/muwire/core/upload/Request.groovy @@ -0,0 +1,16 @@ +package com.muwire.core.upload + +import com.muwire.core.InfoHash + +import net.i2p.data.Base64 + +class Request { + InfoHash infoHash + Range range + Map headers + + static Range parse(InfoHash infoHash, InputStream is) throws IOException { + + } + +} diff --git a/core/src/main/groovy/com/muwire/core/upload/UploadEvent.groovy b/core/src/main/groovy/com/muwire/core/upload/UploadEvent.groovy new file mode 100644 index 00000000..2e173813 --- /dev/null +++ b/core/src/main/groovy/com/muwire/core/upload/UploadEvent.groovy @@ -0,0 +1,7 @@ +package com.muwire.core.upload + +import com.muwire.core.Event + +public class UploadEvent extends Event { + Uploader uploader +} diff --git a/core/src/main/groovy/com/muwire/core/upload/UploadFinishedEvent.groovy b/core/src/main/groovy/com/muwire/core/upload/UploadFinishedEvent.groovy new file mode 100644 index 00000000..8550107a --- /dev/null +++ b/core/src/main/groovy/com/muwire/core/upload/UploadFinishedEvent.groovy @@ -0,0 +1,5 @@ +package com.muwire.core.upload + +class UploadFinishedEvent { + Uploader uploader +} diff --git a/core/src/main/groovy/com/muwire/core/upload/UploadManager.groovy b/core/src/main/groovy/com/muwire/core/upload/UploadManager.groovy new file mode 100644 index 00000000..fbb68d35 --- /dev/null +++ b/core/src/main/groovy/com/muwire/core/upload/UploadManager.groovy @@ -0,0 +1,57 @@ +package com.muwire.core.upload + +import java.nio.charset.StandardCharsets + +import com.muwire.core.EventBus +import com.muwire.core.InfoHash +import com.muwire.core.SharedFile +import com.muwire.core.connection.Endpoint +import com.muwire.core.files.FileManager + +import groovy.util.logging.Log +import net.i2p.data.Base64 + +@Log +public class UploadManager { + private final EventBus eventBus + private final FileManager fileManager + + public UploadManager(EventBus eventBus, FileManager fileManager) { + this.eventBus = eventBus + this.fileManager = fileManager + } + + public void processEndpoint(Endpoint e) throws IOException { + while(true) { + byte [] infoHashStringBytes = new byte[44] + DataInputStream dis = new DataInputStream(e.getInputStream()) + dis.readFully(infoHashStringBytes) + String infoHashString = new String(infoHashStringBytes, StandardCharsets.US_ASCII) + log.info("Responding to upload request for root $infoHashString") + + byte [] infoHashRoot = Base64.decode(infoHashStringBytes) + Set sharedFiles = fileManager.getSharedFiles(infoHashRoot) + if (sharedFiles == null || sharedFiles.isEmpty()) { + log.info "file not found" + e.getOutputStream().write("404 File Not Found".getBytes(StandardCharsets.US_ASCII)) + e.getOutputStream().flush() + return + } + + byte [] rn = new byte[2] + dis.readFully(rn) + if (rn != "\r\n".getBytes(StandardCharsets.US_ASCII)) { + log.warning("Malformed GET header") + return + } + + Request request = Request.parse(new InfoHash(infoHashRoot), e.getInputStream()) + Uploader uploader = new Uploader(request, e) + eventBus.publish(new UploadEvent(uploader)) + uploader.respond() + eventBus.publish(new UploadFinishedEvent(uploader)) + } + + } +} + diff --git a/core/src/main/groovy/com/muwire/core/upload/Uploader.groovy b/core/src/main/groovy/com/muwire/core/upload/Uploader.groovy new file mode 100644 index 00000000..05a08f19 --- /dev/null +++ b/core/src/main/groovy/com/muwire/core/upload/Uploader.groovy @@ -0,0 +1,17 @@ +package com.muwire.core.upload + +import com.muwire.core.connection.Endpoint + +class Uploader { + private final Request request + private final Endpoint endpoint + + Uploader(Request request, Endpoint endpoint) { + this.request = request + this.endpoint = endpoint + } + + void respond() { + + } +}