From ef9ad1549a5e18fcafd0a8ab90fd67df1790a563 Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Wed, 20 Oct 2021 14:30:40 +0100 Subject: [PATCH] Mark which upload requests were first for the connection and only refresh the Library for those. Fix accounting of upload slots per user. GitHub issue #98 --- .../com/muwire/core/upload/UploadEvent.groovy | 1 + .../muwire/core/upload/UploadManager.groovy | 170 +++++++++--------- .../com/muwire/gui/MainFrameModel.groovy | 3 +- 3 files changed, 92 insertions(+), 82 deletions(-) diff --git a/core/src/main/groovy/com/muwire/core/upload/UploadEvent.groovy b/core/src/main/groovy/com/muwire/core/upload/UploadEvent.groovy index 2e173813..7b2409c3 100644 --- a/core/src/main/groovy/com/muwire/core/upload/UploadEvent.groovy +++ b/core/src/main/groovy/com/muwire/core/upload/UploadEvent.groovy @@ -4,4 +4,5 @@ import com.muwire.core.Event public class UploadEvent extends Event { Uploader uploader + boolean first } diff --git a/core/src/main/groovy/com/muwire/core/upload/UploadManager.groovy b/core/src/main/groovy/com/muwire/core/upload/UploadManager.groovy index 3abfe1dc..97cb1cd3 100644 --- a/core/src/main/groovy/com/muwire/core/upload/UploadManager.groovy +++ b/core/src/main/groovy/com/muwire/core/upload/UploadManager.groovy @@ -52,10 +52,12 @@ public class UploadManager { DataInputStream dis = new DataInputStream(e.getInputStream()) boolean first = true while(true) { + boolean wasFirst = false boolean head = false - if (first) + if (first) { first = false - else { + wasFirst = true + } else { byte[] get = new byte[4] dis.readFully(get) if (get != "GET ".getBytes(StandardCharsets.US_ASCII)) { @@ -134,7 +136,7 @@ public class UploadManager { uploader = new HeadUploader(file, request, e, mesh) else uploader = new ContentUploader(file, request, e, mesh, pieceSize) - eventBus.publish(new UploadEvent(uploader : uploader)) + eventBus.publish(new UploadEvent(uploader : uploader, first: wasFirst)) try { uploader.respond() if (!head) @@ -205,92 +207,98 @@ public class UploadManager { } Uploader uploader = new HashListUploader(e, fullInfoHash, request) - eventBus.publish(new UploadEvent(uploader : uploader)) + eventBus.publish(new UploadEvent(uploader : uploader, first: true)) // hash list is always a first try { uploader.respond() - } finally { - decrementUploads(request.downloader) eventBus.publish(new UploadFinishedEvent(uploader : uploader)) - } - // proceed with content - while(true) { - byte[] get = new byte[4] - dis.readFully(get) - boolean head = false - if (get != "GET ".getBytes(StandardCharsets.US_ASCII)) { - if (get == "HEAD".getBytes(StandardCharsets.US_ASCII) && dis.readByte() == (byte)32) { - head = true - } else { - log.warning("received a method other than GET or HEAD on subsequent call") + // proceed with content + boolean first = true + while(true) { + boolean wasFirst = false + if (first) { + first = false + wasFirst = true + } + byte[] get = new byte[4] + dis.readFully(get) + boolean head = false + if (get != "GET ".getBytes(StandardCharsets.US_ASCII)) { + if (get == "HEAD".getBytes(StandardCharsets.US_ASCII) && dis.readByte() == (byte)32) { + head = true + } else { + log.warning("received a method other than GET or HEAD on subsequent call") + e.close() + return + } + } + dis.readFully(infoHashStringBytes) + infoHashString = new String(infoHashStringBytes, StandardCharsets.US_ASCII) + log.info("Responding to upload request for root $infoHashString") + + infoHashRoot = Base64.decode(infoHashString) + infoHash = new InfoHash(infoHashRoot) + sharedFiles = fileManager.getSharedFiles(infoHashRoot) + downloader = downloadManager.downloaders.get(infoHash) + if (downloader == null && (sharedFiles == null || sharedFiles.length == 0)) { + log.info "file not found" + e.getOutputStream().write("404 File Not Found\r\n\r\n".getBytes(StandardCharsets.US_ASCII)) + e.getOutputStream().flush() e.close() return } + + rn = new byte[2] + dis.readFully(rn) + if (rn != "\r\n".getBytes(StandardCharsets.US_ASCII)) { + log.warning("Malformed GET header") + e.close() + return + } + + if (head) + request = Request.parseHeadRequest(new InfoHash(infoHashRoot), e.getInputStream()) + else + request = Request.parseContentRequest(new InfoHash(infoHashRoot), e.getInputStream()) + if (request.downloader != null && request.downloader.destination != e.destination) { + log.info("Downloader persona doesn't match their destination") + e.close() + return + } + + if (request.have > 0) + eventBus.publish(new SourceDiscoveredEvent(infoHash : request.infoHash, source : request.downloader)) + + Mesh mesh + File file + int pieceSize + if (downloader != null) { + mesh = meshManager.get(infoHash) + file = downloader.incompleteFile + pieceSize = downloader.pieceSizePow2 + } else { + sharedFiles.each { it.getDownloaders().add(request.downloader.getHumanReadableName()) } + SharedFile sharedFile = sharedFiles[0]; + mesh = meshManager.getOrCreate(request.infoHash, sharedFile.NPieces, false) + file = sharedFile.file + pieceSize = sharedFile.pieceSize + } + + if (head) + uploader = new HeadUploader(file, request, e, mesh) + else + uploader = new ContentUploader(file, request, e, mesh, pieceSize) + eventBus.publish(new UploadEvent(uploader : uploader, first: wasFirst)) + try { + uploader.respond() + if (!head) + eventBus.publish(new SourceVerifiedEvent(infoHash : request.infoHash, source : request.downloader.destination)) + } finally { + eventBus.publish(new UploadFinishedEvent(uploader : uploader)) + } } - dis.readFully(infoHashStringBytes) - infoHashString = new String(infoHashStringBytes, StandardCharsets.US_ASCII) - log.info("Responding to upload request for root $infoHashString") - - infoHashRoot = Base64.decode(infoHashString) - infoHash = new InfoHash(infoHashRoot) - sharedFiles = fileManager.getSharedFiles(infoHashRoot) - downloader = downloadManager.downloaders.get(infoHash) - if (downloader == null && (sharedFiles == null || sharedFiles.length == 0)) { - log.info "file not found" - e.getOutputStream().write("404 File Not Found\r\n\r\n".getBytes(StandardCharsets.US_ASCII)) - e.getOutputStream().flush() - e.close() - return - } - - rn = new byte[2] - dis.readFully(rn) - if (rn != "\r\n".getBytes(StandardCharsets.US_ASCII)) { - log.warning("Malformed GET header") - e.close() - return - } - - if (head) - request = Request.parseHeadRequest(new InfoHash(infoHashRoot), e.getInputStream()) - else - request = Request.parseContentRequest(new InfoHash(infoHashRoot), e.getInputStream()) - if (request.downloader != null && request.downloader.destination != e.destination) { - log.info("Downloader persona doesn't match their destination") - e.close() - return - } - - if (request.have > 0) - eventBus.publish(new SourceDiscoveredEvent(infoHash : request.infoHash, source : request.downloader)) - - Mesh mesh - File file - int pieceSize - if (downloader != null) { - mesh = meshManager.get(infoHash) - file = downloader.incompleteFile - pieceSize = downloader.pieceSizePow2 - } else { - sharedFiles.each { it.getDownloaders().add(request.downloader.getHumanReadableName()) } - SharedFile sharedFile = sharedFiles[0]; - mesh = meshManager.getOrCreate(request.infoHash, sharedFile.NPieces, false) - file = sharedFile.file - pieceSize = sharedFile.pieceSize - } - - if (head) - uploader = new HeadUploader(file, request, e, mesh) - else - uploader = new ContentUploader(file, request, e, mesh, pieceSize) - eventBus.publish(new UploadEvent(uploader : uploader)) - try { - uploader.respond() - if (!head) - eventBus.publish(new SourceVerifiedEvent(infoHash : request.infoHash, source : request.downloader.destination)) - } finally { - eventBus.publish(new UploadFinishedEvent(uploader : uploader)) - } + } finally { + decrementUploads(request.downloader) } } diff --git a/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy b/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy index afcd19b8..36693917 100644 --- a/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy +++ b/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy @@ -621,7 +621,8 @@ class MainFrameModel { wrapper.updateUploader(e.uploader) else { uploads << new UploaderWrapper(uploader: e.uploader) - libraryDirty = true + if (e.first) + libraryDirty = true } updateTablePreservingSelection("uploads-table") }