send X-Have and X-Alts from uploader

This commit is contained in:
Zlatin Balevsky
2019-06-21 13:58:21 +01:00
parent 1b6eda5a40
commit 710f9f52a8
5 changed files with 56 additions and 8 deletions

View File

@@ -217,7 +217,7 @@ public class Core {
eventBus.register(SourceDiscoveredEvent.class, downloadManager)
log.info("initializing upload manager")
UploadManager uploadManager = new UploadManager(eventBus, fileManager)
UploadManager uploadManager = new UploadManager(eventBus, fileManager, meshManager)
log.info("initializing connection establisher")
connectionEstablisher = new ConnectionEstablisher(eventBus, i2pConnector, props, connectionManager, hostCache)

View File

@@ -16,4 +16,13 @@ class Mesh {
this.infoHash = infoHash
this.pieces = pieces
}
Set<Destination> getRandom(int n, Destination exclude) {
List<Destination> tmp = new ArrayList<>(sources)
tmp.remove(exclude)
Collections.shuffle(tmp)
if (tmp.size() < n)
return tmp
tmp[0..n-1]
}
}

View File

@@ -5,18 +5,25 @@ import java.nio.channels.FileChannel
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.StandardOpenOption
import java.util.stream.Collectors
import com.muwire.core.connection.Endpoint
import com.muwire.core.mesh.Mesh
import com.muwire.core.util.DataUtil
import net.i2p.data.Destination
class ContentUploader extends Uploader {
private final File file
private final ContentRequest request
private final Mesh mesh
ContentUploader(File file, ContentRequest request, Endpoint endpoint) {
ContentUploader(File file, ContentRequest request, Endpoint endpoint, Mesh mesh) {
super(endpoint)
this.file = file
this.request = request
this.mesh = mesh
}
@Override
@@ -24,14 +31,18 @@ class ContentUploader extends Uploader {
OutputStream os = endpoint.getOutputStream()
Range range = request.getRange()
if (range.start >= file.length() || range.end >= file.length()) {
os.write("416 Range Not Satisfiable\r\n\r\n".getBytes(StandardCharsets.US_ASCII))
os.write("416 Range Not Satisfiable\r\n".getBytes(StandardCharsets.US_ASCII))
writeMesh()
os.write("\r\n".getBytes(StandardCharsets.US_ASCII))
os.flush()
return
}
os.write("200 OK\r\n".getBytes(StandardCharsets.US_ASCII))
os.write("Content-Range: $range.start-$range.end\r\n\r\n".getBytes(StandardCharsets.US_ASCII))
os.write("Content-Range: $range.start-$range.end\r\n".getBytes(StandardCharsets.US_ASCII))
writeMesh()
os.write("\r\n".getBytes(StandardCharsets.US_ASCII))
FileChannel channel
try {
channel = Files.newByteChannel(file.toPath(), EnumSet.of(StandardOpenOption.READ))
@@ -50,6 +61,15 @@ class ContentUploader extends Uploader {
endpoint.getOutputStream().flush()
}
}
private void writeMesh() {
String xHave = DataUtil.encodeXHave(mesh.pieces.getDownloaded(), mesh.pieces.nPieces)
endpoint.getOutputStream().write("X-Have: $xHave\r\n".getBytes(StandardCharsets.US_ASCII))
Set<Destination> sources = mesh.getRandom(3, endpoint.destination)
String xAlts = sources.stream().map({ it.toBase64() }).collect(Collectors.joining(","))
endpoint.getOutputStream().write("X-Alt: $xAlts\r\n".getBytes(StandardCharsets.US_ASCII))
}
@Override
public String getName() {

View File

@@ -8,6 +8,8 @@ import com.muwire.core.SharedFile
import com.muwire.core.connection.Endpoint
import com.muwire.core.download.SourceDiscoveredEvent
import com.muwire.core.files.FileManager
import com.muwire.core.mesh.Mesh
import com.muwire.core.mesh.MeshManager
import groovy.util.logging.Log
import net.i2p.data.Base64
@@ -16,12 +18,14 @@ import net.i2p.data.Base64
public class UploadManager {
private final EventBus eventBus
private final FileManager fileManager
private final MeshManager meshManager
public UploadManager() {}
public UploadManager(EventBus eventBus, FileManager fileManager) {
public UploadManager(EventBus eventBus, FileManager fileManager, MeshManager meshManager) {
this.eventBus = eventBus
this.fileManager = fileManager
this.meshManager = meshManager
}
public void processGET(Endpoint e) throws IOException {
@@ -72,7 +76,10 @@ public class UploadManager {
if (request.have)
eventBus.publish(new SourceDiscoveredEvent(infoHash : request.infoHash, source : e.destination))
Uploader uploader = new ContentUploader(sharedFiles.iterator().next().file, request, e)
SharedFile file = sharedFiles.iterator().next();
Mesh mesh = meshManager.getOrCreate(request.infoHash, file.NPieces)
Uploader uploader = new ContentUploader(file.file, request, e, mesh)
eventBus.publish(new UploadEvent(uploader : uploader))
try {
uploader.respond()
@@ -162,7 +169,10 @@ public class UploadManager {
if (request.have)
eventBus.publish(new SourceDiscoveredEvent(infoHash : request.infoHash, source : e.destination))
uploader = new ContentUploader(sharedFiles.iterator().next().file, request, e)
SharedFile file = sharedFiles.iterator().next();
Mesh mesh = meshManager.getOrCreate(request.infoHash, file.NPieces)
uploader = new ContentUploader(file.file, request, e, mesh)
eventBus.publish(new UploadEvent(uploader : uploader))
try {
uploader.respond()

View File

@@ -26,6 +26,15 @@ public class SharedFile {
return pieceSize;
}
public int getNPieces() {
long length = file.length();
int rawPieceSize = 0x1 << pieceSize;
int rv = (int) (length / rawPieceSize);
if (length % pieceSize != 0)
rv++;
return rv;
}
@Override
public int hashCode() {
return file.hashCode() ^ infoHash.hashCode();